作者:来自 Sofia Vasileva

我们对 5,000 个真实产品进行了两种 embedding 模型的基准测试,结果发现,将图片与文本结合使用,比单独使用其中任何一种的效果最高可提升 50%。以下是测试数据,以及最终胜出的模型。
立即亲自体验用于 Search AI 的向量搜索,使用这个用于 Search AI 的**自助式动手学习。你现在可以开始 免费的云试用**,或者立即在你的本地机器上体验 Elastic。
一张图片胜过 1.5 倍的文字:我们从产品搜索 embeddings 基准测试中学到了什么
将图片和文本结合为一个 embedding ,比单独使用任意一种效果都更好,而且差距并不小。在我们的测试中,将图片和文本的 embeddings 取平均后,正确产品排在第一名的次数最高达到仅使用图片 embeddings 的 1.5 倍。我们使用两个 Jina embedding 模型 ------ jina-clip-v2 和 jina-embeddings-v5-omni-small ------ 对 5,000 个真实的英语和德语服装及鞋类产品进行了基准测试,以了解哪种模型以及哪种 索引 策略真正能够在 电子商务 搜索中胜出。较旧、更加专一的 Contrastive Language--Image 预训练(CLIP 风格)模型击败了较新、更通用的模型,这并不是我们预期的结果。本文将介绍测试数据、测试方法,以及我们建议你如何利用这些结果。
jina-clip-v2 与 jina-embeddings-v5-omni-small:有什么不同
多模态 embedding 模型通过在同一个高维空间中,为不同类型的输入生成具有代表性的语义向量来工作。

