AIREITER

EmbeddingGemma 2 本地部署:迁移风险指南

最后更新: 2026-10-07 00:41:17

把 EmbeddingGemma 2 部署到本地,并不等于可以直接替换现有的 embedding 服务。运行时通常只需少量应用层改动,但一旦表示契约发生变化,往往就必须重建向量。最稳妥的做法,是把三个问题拆开处理:模型如何运行、现有向量是否仍然兼容,以及混合模态检索是否足以覆盖你的数据集。

迁移决策,一页看懂

如果你希望在同一模型家族中处理本地文本、代码、图像、视频或音频 embedding,并且能够接受受控的向量回填,那么可以考虑 EmbeddingGemma 2。不要先切换生产环境的查询编码器,再慢慢补齐文档向量:embedding 模型本质上属于索引 schema 的一部分,即使向量维度看起来相同也一样。

决策项实际建议
本地部署起点使用官方 checkpoint 配合 Sentence Transformers
纯文本配置规模关闭视觉和音频后为 270M 参数
完整多模态配置规模740M 参数
原生输出768 维
存储折中方案优先测试 256d;对于多模态数据,128d 需要更严格的验证
现有向量只有在完整表示契约未变且已验证兼容时才能复用
生产切换构建第二个索引,或使用带版本的 named vectors,然后同时切换模型和索引

Google 模型卡给出的参考成绩包括:MTEB multilingual v2 得分 61.36,MTEB code v1 得分 78.68,视觉文档检索 NDCG@5 为 67.84,视频检索 Hit@1 为 50.67,音频检索 MRR@10 为 69.54,以上均基于 768 维输出。这些数字适合作为参考基线,但不能替代针对自身查询集的测试。

迁移到 EmbeddingGemma 2 后,哪些会变,哪些不会

EmbeddingGemma 2 会把文本、代码、图像、视频和音频映射到同一个 768 维空间。这个 checkpoint 采用模块化设计:官方开发者指南介绍了 270M 的纯文本配置、440M 的文本加视觉配置、570M 的文本加音频配置,以及 740M 的完整配置。关闭某个 encoder 会减少加载的权重和峰值内存,但并不会因此自动产生一个新的语义空间。

这一区别对迁移很关键。使用 270M 配置生成的文本查询,可以与使用完整配置生成的 EmbeddingGemma 2 文档向量进行比较,因为 Google 明确说明这些配置共享兼容的向量空间。但这不意味着旧的 EmbeddingGemma 1、Qwen、Nomic 或 API 服务商向量,只要同样拥有 768 个坐标,就能直接拿来配合 EmbeddingGemma 2 查询。

任务格式同样属于契约的一部分。对于非对称检索,EmbeddingGemma 2 需要类似 task: search result | query: ... 的搜索查询指令,以及类似 title: ... | text: ... 的文档格式。代码检索也有专用的任务指令。如果旧流水线使用了不同的前缀、切分方式、归一化策略或输入字段,就应该把这些变化记录为新的表示版本,并按照一次正式迁移来验证。

运行时支持:优先选择最小、最稳妥的本地路径

先用 Sentence Transformers,确保结果正确

官方模型卡提供了通过 Sentence Transformers 和 Transformers 使用 google/embeddinggemma-2 的说明。如果需要处理媒体输入,请安装多模态扩展:

pip install -U "sentence-transformers[image,audio,video]" transformers

对于迁移来说,这是最适合作为基准的路径,因为 prompt 名称、截断、归一化以及多模态输入行为都遵循官方示例。它未必是延迟最低的服务方案,但在开始优化之前,可以先建立一个可信的基准。

最小化的纯文本冒烟测试如下:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer(
    "google/embeddinggemma-2",
    config_kwargs={"vision_config": None, "audio_config": None},
)
query = model.encode(
    "embedding model migration",
    prompt_name="SearchQuery",
    truncate_dim=256,
    normalize_embeddings=True,
)
document = model.encode(
    "Rebuild vectors when the embedding representation changes.",
    prompt_name="Document",
    truncate_dim=256,
    normalize_embeddings=True,
)
print(model.similarity(query, document).item())

