把文字、代码、图片、音频放进同一个本地索引,用一句自然语言查回来,全程不出网。基于 Google 10 月发布的 EmbeddingGemma 2,从装依赖到出一次可用的检索结果,含六个高频坑的排查办法。
用 EmbeddingGemma 2 搭本地多模态检索
这篇教程解决什么
目标是把你手头的文字、代码、图片、音频(含视频帧)放进同一个本地索引,用一句自然语言查回来,全程不出网、不调云端接口。读完你能得到一条可复现的链路:装依赖 → 按数据形态加载模型 → 分模态建索引 → 跨模态检索。
前提:会用命令行、能装 Python 包。读完能独立完成,不需要机器学习背景。
不覆盖什么,先说清:大规模分布式向量库调优、模型微调、手机端打包发布。这三件各有专门的路数,最后一节「进阶用法」只给方向。
为什么是现在写:2026 年 10 月 6 日,Google 发布了 EmbeddingGemma 2 —— 7.4 亿参数、Apache 2.0 许可证,把文本(含代码)、图片、视频、音频映射进同一个 768 维向量空间。此前做本地检索,文本是一套模型、图片是另一套,两套向量放不进同一个空间;现在一个模型搞定,这是链路变简单的直接原因。发布动态见站内快讯:EmbeddingGemma 2 发布。
开始前的准备
按官方开发者指南,装依赖一条命令:
pip install -U "sentence-transformers[image,audio,video]" transformers
前置条件逐条列:
- Python 环境。建议用虚拟环境(venv 或 conda 均可),别装进系统 Python——后面还会装 torch 这类大依赖,出问题好回滚。
- 磁盘空间。权重与依赖合计按 GB 级准备,机械硬盘会明显拖慢首次下载。
- 内存。全模态配置比纯文本档高,官方博客给的端侧参考是量化后纯文本约 191MB 活跃内存、全模态约 567MB(Pixel 11 Pro 实测口径,桌面设备余量更大,以官方说明为准)。普通办公本够用。
- 网络。权重从 Hugging Face 下载(模型页见官方链接),境内网络可能需要镜像或加速手段;下载失败是最常见的启动卡点,见「常见坑与排错」第 1 条。
- 精度。运行精度按官方模型卡的建议选(bfloat16 或 float32 一类,以模型卡当前版本为准),不要自作主张换成更省内存的精度——这类错不报异常,只悄悄拉低检索质量,最难排查。
不需要装向量数据库:本篇第 7 步用 NumPy 直接算相似度,索引量在几万条以内完全够;上规模再说。
步骤详解
第 1 步:安装依赖并确认版本
装完第一步就做一次可复现的验证,避免版本漂移:
import sentence_transformers, transformers
print(sentence_transformers.__version__, transformers.__version__)
看到什么算成功:两条版本号正常打印,且 sentence-transformers 满足官方指南当前要求的版本(以指南标注为准)。版本不满足时,多模态加载参数可能直接不识别,这是后面报错的常见根源。
第 2 步:按数据形态加载模型
四种加载配置出自同一个检查点,编码器可以按需关掉,不用的编码器不进内存:
from sentence_transformers import SentenceTransformer
MODEL_ID = "google/embeddinggemma-2"
全模态:文本 + 代码 + 图片 + 视频 + 音频(740M 参数)
model = SentenceTransformer(MODEL_ID)
只要文本与代码:关掉视觉与音频编码器(270M 档)
text_only = SentenceTransformer(
MODEL_ID,
config_kwargs={"vision_config": None, "audio_config": None},
)
文本 + 图片 + 视频:关掉音频编码器(440M 档)
text_image = SentenceTransformer(MODEL_ID, config_kwargs={"audio_config": None})
文本 + 音频:关掉视觉编码器(570M 档)
text_audio = SentenceTransformer(MODEL_ID, config_kwargs={"vision_config": None})
官方指南明确说明:四种配置共享同一个向量空间,先用文本档建的索引,之后想加图片或音频,重新加载带编码器的模型继续算就行,已算好的向量不用重算。这条是整篇教程最省事的一条性质,规划存储时可以直接依赖它。
看到什么算成功:模型加载完成且无权重缺失警告。首次运行会先下载权重,网络慢时这一步以分钟计,属正常。
第 3 步:给文本与代码建索引
模型训练时带了任务前缀,检索任务要给查询与文档用不同的前缀,这是官方强调的质量关键项:
query = "合同里关于验收标准的条款"
doc = "title: 采购合同 | text: 乙方交付后,甲方应在十个工作日内完成验收……"
query_emb = model.encode(query, prompt_name="SearchQuery")
doc_emb = model.encode(doc, prompt_name="Document")
两个细节照做:带真实标题的文档要手工拼成 title: xxx | text: xxx 的格式,prompt_name="Document" 只会套 title: none;代码检索用 prompt_name="CodeRetrieval"。前缀只作用于文本输入,媒体输入不带前缀。
看到什么算成功:两条向量能算出相似度,语义相关的句子对分数明显高于无关句对。注意官方文档提醒过:余弦相似度的绝对值普遍偏高,无关句子也可能在 0.6 以上,看相对排序,不要看绝对值。
第 4 步:给图片、音频、视频建索引
媒体用字典形式按模态传入:
img_emb = model.encode({"image": "photos/desk.jpg"})
aud_emb = model.encode({"audio": "memos/note.wav"})
vid_emb = model.encode({"video": "clips/demo.mp4"})
上下文预算是全模态共享的。按官方模型卡的口径:一张图约 280 token、一帧视频约 140 token、音频每秒约 25 token,总窗口 8192 token——单次输入大约装得下 29 张图、58 帧视频或五分半钟音频(以模型卡为准)。所以音频别整条塞,先按你的场景切片;视频同理,按帧采样。
看到什么算成功:三种向量维度与文本向量一致(都是 768 维),说明真的进了同一个空间。
第 5 步:把文字和媒体放进同一条输入
商品页、报告这类「文字配图配视频」的资料,可以合成一条向量而不是各算各的。官方文档用一组占位符在文本里标记媒体位置(形如 <image>、<video>,具体写法以官方指南为准):
listing = model.encode({
"text": "防水越野鞋,附抓地力测试视频:",
"image": "front.jpg",
"video": "grip_test.mp4",
})
看到什么算成功:返回的是一条向量而不是三条。什么时候该用这招、什么时候不该,判断标准很直接:资料本身是一个整体(一份带图的说明书)就合;资料是独立的条目(图库里的散图)就分开,分开才好单独管理。
第 6 步:用 Matryoshka 截断维度
官方训练支持把 768 维输出截到 512 / 256 / 128 维,向量库存储随之缩减,最高到六倍:
q = model.encode(query, prompt_name="SearchQuery",
truncate_dim=256, normalize_embeddings=True)
三条纪律:查询与文档必须用同一个维度,一边 768 一边 256 算出来的相似度没有意义;截断要配 normalize_embeddings=True,保证向量是单位长度;维度怎么选按官方指南的说法取舍——256 档在多模态检索上保留的质量较高,128 档更适合纯文本与代码场景。不确定就从 256 开始。
看到什么算成功:换维度后抽样复核,排序与全维度基本一致。出现明显错位就退回高维度,别硬扛。
第 7 步:建本地索引并做一次跨模态检索
不用向量数据库,NumPy 就够:
import numpy as np
docs = ["第一批资料的标题 | 正文……", "第二批资料的标题 | 正文……"]
doc_vecs = model.encode(docs, prompt_name="Document", normalize_embeddings=True)
np.save("index.npy", doc_vecs) # 持久化,重启进程不用重算
一句自然语言查图片(跨模态:查询是文本,索引里有图像向量)
q_vec = model.encode("一张办公桌的照片", prompt_name="SearchQuery",
normalize_embeddings=True)
scores = doc_vecs @ q_vec
print(int(np.argmax(scores))) # 命中的条目下标
看到什么算成功:一句文字查询命中了正确的媒体条目,换两三个不同说法命中率稳定。到这里链路就通了:之后只做两件事——往索引里加新条目、把命中结果接到你的应用里。
常见坑与排错
按出现频率排:
- 权重下载失败或极慢。境内网络访问 Hugging Face 的常见卡点,先解决下载通道(镜像或加速),再排查代码。判别办法:报错发生在模型加载这一步、且报的是连接类错误,就是它。
- 精度用错,质量悄悄下降。运行精度按官方模型卡的建议来(以当前版本说明为准),不要为省内存自选低精度。这类问题无异常报错,症状是检索排序莫名变差,回滚精度设置立刻恢复就能确认。
- 查询与文档用了不同的任务前缀或不同维度。症状同样是「排序不对劲」但偶尔又对。统一成第 3 步的写法(查询用 SearchQuery、文档用 Document、维度一致),问题即消。
- 把音频或长视频整条塞进去。8192 token 的窗口是共享的,按第 4 步的消耗速度很快爆掉。先切片再入库,切片粒度宁小勿大——检索命中的是切片,回放时再合并相邻切片。
- 拿跨模态相似度的绝对值当阈值用。官方文档没有给跨模态与同模态分数的统一校准口径,两类分布不一定可比。稳妥做法:分模态各取候选再合并排序,阈值按你自己数据里的实测分布定,不要抄通用数值。
- 只跑基准不跑自己的数据。官方公布的基准成绩是它的口径,站内不核不转述。决策依据应该是第 7 步在你自己的资料上跑出来的命中率,半小时就能测完。
进阶用法
三个方向,各给一句判断标准:
- 配 Gemma 4 做本地 RAG:检索命中后把原文喂给本地生成模型作答,整条链路不出网。适合材料敏感、或调用云端按量计费不划算的场景;代价是本地生成模型那部分要另配资源。
- 端侧部署:官方生态里有 MediaPipe Tasks 与 LiteRT 一侧的集成路线,主打手机与嵌入式设备。适合产品要离线运行的场景;本篇的 Python 链路是开发期验证用的,上线前按端侧文档重走一遍。
- 接入现成工作流平台:不想写代码,可以把「批量算向量」封成一个脚本步骤,接到 Dify 或 n8n 这类平台里当自定义节点,检索部分用本地 HTTP 服务包一层。适合团队里有人负责流程、有人负责脚本这种分工。
常见问题
这个模型可以商用吗?
许可证是 Apache 2.0,属商用友好的开源协议,具体权利义务以许可证原文与官方发布页为准。商用前值得做的一件事:用你自己的真实数据(中文材料、行业图片、真实录音)跑一轮命中率,再决定要不要进生产——公开基准替代不了这一步。
我的电脑跑得动吗?
大概率可以。官方端侧参考是量化后纯文本约 191MB 活跃内存、全模态约 567MB(手机实测口径,以官方说明为准),普通办公本的内存远大于此,主要瓶颈是首次下载权重时的磁盘与网络。拿不准就先用 270M 的纯文本档跑通全流程,再换全模态档,两种档位共享向量空间,切换成本几乎为零。
和云端 embedding 接口比,什么时候该用本地的?
三条边界:材料敏感、不能出网,用本地;调用量大且稳定、按量计费累积明显,用本地划算;需要离线运行(边缘设备、内网隔离环境),只有本地可行。反过来,数据本就不敏感、调用量零散、或需要与云端其他能力直接组合时,云端接口省事。两者也可以分层:常用资料本地索引,长尾查询走云端,代价是维护两套。
中文效果怎么样?
官方称本代的多语言文本能力与上一代持平、代码检索指标有明显提升(具体数字与语言清单以官方模型卡为准)。中文材料的实际表现以你自己的数据为准:拿五十条真实中文文档跑第 7 步的检索,人工看前十命中,半小时能得出结论。多语言场景同理,别用英文语料的印象代替实测。
跨模态检索结果不准,先查什么?
按顺序查三件事:查询与文档的前缀、维度、精度设置是否一致(第 3、6 步与排错清单);媒体是否按模态分开建索引、而不是和文本混在同一条里(混入是常见错误源);最后才是模型能力本身——把同一查询换成同模态的查询(用文字查文字、用图查图)验证,若同模态正常而跨模态差,按排错清单里的办法分模态检索再合并,而不是硬调阈值。
相关工具与内容
- 站内工具:NotebookLM(云端的多文档问答与资料整理,与本地检索形成「云、本地」两条路线)、腾讯云文字识别(入库前把扫描件转成文本的前置环节)、ComfyUI(图片生成侧的工作流编排,可与本地检索组合成素材库)
- 分类入口:AI 编程 · AI 搜索 · AI 视频
- 相关深度与快讯:EmbeddingGemma 2 发布、Cohere Embed 5 发布(云端 embedding 侧的对照)、Ollama 决策模型更新(本地跑小模型的另一条路)、NVIDIA DGX Spark(把本地链路搬到专用硬件的选项)、给智能体接实时联网搜索
相关内容
Cloudflare 推出 Clef-omni:决策模型开始直接吃音频、视频与图片
Cloudflare 于 2026 年 10 月 9 日在官方博客发布 Clef-omni,把决策模型的输入从文本与图像扩展到音频与视频,一次调用即可跨模态打分;同时宣布 Clef 本体提速、Clef-flash 降价。官方称权重以开放权重形式发布在 Hugging Face,并与 Jev API 兼容。
EmbeddingGemma 2 发布:7.4 亿参数的端侧多模态嵌入模型,文本、图像、音频、视频共用一个向量空间
Google DeepMind 于 2026 年 10 月 6 日在官方博客发布 EmbeddingGemma 2,把上一代的纯文本嵌入扩展到代码、图像、视频与音频,统一映射到同一个嵌入空间。模型基于 Gemma 4 架构、7.4 亿参数、Apache 2.0 许可,面向手机与浏览器等端侧场景,官方称其支持可裁剪的模块化编码器与 Matryoshka 向量降维。
ComfyUI v0.39.0 发布:新增离线与关闭合作节点开关,一批第三方模型节点同步上线
节点式图像与视频生成工具 ComfyUI 于 2026 年 10 月 5 日发布 v0.39.0。官方 changelog 显示,这一版新增了「--offline」与「--disable-partner-nodes」两个启动开关、为多个第三方模型补上节点、并把素材扫描与视频导出的默认行为调整为更稳更省的一档。
继续阅读:职徒简历 4.2 分:同一份简历,怎么变成中英两版和四种格式 · 微软发布 Microsoft-Decision-1:专做决策打分的模型,已上 Foundry 与 OpenRouter