EmbeddingGemma 2 上手指南:740M 参数把文字、图片、音频压进同一个向量空间,M4 本机实测

Google DeepMind 在 10 月 6 日把 EmbeddingGemma 2 放了出来。它不是聊天模型,而是一个嵌入模型——输入一段文字、一张图、一段音频或几帧视频,输出一个 768 维的向量。这些向量生活在同一个空间里,所以你可以用文字搜图片、用图片搜视频、用代码描述搜代码片段,全程离线、不需要 API Key。

这篇我把权重从 Hugging Face 拉到 M4 Mac 上跑了一遍,覆盖了文本相似度、跨模态图像检索和代码检索。下面的数字都是我这次实际测出来的,不是新闻稿里抄的。


模型基本信息:小、多模态、Apache 2.0

按 官方 model card,EmbeddingGemma 2 总参数量 740M,可以拆成三块加载:

  • 文本/代码编码器:270M
  • 视觉编码器:+170M
  • 音频编码器:+300M

也就是说,如果你只做文本 RAG,只加载 270M 那块就行;需要看图听声再按需加。上下文窗口 8192 token,官方说单次能塞下 5.5 分钟音频、29 张图或 58 帧视频。输出向量固定 768 维,但支持 Matryoshka Representation Learning(MRL),可以截断到 512/256/128 维来省存储。

授权是 Apache 2.0,没有 Gate,CI/CD 可以直接 git clone 或 from_pretrained 拉权重。这一点比 EmbeddingGemma 1 友好很多——后者是 Gemma Terms of Use 且需要手动申请。


本机环境准备

我用的环境:M4 MacBook Pro、16GB 内存、macOS 26.5.2、Python 3.13.12。EmbeddingGemma 2 需要较新的 transformers,因为模型类型 embedding_gemma2 在稳定版里还识别不了。我实测必须装 transformers 的 git 主分支才能加载成功。

Bash
# 创建独立环境
python3 -m venv .venv
source .venv/bin/activate

# 必须装 git 版 transformers,稳定版会报 model type 不认识
pip install -U git+https://github.com/huggingface/transformers.git
pip install -U "sentence-transformers[image,audio,video]"

如果你只做文本,可以只装 sentence-transformers;想跑图片/音频再带 [image,audio,video]。第一次下载权重需要 Hugging Face 缓存,大小约 1.5GB。


实测一:文本相似度与检索

最小可运行示例如下。注意 EmbeddingGemma 2 对「任务前缀」比较敏感,做检索时要给 query 和 document 分别加前缀:

Python
from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim

model_id = "google/embeddinggemma-2"
model = SentenceTransformer(model_id, trust_remote_code=True)

# 对称任务:句子相似度
sentences = [
    "如何用 Python 给本地相册做语义搜索?",
    "本地图像检索可以用嵌入模型把图片转成向量。",
    "Redis 是一款流行的键值存储数据库。",
]
emb = model.encode(sentences, convert_to_tensor=True)
print(cos_sim(emb, emb))

我的输出:

Plaintext
[[1.0000, 0.7870, 0.6931],
 [0.7870, 1.0000, 0.6991],
 [0.6931, 0.6991, 1.0000]]

前两句都在讲「本地语义搜索」,相似度 0.7870;第三句是 Redis 介绍,和前两句都在 0.69 左右。这个基线比我想象中高——说明完全无关的句子也能拿到 0.69,做阈值判断时不能按 GPT 类模型的「0.5 以下才算无关」来套。

不对称检索要加前缀。我测了一个 query 对三个文档:

Python
query = "task: search result | query: 本地相册 语义搜索"
docs = [
    "task: search result | text: 用 EmbeddingGemma 2 把照片转成向量后存入向量数据库,再用文字搜索相关图片。",
    "task: search result | text: Claude Haiku 5.5 是 Anthropic 发布的小模型,适合高吞吐任务。",
    "task: search result | text: Redis 支持向量索引插件 RedisVL,可用来存储 embedding。",
]
q_emb = model.encode([query], convert_to_tensor=True)
d_embs = model.encode(docs, convert_to_tensor=True)
print(cos_sim(q_emb, d_embs))

结果:相关文档 0.7452,无关的 Claude 文档 0.6020,Redis 文档 0.6561。排序是对的,但分数都不低——用 EmbeddingGemma 2 做检索时,建议按相对排序取 top-k,而不是设一个绝对阈值。

模型首次加载我用了 20.5 秒(MPS + bfloat16),后续缓存后降到 8-9 秒;强制 CPU 加载是 9.2 秒,编码两条句子 0.12 秒。744.4M 参数全部进内存,显存/内存占用在 M4 上没压力。


实测二:文字搜图片

多模态检索是 EmbeddingGemma 2 最大的卖点。我用 PIL 临时画了三张图:蓝色背景的 CAT、绿色背景的 DOG、红色背景的 CAR,然后用英文 query 去搜。

Python
from PIL import Image, ImageDraw, ImageFont

img1 = Image.new("RGB", (224, 224), "blue")
# ... 画上 CAT / DOG / CAR 文字

queries = ["a photo of a cat", "a photo of a dog", "a red vehicle"]
q_emb = model.encode(queries, convert_to_tensor=True)
i_emb = model.encode([img1, img2, img3], convert_to_tensor=True)
print(cos_sim(q_emb, i_emb))

结果矩阵:

Plaintext
[[0.6553, 0.6137, 0.6072],
 [0.5845, 0.6523, 0.5844],
 [0.5539, 0.5555, 0.6818]]