在引入服务端、量化方案或向量数据库之前,先运行这段测试。它可以确认 checkpoint、任务 prompt、输出维度和归一化流程是否能够正确配合。

确认功能对齐后,再考虑生态运行时

Google 的开发者指南将 vLLM、Hugging Face Transformers、Sentence Transformers、SGLang、MLX、Ollama、LM Studio 和 LiteRT 列为支持的开发或部署工具。应把这份列表理解为“可以使用”的信号,而不是每个运行时都完整支持文本、图像、视频、音频、交错输入、任务前缀、截断和批处理。

对于每个候选运行时,都要用真实请求核对五件事:确切的 checkpoint revision、你实际使用的模态输入、输出维度、截断后的归一化,以及查询和文档前缀的处理方式。一个只能高效处理文本、却忽略视觉文档路径的运行时,并不能等价替代完整模型。

轻量原生服务端是优化项,不是迁移方案

公开的 embeddinggemma.c repository 为 EmbeddingGemma 300M 提供了专用的 C11/Metal 风格服务端,并支持 CPU、Metal、CUDA、ROCm 和 Intel XPU 版本。其 README 记录了兼容 OpenAI 的 /v1/embeddings 接口、768/512/256/128 维输出,以及 278 MB 的 Q4_0 模型下载。该项目还公布了在 Apple M5 Max 上、针对 llama.cpp build b8981 的受控对比结果:覆盖 54 个测试单元,几何平均优势为 1.25×。这些是项目自身的吞吐测试结果,既不是质量对比,也不能证明它与 740M checkpoint 在多模态能力上完全一致。

它对迁移最有价值的地方,在于接口形态。如果你的应用已经使用 OpenAI 风格的 embedding 接口,那么兼容该接口的本地服务端可以减少适配工作。不过,在服务端的模态支持和前缀行为与生产流水线对齐之前,仍应保留 Sentence Transformers 的结果作为正确性基准。

索引重建风险:维度只是迁移维度之一

只要源数据到向量的映射变了,就应重新 embedding

只要发生以下任一变化,就应按完整重建来规划:模型家族、模型版本、任务前缀、归一化方式、切分策略、截断策略、输入字段或相似度语义。Qdrant 的迁移指南以及 Nalar 的模型迁移分析都强调了同一个运维原则:文档向量和查询向量必须属于同一个表示版本。维度相同,并不能证明语义兼容。

不要直接截取一个旧的 768 维向量,然后把它当成 256 维 EmbeddingGemma 2 向量。EmbeddingGemma 2 的 Matryoshka 输出是针对受支持的截断尺寸训练的,并且截断后必须重新归一化。模型卡给出了以下官方参考成绩:

维度存储缩减MTEB multilingual v2Code v1MIEB LiteMMEB v2 overall
7681×61.3678.6864.6459.01
5121.5×61.1777.2464.3258.38
2563×60.4176.1863.1356.24
1286×57.8971.4159.0645.65

官方模型卡还报告了 768 维下视觉文档检索 NDCG@5 为 67.84、视频检索 Hit@1 为 50.67。应把它们作为完整维度的基线,而不是自行推算低维成绩。可靠的结论是:256d 的质量明显更接近完整输出,而 128d 下的多模态得分下降更明显。应使用官方 checkpoint,在选定维度下重新生成所有向量,而不是截取其他模型的向量。

共享的 EmbeddingGemma 2 空间,可以避免不必要的重建

这里有一个重要例外。如果现有语料本来就使用 EmbeddingGemma 2 生成向量,而你只是改为加载其中一部分 encoder,那么 Google 的开发者指南表示,这些配置共享同一个向量空间。纯文本查询可以匹配完整模型生成的文档向量。在这种情况下,不需要仅仅因为当前服务进程开始支持视觉或音频,就重新生成已有的文本向量。

但对于新增加的媒体记录,仍然需要生成新的向量。一个只有文本向量的索引,无法检索从未被 embedding 的图像、视频或音频内容。因此,即使 checkpoint 没有变化,增加多模态检索仍然意味着一次增量式的语料迁移。

采用蓝绿切换或 named-vector 方案

