1. 为什么多模态 Embedding 是检索系统的分水岭
多模态 Embedding 这个词,这两年已经被提到很多,但真正在业务里跑过的人应该都有同感:跨模态检索从“能跑通”到“能扛业务”,中间隔了很长一段路。我自己是从单模态搜索转到多模态检索的,最早接触 CLIP 一系模型时,确实被“一句话搜图”的能力震撼过,但也真被它的工程短板坑过不少次。这篇内容就从工程视角,聊聊以 jina-clip-v2 为代表的 CLIP 路线迭代,以及它和现在很火的 MLLM(多模态大语言模型)范式到底有什么不同、实际项目里该怎么选。
先说为什么我把多模态 Embedding 看作检索系统的分水岭。过去很多系统的做法,是把文本和图像分开处理:文本走全文检索,图片走标签或者 OCR 结果。这种结构在内容量小的时候没问题,可一旦数据规模上来,问题立刻暴露。标签是人工标的,永远标不全;OCR 只能识别图中文字,识别不出画面内容;而用户真正想问的往往长这样——“找一张春季新款、浅色系、适合通勤的背包图”。这种自然语言 query,单靠标签和 OCR 都无解,必须依靠模型把画面和文字放进同一个语义空间去比对。
1.1 跨模态检索为什么不是两个单模态系统的拼接
真正把多模态检索做好的方式,是让文本和图像落在同一个向量空间里。Embedding 模型在这里扮演的是“坐标转换器”的角色:无论输入是一段文字、一张商品图、一个视频帧还是一段语音,最终都被映射成一组固定维度的向量。检索系统不再关心你输入的是文本还是图片,它只做一件事:算向量之间的距离,距离近的就是相关内容。
这套设计解决的不只是“文本搜图”,还能做图像搜图、图像搜文本、多模态相似推荐。我后来发现自己遇到的大多数检索场景,本质上都可以概括成“给定一个模态,找相关的另一个模态”。比如用户上传一张产品外包装图,想找到对应的商品详情页;再比如运营人员拿一张活动海报,想找出素材库里所有风格相似的海报。这些需求天然依赖多模态 Embedding,传统分开索引的做法完全没有办法支撑。
1.2 对比学习:CLIP 式模型的核心机制
CLIP 这类模型的基础是双塔结构:一个文本编码器、一个图像编码器。训练时,把配对的文本和图像当作正样本,把同一个 batch 里其他样本当作负样本,用对比损失拉近正样本对的向量距离、推远负样本对的向量距离。训练结束后,文本和图像都被压缩成同一维度的向量,比如 768 维或者更高。
如果只用机器学习的术语解释对比学习,可能不太好懂。我习惯用一个类比:两个编码器就像两个翻译官,一个负责翻译文字,一个负责翻译画面,训练目标是把每种内容都翻译成同一门“语义外语”。起初两个翻译官各说各话,对比损失就是反复纠正他们翻译姿势的教练:同样的意思,必须落到词典里相近的位置,否则就扣分。
这里的关键不是向量维度,而是“对齐”本身。同一条图像向量,和正确文本向量的距离,必须比和错误文本向量的距离更近。这种相对关系稳定了,检索结果才是可靠的。CLIP 式模型刻意训练这种相对关系,所以它天然适合做 Embedding,而不是另一个只会生成描述的模型。
2. CLIP 路线迭代:jina-clip-v2 到底改了什么
CLIP 这个概念虽然很美好,但早期模型拿来落地时,被吐槽最多的就是“道理我都懂,一跑全是问题”。如果只拿它做 Demo 没问题,一旦接进真实系统,各种边界情况能把人折磨疯。所以我觉得,jina-clip-v2 最有价值的不是某一个指标的提升,而是把 CLIP 路线的生产短板一块一块补上了。
2.1 老 CLIP 模型在工程侧的四个短板
第一是文本长度限制。老 CLIP 的文本编码器接受的 token 数很有限,模型卡里写着一个非常保守的上限。实际业务里,用户搜图根本不会只输入一个词,而是输入一大段描述:“灰色羽绒服,立领设计,袖口有松紧收口,适合北方冬天穿”。这种长 query 喂进去,后半段关键信息基本被截断,检索结果自然一塌糊涂。
第二是图像分辨率限制。老 CLIP 一般先把图缩放到一个比较小的固定尺寸再送进模型,这对细节敏感的产品图、截图、文档里的图表都非常不友好。相机照片里的小字、包装上的规格参数、扫描件里歪歪扭扭的批注,缩放之后信息全丢了,模型只能看到一个大致的轮廓。
第三是语言覆盖问题。早期 CLIP 类模型在英文上的表现和对中文的支持程度差距很大,尤其在中文长句上,经常出现语义漂移。同一个 query,换成中文和英文,检索结果的差异可能非常明显,这给国内业务落地带来了不少麻烦。
第四是模型本身的表达能力有限。早期 CLIP 模型的参数量不算大,处理复杂场景时,对“属性组合”的建模能力偏弱。比如“一只站在树枝上的蓝色鹦鹉”和“一只站在桌上的蓝色杯子”,模型可能把蓝色和鸟类搞混,这类细粒度区分能力不足的问题,直接影响了排序质量。
2.2 jina-clip-v2 的变化,处处对着短板打
jina-clip-v2 在我看来的核心变化,是换用了更强调长文本语义对齐的文本编码器,上下文长度从原来几十个 token 直接拉高到数千量级。这对检索是质变:长描述、长问句、整段说明书文本,都可以整段编码,不用再担心截断问题。
图像端也支持接近原图分辨率的输入处理,不再强行压缩成小图。这个改动对包含小字、标注、图表的业务场景非常关键。我做过一个行业图纸检索的项目,图纸上有大量尺寸标注和材质说明,老模型把图缩完后,标注文字变成了一团模糊的噪声;换了 v2 这类支持高分辨率输入的模型后,图纸上的关键标注能参与语义匹配,检索精度提升非常明显。
多语言覆盖也是 v2 的一个重点。它在中文场景下的跨模态检索效果,比我预期中要好。过去我处理中文搜索,经常要先做分词、同义词扩展,现在模型本身对中文语义的对齐能力强了不少,很多预处理逻辑可以直接砍掉,省了一大笔维护成本。
我强调一句,我不是说 jina-clip-v2 完美了,任何模型都做不到完美。但它是那种“针对生产场景做减法”的模型,知道用户真正要的是什么:稳定的向量、可对比的距离、扛得住脏数据。
2.3 快速体验:一段描述找一张图
如果你还没用过这类模型,我把最核心的流程拆给你看,其实不复杂:加载模型,对图片编码,对文本编码,算余弦相似度。下面是一段伪代码,具体接口以模型托管平台的最新说明为准。
# 伪代码:演示核心流程 model = load_multimodal_embedding("jina-clip-v2") img_vec = model.encode_image("商品图.png") text_vec = model.encode_text("红色手柄、带防滑橡胶的金属阀门") score = cosine_similarity(img_vec, text_vec) print(score)这段代码在老一代 CLIP 模型上的失败方式非常有代表性:“红色手柄”还能勉强命中,但“带防滑橡胶的金属阀门”这种长尾属性组合,基本不在模型的语义射程内。而在 jina-clip-v2 上,整段文本可以完整编码,多个属性信息能同时和图像区域建立关联,检索体验就完全不一样了。
3. MLLM 范式:它能理解,但未必适合 Embedding
聊完了 CLIP 路线,再来看看 MLLM 范式。这两年多模态大模型非常火,很多人会惯性思维:既然大模型这么强,直接把多模态大模型拿来做 Embedding,不是更省事?这个想法我在项目里试过,结论是:MLLM 确实能“理解”图像,但它给出的表示,和检索系统需要的 Embedding 是两回事。
3.1 MLLM 的基本架构与训练目标
MLLM 的典型结构是“视觉编码器 + 投影层 + 大语言模型”。图像先被切成 patch,变成一串视觉 token,投影层把这些 token 映射到大语言模型能理解的向量空间,之后和文本 token 拼接在一起,由大模型做自回归生成。于是 MLLM 能做图文对话、视觉问答、图表推理这些事。
这套结构的能力边界在于,它的主任务是生成,不是表示。训练目标是预测下一个 token,模型关心的是“这段上下文接下来最可能的输出是什么”,而不是“两张图的语义距离应该多近”。这两种目标在数学上完全不搭,模型内部算出来的向量自然也不会天然具备检索友好的性质。
3.2 为什么不能直接把 MLLM 的输出层当 Embedding 用
我经常被人问:大模型内部到处都是向量,直接抽一层的向量当 Embedding 行不行?我的回答是:能抽,能不能用就另说了。
第一,生成式模型的中间层向量没有刻意做“相似对象近邻”约束。比如一张红色汽车图,和一张红色椅子图,中间层向量可能更关注语言上的上下文关联,而不是视觉内容本身的相似性。你拿它做近邻搜索,出来的结果往往是不可解释的。
第二,MLLM 输出的是变长 token 序列,不是固定维度向量。检索系统需要把每个样本压缩成一条固定维度的向量,才好写进索引做 ANN、聚类。变长序列要么池化要么拼接,但是任意池化都会破坏语义结构,想要可靠结果就得重新训练一个嵌入头,那已经是另一套工程了。
第三,跨模态对齐的机制不一样。CLIP 式模型在训练时直接对文本向量和图像向量做对比约束,隐空间里的距离天然有意义;MLLM 虽然图文一起输入,但对齐是在跨层注意力里隐式完成的,最终得到的特征未必能在统一空间里直接算距离。
我常用一个比喻:MLLM 像一位很会讲解的导游,你问他路线,他能用各种方式描述得明明白白;但如果你需要一张可以直接量距离的地图,他还是拿不出来,因为导游的职业训练里没有“画标准坐标”这一项。你想让他同时当好导游和制图师,就得额外教他绘图课,那就是二次训练。
3.3 两种范式的关键差异一张表看懂
| 对比维度 | jina-clip-v2 为代表的 CLIP 式嵌入模型 | MLLM 范式 |
|---|---|---|
| 输出形态 | 固定维度向量,直接进向量库 | 变长 token 序列,需要额外策略才能转向量 |
| 训练目标 | 对比对齐,拉近匹配对、推远不匹配对 | 自回归生成,预测下一个 token |
| 跨模态检索 | 天然支持,直接用余弦距离 | 不直接可用,需要二次开发或重新训练 |
| 工程复杂度 | 低,部署轻,索引友好 | 高,显存占用大,推理链路长 |
| 核心适用任务 | 召回、排序、去重、聚类、RAG 最近邻 | 图文问答、内容理解、摘要生成、复杂推理 |
这张表基本解释了我对两个方向的定位:CLIP 式 Embedding 是“检索的底座”,MLLM 是“理解与生成的大脑”。两者在真实项目里往往是配合关系,而不是替代关系。
4. 三个落地场景里的对比观察
光聊概念没有意思,我直接把两种范式放到三个常见业务场景里做了对比,结果很能说明问题。
4.1 场景一:以文搜图
某内容库产品希望支持用户用自然语言找图。我采用 jina-clip-v2 式模型把全部图片离线编码好,写入向量索引;用户输入文本 query 后,编码成向量去库里做近似最近邻检索。上线后最明显的变化有两个:一是 query 长一些也没关系,二是细节词都能命中。
作为对比,如果我用 MLLM 来做这个场景的角色分配,它的强项是 query 改写。用户说“帮我找一张看着很专业、适合做汇报封面的图”,MLLM 可以把这个口语话的请求改写成“商务风、蓝灰色调、简洁构图、适合 PPT 背景”,然后再交给嵌入模型做召回。这个混搭方案效果很好,因为擅长什么就让谁干什么。
4.2 场景二:多模态 RAG 的知识召回
现在很多 RAG 系统处理的是图文混合文档,比如产品手册、设备说明书、研究报告。这类文档里大多是段落文字,但关键信息经常藏在图表、截图和流程图里。如果只做文本切块,图片中的信息就全部丢失了。
我的做法是:图像和表格单独切出来,用 CLIP 式嵌入模型做向量化,和文本向量放在同一个索引里。用户提问时,先由嵌入模型做多模态召回,把相关的文字段落和图片片段都捞出来,再丢给 MLLM 做阅读理解,生成最终答案。分工非常明确:召回归嵌入模型,理解归 MLLM。
还有个可行变体:先用 MLLM 给每张图生成描述,把描述加进文本侧,再由嵌入模型编码。等于让 MLLM 担任“信息预处理官”,把图片内容翻译成文本,嵌入模型再负责把这些内容统一成索引向量。这个方案对召回率的提升也很明显。
4.3 场景三:相似内容去重
内容平台经常需要判断两张图是否属于同一主题,比如用户上传的重复活动海报、相似商品图。这个任务对 Embedding 的稳定性要求很高:模型提取的特征,要经得住裁剪、轻微调色、压缩等干扰,相似对象之间的距离仍然要稳定。
CLIP 式嵌入模型因为训练时直接约束匹配距离,这种稳定性是它的禀赋。配合一个相似度阈值,可以粗召回大量重复内容。MLLM 在这个场景里更适合做“精判”:先用 Embedding 召回一批疑似重复项,再让 MLLM 对候选做一次确认性判断,给出结构化结果。我实践下来的体感是,粗召回靠 Embedding,精判靠 MLLM,效率最高。
5. 我曾尝试把 MLLM 当嵌入模型用:一次完整踩坑复盘
这一段我专门拿出来讲,因为我相信很多人都有过类似的想法,也都会踩同样的坑。有一段时间,团队要处理一批行业图纸和说明书的检索。当时有个观察:CLIP 式嵌入模型对“图中文字很多”的数据总是不够“懂”,因为图里的大量文字描述被视觉特征稀释了。于是团队里有人提出:不如直接把 MLLM 当作 Embedding 模型用,毕竟它理解力更强。听起来很有道理,我们就做了一次完整实验。
5.1 起因:被 MLLM 的理解能力打动
我先选了一个开源多模态小模型作为骨干,把图纸图片喂进去,取它倒数第二层的平均池化作为图像向量;文本侧也一样处理,把问题文本编码成向量;然后用向量数据库做检索。
最初设想很简单:MLLM 对图像的理解能力明显强于对比学习模型,它编码出的图像向量应该语义更丰富。但我们忘了一个关键差异——理解能力和检索能力是两回事。实验结果很快给了我们一记重击。
5.2 现象:相似图检索完全没有规律
第一轮测试跑完,现象非常明显:单独查图像与图像时,语义上明明同一类的图纸,向量距离忽远忽近,有时甚至和不相关图纸的距离差不多。我拿到结果一度以为索引写错了,反复检查了好几遍。
排查第一步,我用一批人工标注好的相似图对,分别计算 MLLM 特征和 CLIP 式嵌入的相似度分布。结果是 CLIP 式嵌入的区分度很清晰,相关图的距离明显更近;MLLM 特征则几乎看不出规律,相关图与不相关图的距离重叠严重。
第二步检查输出层。我把最后一层和倒数第二层都试了一遍,发现向量空间差异不大,但稳定性不好:同一张图稍微翻转或裁剪一下,余弦相似度波动很大。这说明问题不在预处理,而在模型本身的表示空间里,并没有一个“相似物体距离近”的约束。
第三步做跨模态验证,把文本 query 和 MLLM 图像特征做混合检索。这个环节的结果更差。文本和图像在自回归训练中并没有被显式地做对比对齐,所以两种模态的向量根本不在一个可比较的分布里,强行算相似度,结果和随机排序也没太大区别。
5.3 根因与修复:让嵌入回归嵌入
经过这轮排查,根因已经很清楚了:MLLM 的表示空间是“面向生成的”,不是“面向检索的”。它的主任务是推理生成,以此为目标的训练方式没有给我们想要的距离度量性质。想要获得稳定的检索特征,必须额外做对比学习训练或者外挂一个嵌入头,这个成本相当于重新训练一个小型检索模型。
最后我把方案改成了两条腿走路:先用 jina-clip-v2 式嵌入模型做图像和文本的召回,保证索引可比较、距离稳定;再用 MLLM 对 topK 结果做二次理解与排序,让“懂内容”的能力出现在后半段。对于图中文字多的场景,我额外加了 OCR 流程,把图里文字提取出来挂到图像旁作为文本补充。这样既发挥了 MLLM 的理解优势,又保住了检索链路的稳定性。
回头总结,这条坑踩得不冤,它让我彻底理解了“检索需要嵌入,理解需要生成”这句话,也让我后续做所有方案选型时,先问一句输入输出形态再动手。
6. 落地选型与部署避坑清单
最后聊点实用的。如果你现在要上一个多模态检索项目,面对一堆模型名词不知道怎么选,我把自己的判断逻辑和部署经验分享出来。
6.1 选型判断:看任务不看热度
我一直强调,技术选型不要看热搜榜,看任务本身要什么输出。我把任务分成三类,大家可以直接对号入座:
| 任务性质 | 建议主体模型 | 选择原因 |
|---|---|---|
| 跨模态检索、相似推荐、去重聚类 | CLIP 式嵌入模型 | 输出固定向量,对齐天然,向量库友好 |
| 图文问答、内容理解、摘要生成 | MLLM | 强项是推理与生成,不需要承担检索职责 |
| 检索与理解混合的业务 | 嵌入模型 + MLLM 分工 | 召回阶段用嵌入,理解与重排阶段用 MLLM |
这张表不是绝对的,但能解决 80% 的选型纠结。核心逻辑是:如果你的链路最后需要“算距离、排序、拿 topK”,那就一定要有一个稳定且对齐良好的 Embedding 空间;如果你需要“描述内容、回答问题、生成结论”,那就交给 MLLM。
6.2 部署时要盯住的几个细节
第一,模型精度和显存。CLIP 式嵌入模型一般比 MLLM 参数少很多,部署压力小,但也别掉以轻心。建议先用半精度或者 INT8 跑一轮压测,确认峰值显存和延迟,再上生产。图像输入尺寸大、文本长度长,这两类高负载场景要分开规划。
第二,向量维度一旦定下来,尽量别中途换模型。换模型意味着所有文档向量都要重新生成,否则旧 query 向量和新 doc 向量不在同一个语义空间,检索结果会是灾难性的。做灰度时务必新旧索引同时保留,逐步切换。
第三,向量索引参数不要照抄。HNSW 的 M 和 efConstruction 会影响召回率和内存占用,我一般从 M=32、efConstruction=200 起步,再用业务数据调优。图文混合投递时,单次 batch 大小和线程数要专门测,不能想当然按纯文本场景设置。
第四,上线前务必准备硬负样本集做召回率评测。我会挑 200 个正样本、200 个难负样本,比如视觉上相似但语义不同的图片对,看模型能否稳定区分。没有这一步,再好的模型上线都像闭着眼睛开飞机。
6.3 最后再分享一点个人体会
如果用一句话总结这次迭代复盘带来的实际收益,那大概是:我越来越不迷信模型名词,而是先问自己——我要的是统一向量空间里的相似匹配,还是跨模态理解与生成。前者首选把对比对齐做到极致的 CLIP 式嵌入模型,后者再看 MLLM。两者组合在一起,能覆盖绝大多数检索业务。
将来嵌入模型如果也能借助更强的生成能力做数据增强,比如用 MLLM 生成更多难样本、做模态补全,那只会让召回变得更好,并不会改变“检索需要嵌入、理解需要生成”的基本分工。至少在我目前做过的项目里,这个分工始终有效。