我们使用了两种能够完成这项工作的模型:
| 特性 | jina-clip-v2 | jina-embeddings-v5-omni-small |
|---|---|---|
| 架构 | 双编码器(独立的文本塔 + 图片塔) | 单一共享骨干网络 + 冻结编码器 |
| 参数量 | 约 8.65 亿 | 约 17.4 亿 |
| embedding 维度 | 1024 | 1024 |
| 最大输入 | 512×512 图片,8k token 文本 | 32k token |
| 语言覆盖 | 广泛的多语言支持 | 约 100 种语言 |
| 模态处理 | 文本 ↔ 图片对齐(专门设计) | 通过投影器支持文本、图片、音频和视频 |
jina-clip-v2 是一个 CLIP 风格的双 编码器:一个文本塔(Jina XLM-RoBERTa,5.61 亿参数)和一个独立的图片塔(EVA02-L14,3.04 亿参数),总参数量约为 8.65 亿。这两个塔分别进行训练,但经过联合微调,以便输出到同一个语义空间。它生成 1024 维 embeddings,支持最大 512×512 的图片和最长 8k token 的文本,并提供广泛的多语言支持。它专门针对文本到图片、图片到文本以及文本到文本匹配进行了设计。
jina-embeddings-v5-omni-small 的覆盖范围更广。它在 [jina-embeddings-v5-text](https://jina.ai/models/jina-embeddings-v5-text-small/ "jina-embeddings-v5-text") 模型的基础上进行了扩展,通过将冻结的视觉编码器和音频编码器连接到冻结的文本骨干网络,使其支持图片、音频和视频。这些编码器通过 跨模态投影器 (cross-modal projectors)连接,这些投影器是经过训练的小型网络层,用于将各个编码器的输出映射到文本模型的 embedding 空间 。这些投影器是模型中唯一接受额外训练的部分。最终得到的模型生成 1024 维 embeddings,支持最长 32k token 的输入上下文,并覆盖约 100 种语言。它以非对称方式对查询和文档进行编码:查询 使用 retrieval.query 任务,而文档 使用 retrieval.passage。
这两个模型之间存在一个重要的功能差异:jina-clip-v2 实际上是两个独立训练并协同工作的模型,而 jina-embeddings-v5-omni-small 使用一个共享的骨干网络,为它支持的所有媒体类型生成 embeddings。所有模态都会映射到同一个共享 向量 空间。从理论上讲,它能够处理文本、图片、音频或视频,也能够将不同媒体类型的内容组合为一个输入,并生成一个涵盖所有数据的 embedding。
不过,在使用 jina-embeddings-v5-omni-small 时有两个重要的注意事项:将图片和文本组合到同一个输入中,是该模型已知的一个弱点;此外,Jina API 每次请求只允许用户对一种模态生成 embedding。从理论上讲,它能够创建联合的图片和文本向量,但在实际使用中,你无法通过 API 实现这一点(而且无论如何也不建议这样做)。
我们使用的电子商务产品数据集
在本文中,我们下载了 Kaggle 上的 Fashion Product Images 数据集。该数据集包含约 44,000 条来自真实时尚零售商的产品目录记录,每条记录都包含一张高分辨率图片和结构化元数据。我们仅使用了 Apparel(服装)和 Footwear(鞋类)两个类别(约 30,600 个产品),并使用固定的随机种子从中抽样了 5,000 个产品。
对于每个产品,数据集包含三类记录:
-
每个产品都有一张 1800×2400 的 JPEG 图片,背景干净简洁。
-
元数据,包含
gender、masterCategory、subCategory、articleType、baseColour、season、year、usage和productDisplayName等标签。 -
一组附加信息,包含
Neckline、Pattern、Sleeve Length、Fit和Fabric等标签,以及一段英文自由文本描述。
例如,编号为 #13885 的商品标注为"Scullers Men Check Black Shirts ",附带一张产品图片(见下图),以及如下描述:"黑白格纹衬衫,由 100% 棉制成,全长纽扣门襟,长袖,纽扣袖口。"

我们如何生成搜索查询
我们生成测试查询时没有使用 AI 语言模型,而是使用规则和替换列表。
对于每个产品,我们从它的颜色和商品类型开始,然后从产品可用的元数据中随机添加一个描述性修饰词:领口、图案、袖长、长度、表面样式、版型、面料、季节或用途。之后,我们通过从固定的同义词表中替换词语,对查询进行改写。这样可以避免生成重复使用目录自身词语的查询。
例如,″t-shirt″ 会变成 ″tee″ ,″regular fit″ 会变成 ″classic cut″ ,″printed″ 会变成 ″with graphic design″ ,″sleeveless″ 会变成 ″no sleeves″ 。替换时会优先替换包含同义词的最长短语,因此我们会替换 ″sports shoes″ ,而不是仅替换 ″shoes″。
由于该流程基于规则并使用固定随机种子,因此查询生成过程具有可复现性,并且所有变化都会被考虑在内。德语查询也使用相同方式生成,只是使用德语词汇表,然后由母语者对其进行修正,使其符合自然的零售表达方式。
一些示例:
bash
`
1. # usage / occasion
2. "in casual style": "for everyday wear",
3. "in formal style": "for the office",
4. "in sports style": "for working out",
5. "in ethnic style": "in traditional wear",
6. "in party style": "for a night out"# article types
7. "t-shirt": "tee",
8. "trousers": "pants",
9. "sweatshirt": "pullover",
10. "sweater": "knit pullover",
11. "kurta": "tunic",
12. "capris": "cropped pants",
13. "track pants": "joggers",
14. "innerwear vest": "undershirt",
15. "briefs": "underwear"
16. # colours (safe near-equivalents)
17. "navy blue": "dark blue",
18. "off white": "cream",
19. "maroon": "deep red",
`AI写代码
德语查询使用了它们自己的术语表,将相同的目录属性映射为自然的德语零售表达方式(之后由母语者进行检查)。一些示例:
我们测试的六种 embedding 配置
我们在六种配置下测试了检索 ,每个测试条件都使用相同的文本查询,并使用相同的 5,000 个产品索引数据集。对于 jina-clip-v2 和 jina-embeddings-v5-omni-small,我们测试了三种不同的生成 embedding 用于索引的方法:
-
仅图片。 我们仅使用图片生成 embeddings,不包含任何其他数据。
-
仅文本。 我们仅使用自由文本描述生成 embeddings。
-
图片和文本平均值。 对于每个产品,我们分别为图片和文本描述生成 embeddings,然后将两个向量进行平均,合成为一个向量。
我们使用 Jina API 为产品图片和自由文本描述生成文档和查询 embeddings,如下面的代码所示。所有图片在处理之前都会调整大小,以适配 512x512 像素的正方形尺寸。
ini
`
1. import requests
3. def embed(inputs, model, task=None):
4. body = {"model": model, "input": inputs}
5. if task:
6. body["task"] = task
7. response = requests.post(
8. "https://api.jina.ai/v1/embeddings",
9. headers={"Authorization": f"Bearer {JINA_API_KEY}"},
10. json=body, timeout=120,
11. )
12. response.raise_for_status()
13. return [d["embedding"] for d in response.json()["data"]]
15. # Query example using text
16. query_vec = embed([{"text": "T-Shirt in Grau für den Herbst"}],
17. "jina-embeddings-v5-omni-small", task="retrieval.query")
19. # Document example using an image. "
20. # image_base64" is the resized and base64 encoded PNG.
21. image_vec = embed([{"image": image_base64}],
22. "jina-embeddings-v5-omni-small", task="retrieval.passage")
`AI写代码
我们通过分别对图片和文本生成 embedding,然后将两个向量取平均,最后对结果进行归一化来组合图片和文本,这样可以加速计算余弦相似度。由于两种 embedding 共享同一个语义空间,因此这种方法适用于多模态模型。两个向量的和会形成一个新的向量,其中包含两者的语义特征。
使用 Python 中的 numpy 包可以非常轻松地完成这一操作。我们使用了下面的代码:
python
`
1. import numpy as np
3. def l2(x): # includes row-wise L2 normalization
4. return x / np.linalg.norm(x, axis=1, keepdims=True)
6. # image_vecs and text_vecs are embeddings of the same products.
7. # They share one space, so averaging them is meaningful.
8. combined = l2((l2(image_vecs) + l2(text_vecs)) / 2)
`AI写代码
对于本文,我们进行了精确检索,计算查询与所有 5,000 个存储产品 embeddings 之间的余弦相似度。在 Elasticsearch 中,我们会使用一种近似方法来获得相同的结果。从排序后的结果中,我们计算了 Recall@1、Recall@5、Recall@10、平均倒数排名(MRR)以及位置 10 的归一化折损累计增益(nDCG@10)。
每个查询都只有一个正确答案,因此 Recall@K 表示正确产品出现在前 K 个结果中的查询所占比例。MRR 根据正确答案距离顶部结果的位置远近对结果进行评分。nDCG@10 是一种标准指标,它会惩罚将最佳答案放在结果列表较低位置的情况。
产品搜索基准测试结果
下面的表格展示的是德语跨语言测试结果。我们评估了使用德语查询查找具有英文描述的产品的效果:

使用德语文本查询以及服装图片和英文描述,对 jina-clip-v2 和 jina-embeddings-v5-omni-small 进行查询基准测试的结果。
无论使用 jina-clip-v2 还是 jina-embeddings-v5-omni-small,图片/文本平均 embeddings 都取得了最佳效果。令人意外的是,来自 jina-clip-v2 的平均向量位列表现最佳。它将正确产品排在第一位的频率约为仅使用图片配置的 1.5 倍,并且明显高于仅使用文本配置的结果。此外,它还超过了 jina-embeddings-v5-omni-small 的所有测试条件。
以下是使用英语查询进行相同测试的结果:

使用英语文本查询以及服装图片和英文描述,对 jina-clip-v2 和 jina-embeddings-v5-omni-small 进行查询基准测试的结果。
在相同的 5,000 个产品上进行的英语测试得出了相同的结论。主要区别在于,jina-embeddings-v5-omni-small 的得分明显更接近 jina-clip-v2,尽管仍然低于它。
基准测试分数实际代表什么
上面德语和英语基准测试表中的相对较低分数是可以预期的。这是一个真实世界的数据集,其中充满了高度相似的产品。例如,搜索 "black tee with classic cut/经典剪裁的黑色 T 恤" 时,需要在几十件基础款黑色 T 恤中进行排序,即使是在最佳的电子商务网站上,也会预期出现类似结果。
重要的是理解不同测试条件之间的分数差异,而不是它们的绝对值。我们的关键发现是,将文本和图片 embeddings 结合起来,比单独使用其中任何一种都有更好的性能,这突出了由多模态 AI 驱动的搜索如何利用不同的信息来源,比非多模态策略产生更好的性能。
当一张图片胜过千言万语,以及什么时候不是这样
将图片添加到文本 embeddings 中带来的收益并不是均匀分布的。我们深入分析了结果,查看是否存在某种规律,并发现了以下几点:
-
图片对于视觉上具有明显特征的商品和属性帮助很大。 例如,在鞋类产品中,仅图片检索的效果与仅文本检索相当:Recall@1 分别为 0.029 和 0.028。鞋子的款式具有明显的形状特征,因此图片可以发挥作用(仅图片 0.029,对比文本 0.028)。对于更广泛的可见属性(颜色、图案、袖长)也是如此,在这些情况下,融合图片和文本相比仅使用文本带来了最大的提升(0.085 对比 0.073)。
-
图片对于模型无法观察到的内容帮助最小。 例如,如果我们查询面料类型,将图片加入 embeddings 几乎没有带来任何提升。人类和 AI 模型都难以判断某件商品是否由亚麻、聚酯或其他类型的面料制成。这些信息只存在于文本描述和元数据中。
作为经验法则,我们发现服装搜索更依赖准确的文本描述,而鞋类搜索更依赖图片的语义。但在这两种情况下,合并两个 embeddings 要么提升结果,要么不会使结果变差。这说明具体使用场景的特点决定了最佳搜索策略。
跨语言查询从多模态 embeddings 中获得巨大收益
使用 jina-clip-v2 时,仅文本 embeddings 与图片和文本组合 embeddings 之间的性能差距,在德语查询中(Recall@1 为 0.074 对比 0.065)明显大于英语查询(0.076 对比 0.075)。
这意味着英语查询可以利用与产品描述相同语言带来的优势。无论这是因为词语之间存在重叠,还是因为模型在单语言语义理解方面比跨语言理解更强,都不重要。但将图片加入文本 embeddings,几乎完全弥补了模型在跨语言检索方面的不足。
对于 jina-embeddings-v5-omni-small,这个差距甚至更大。在任何跨语言或多语言场景中,多模态 embeddings 似乎都能够显著提升检索性能。
AI 生成的产品描述可以替代人工描述吗?
在我们的测试中,AI 生成的描述得分低于人工编写的描述。我们尝试使用基于图片生成描述的 [jina-vlm](https://jina.ai/models/jina-vlm "jina-vlm") 替换人工编写的产品描述。在这个测试中,我们使用了随机抽取的 1,000 个产品子集。
结果明显比原始人工文本差。这符合我们的预期:自动生成的描述准确性较低,并且不像人工编写的描述那样关注产品的重要特征。
所以事实证明,并不是所有人的工作都可以被 AI 替代。现在,为产品目录撰写描述的人应该还是安全的。
你应该如何索引你的电子商务数据?
我们的测试并不完全符合严格的科学标准,但它们确实提供了一些关于如果你拥有类似数据时可能遇到的问题的洞察。我们提出以下作为暂定结论:
-
如果你拥有匹配的文本和图片(大多数目录都拥有),请将它们组合到你的 embeddings 中。 在所有情况下,使用 Elastic 提供的类似 Jina AI 的多模态 embedding 模型 ,然后对图片和文本 embeddings 进行平均,都明显优于其他所有方案。这种组合不会增加 推理 时的计算成本,但会在生成 embedding 时产生额外成本。对于每个产品,你需要生成两个 embeddings 并将它们组合,这大约会使成本增加一倍。
-
使用正确的模型。 你需要确定一个支持你计划使用的所有模态和语言的模型。所有输入必须被嵌入到同一个语义向量空间中,否则这一切都无法工作。你不能使用两个单模态模型或多个特定语言的文本模型,然后对它们的输出取平均,并希望获得最佳结果。Elastic 提供的 Jina AI 当前支持最多 100 种语言的文本,包括计算机代码和技术术语;支持各种类型的图片,例如扫描件和信息图;以及音频和视频数据。你之后可以改变模型选择,但前提是你愿意重新索引所有数据。
-
无论你选择什么,都要在自己的数据上进行测试。 想知道对于你、你的数据和你的使用场景来说最佳模型是什么,唯一方法就是实际尝试。我们非常惊讶于在这个数据集中,较旧的 CLIP 风格模型击败了最新模型,但这是因为它几乎就是针对这个使用场景训练的。你的数据和使用场景很容易得出相反的结果。这个结果来自一个目录、一种摄影风格以及一种查询类型。如果领域、图片风格或查询组合不同,两个模型之间的排名可能会发生变化。在做出最终选择之前,请在你自己的产品样本上运行类似的基准测试。这是唯一能知道哪个模型真正适合你的方法。
-
使用生成的描述来填补缺失,而不是替代优秀的文本。 AI 不是替代认真工作的人所创造的高质量内容的工具。用机器生成的描述替换人工描述会导致结果变差。只有在必须使用 AI 时,例如数据缺失、需要补充数据,并且让人工填补这些空白不现实的情况下,才应该让 AI 替代人工。是的,我们有适用于这些场景的工具,但它们并不一定是好的替代品。有时,它们只是还可以的替代品。
对你的 embeddings 取平均。 语义 embeddings 非常稳定,而对它们取平均是一种成本相对较低的解决方案,并且完全不会影响推理阶段的成本。这相比于分别索引每种模态、并且需要多次查询才能满足单个请求的方法,是一个真正的优势。但它确实要求使用兼容的多模态模型。
这个产品搜索基准测试的限制
在从这个实验中进行过度推广之前,需要注意以下几点:
这篇文章并不能完全匹配真实世界的使用场景。真实用户会提出更加混乱的查询,并且具有更加模糊的匹配标准。我们使用的查询是专门为这些数据生成的。如果使用系统日志中的真实客户查询进行测试,会更加合理。
embedding 平均值并不等同于真正的联合 embedding。Embedding 模型依靠输入不同部分之间的交互来提取整体语义表示。本文使用的方法有一点取巧,它依赖语义 embedding 空间的稳定特性来完成任务。我们预计未来 Jina AI 的模型将通过一次支持多个输入模态,生成更好的 embeddings。
这是一个单一领域中的单个数据集,并且具有明显特征。时尚摄影通常高度聚焦主体,而描述中包含丰富的属性信息。其他类型的材料,即使是在电子商务领域,也可能完全不同。尽可能使用你自己的数据,或者非常相似的数据进行测试非常重要。
如何开始使用多模态产品搜索 embeddings
jina-clip-v2 和 jina-embeddings-v5-omni-small 可以通过 Jina API、Elastic Inference Service](EIS)以及 Hugging Face 获取。Omni 模型可以在 CC-BY-NC-4.0 许可证下免费下载,并且可以免费用于非商业用途;商业许可则通过 Elastic 提供。如果你使用 Elasticsearch,EIS 会通过 semantic_text 字段类型提供这两个模型,并支持使用 Base64 编码表示非文本媒体。
本文的核心结论旨在实用且可执行:对于产品搜索,图片和它的描述并不是相同的信息信号。两者都会提供额外信息,你不必二选一。对你的多模态 embeddings 取平均,并使用你自己的数据进行基准测试,从而了解你可以期待获得什么类型的结果。
原文:Multimodal embeddings for ecommerce product search - Elasticsearch Labs