对于在线系统,Qdrant 的迁移模式提供了一个清晰模板:创建新 collection,持续双写新记录,从权威源数据回填,对比 Recall@10/MRR/nDCG@10,切换 alias,并保留旧 collection 以便回滚。Qdrant 指南使用了 1.19.0、512 维示例和每批 100 个 point;这些只是示例,并不是 EmbeddingGemma 2 的强制要求。

如果向量数据库支持,并且更新流程能够始终同时写入两种表示,那么 named-vector 设计可以把新旧表示放在同一个 collection 中。Weaviate 的 vectorizer 迁移指南建议生产环境使用 collection alias,因为这样可以保留旧 collection,完成验证后立即回滚,并在确认无误后再删除。另一种做法是在现有 collection 中新增一个向量,但这可能永久增加存储开销,更适合做对比,不适合作为最终的整洁状态。

混合模态质量:重点验证模型真正改变的部分

EmbeddingGemma 2 的共享空间只有在检索行为符合你的数据特征时才有价值。纯文本基准可以证明迁移没有破坏文本搜索,却可能掩盖 PDF 页面、图表、图像字幕、视频帧、音频片段或交错记录中的问题。

先建立相互独立、带标签的测试切片:

  1. 文本查询 → 文本片段。
  2. 代码查询 → 代码片段。
  3. 文本查询 → 图像或视觉文档。
  4. 文本查询 → 视频帧或音频片段。
  5. 文本加媒体查询 → 混合文档。
  6. 跨语言查询 → 你实际提供服务的语言对应文档。

多模态基线建议先从 768d 或 512d 开始。官方模型卡规定:每张图像占用 280 个 token,每个视频帧占用 140 个 token,每秒音频占用 25 个 token,共享上下文上限为 8,192 个 token。混合输入会共同消耗这部分预算,因此同时包含文本、图像和视频的记录,分配给每个组件的空间会少于单一模态输入。

模型卡还指出,与纯文本任务相比,128d 对多模态任务造成的质量下降更明显。因此,128d 可以作为大型文本索引的第一阶段候选方案,但不应默认用于混合媒体档案。在接受它带来的存储节省之前,先用真实的视觉文档和跨模态查询测试 256d。

应使用完全相同的查询,对统一的 EmbeddingGemma 2 流水线和当前的独立文本/图像流水线进行对比;不要仅凭模型采用共享空间这一架构事实,就推断混合模态质量。

面向现有 RAG 系统的分阶段部署方案

  1. 盘点当前契约。记录模型 ID、checkpoint revision、前缀、切分策略、维度、距离度量、归一化方式、源字段,以及当前已建立索引的所有模态。
  2. 建立有代表性的评测集。设置 Recall@k、MRR 或 nDCG 目标,并分别覆盖文本、代码、视觉文档、音频、视频、语言和长查询切片。
  3. 建立本地基线。先使用 Sentence Transformers 对同一语料运行测试,记录 embedding 延迟、搜索延迟、内存、索引大小、失败情况和得分分布。
  4. 构建带版本的候选索引。保持稳定的文档 ID,并将权威源文本/媒体保存在向量存储之外,确保回填过程可重复。
  5. 在回填期间协调写入。使用源数据快照加变更重放,或者将新记录和更新记录同时写入两个表示版本。
  6. 对生产查询做影子测试。在不改变用户可见答案的情况下,对比排序结果、空结果率、延迟和带标签的相关性。
  7. 原子切换。将 EmbeddingGemma 2 查询编码器与匹配的索引绑定到同一个版本或 alias 下。绝不要让新的查询编码器在中间状态下直接访问旧索引。
  8. 保留回滚能力。在代表性流量达到验收阈值之前,保留旧索引和旧查询路径;确认无误后,再停止双写并回收存储。

常见问题

EmbeddingGemma 2 可以只用 CPU 运行吗?

可以,只要使用支持 CPU 的运行时。模型卡建议在无法使用 bfloat16 时采用 float32,纯文本配置规模为 270M 参数。CPU 吞吐量取决于运行时、精度、批处理方式和硬件,因此应在自己的语料上实测,不要直接套用 GPU 数字。

运行时的选择,本质上是在参考实现的正确性、功能对齐程度、服务效率,以及验证一个新检索版本所需的成本之间做权衡。