对角线最高:cat→cat 0.6553,dog→dog 0.6523,red vehicle→car 0.6818。跨模态能 work,但分数绝对值比纯文本低,top-k 检索更稳。另外我这是合成图,真实照片的表现需要更多样本验证。

文字搜图片这个能力,和之前写过的 Qwen-Image-2.1 图像生成 形成互补:一个负责「生成」,一个负责「检索」。


实测三:代码片段检索

官方把代码任务当作重点,MTEB Code v1 从 EmbeddingGemma 1 的 68.76 涨到 78.68。我用三小段 Python 测了一下:

Python
query = "task: code retrieval | query: 用 Python 读取 JSON 文件"
snippets = [
    "task: code retrieval | text: import json\nwith open('data.json', 'r', encoding='utf-8') as f:\n    data = json.load(f)",
    "task: code retrieval | text: import requests\nresp = requests.get('https://api.example.com')\nprint(resp.json())",
    "task: code retrieval | text: import csv\nwith open('data.csv', newline='') as f:\n    reader = csv.reader(f)",
]
scores = cos_sim(model.encode([query]), model.encode(snippets))[0]

结果:json 片段 0.8000,requests 片段 0.7486,csv 片段 0.7217。排序正确,且分数区分度比文本检索更明显。拿它给本地代码库建索引、配合 Codex Harness 或 Cursor 做 Agentic 代码搜索,是个合理的落地路径。


踩坑提醒:MRL 降维别只看相似度

MRL 允许把 768 维截断到 256 或 128 维,官方宣传「最多省 6 倍存储」。我在同一对句子上测了三个维度:

Plaintext
768d 相似度: 0.7871
256d 相似度: 0.8082
128d 相似度: 0.8656

维度越低,相似度反而越高。这不是说 128 维更好,而是截断会改变向量空间的尺度。如果你混用 768d 和 128d 的向量去搜同一个库,结果会乱套。生产环境里必须全库统一维度,且 128 维官方建议只用于纯文本任务,多模态任务会明显掉质量。


什么时候用,什么时候不建议用

适合的场景:

  1. 端侧 RAG:配合 本地 Agent 方案,把个人文档、笔记、截图都向量化,查询不上云。
  2. 相册/视频语义搜索:文字描述搜照片,或者截图搜视频关键帧。
  3. 代码库检索:对函数、模块、报错信息做语义索引,比纯关键词匹配更鲁棒。

不建议的场景:

  1. 需要强多语言对齐的跨语言检索。MTEB multilingual v2 得分 61.36,只比上一代涨 0.21,中文查询搜英文文档的效果建议自己测过再上线。
  2. 对延迟极度敏感的在线服务。M4 上单条句子几十到几百毫秒,批量推理能摊薄,但高 QPS 场景建议用 vLLM / SGLang 服务化或上 GPU。
  3. 需要精确关键词匹配的任务。Embedding 模型会丢拼写、ID、版本号这类字面信息,必须搭配 BM25/关键词召回做混合搜索。

小结

EmbeddingGemma 2 最吸引我的不是参数大小,而是「一个模型、按需加载、离线可用」的工程形态。文本 RAG 只要 270M;想看图再加 170M;想听声再加 300M。全部 Apache 2.0,CI 可以直接拉权重,不需要写邮件申请。

我这次实测验证了:

  • sentence-transformers + git 版 transformers 可以加载;
  • 文本检索、跨模态图文检索、代码检索的排序都正确;
  • MRL 截断会改变相似度尺度,必须统一维度使用。

没实测的部分我会直接标出来:音频/视频嵌入我没跑(需要准备合适的音视频样本),不同量化精度对精度的影响也没系统测,长文档切分策略留到后续补充。

如果你手里有一台带 M 系列芯片的 Mac,或者一张 8GB 显存的卡,半小时就能把它接到自己的笔记、相册或代码库里。


没实测的部分我会直接标出来:音频/视频嵌入我没跑(需要准备合适的音视频样本),不同量化精度对精度的影响也没系统测,长文档切分策略留到后续补充。

推荐阅读

  • REA 冲上 Trending 第一当天实测:给 AI 编程工具装上逆向工程之手,Mac 上的 4 个坑我先踩了

    REA 是发布首日就冲上 GitHub Trending 榜首的开源项目:用 MCP 把 Ghidra、Hopper 等逆向工具接给 Claude Code、Cursor 这类编程 Agent,让 A…

  • Agent Reach 实测:一条命令给 AI Agent 装上联网能力,B站搜索免 Key 跑通

    AI Agent 写代码很利索,联网取资料就抓瞎:Twitter API 收费、Reddit 403、B站风控、小红书登录墙。GitHub 9.2 万星的 Agent Reach 把十几个平台的接入选…

  • llama.cpp 决策模型实测:/v1/systemone 一次前向出概率,M4 跑通 Kev-4B,中文比英文省 28% token

    llama.cpp 10 月 2 日合入 /v1/systemone 端点,决策模型从此能跑在自己机器上,不用再绑任何厂商 API。我在 M4 Mac 上实测 Kev-4B 与 Julia-1 两个官…

  • OpenAI Dots 开源平替实测:Mac 自托管 Open Dots,30 行代码吃上本地模型

    OpenAI Dots 限 Pro 订阅还缺席多数地区,开源平替两天涨了四百星。我在 M4 Mac 上实测自托管全流程:五分钟起服务,发现它不兼容 Chat Completions 协议,Ollama…