Featured image of post RAG之关键Embedding模型国内外大PK

RAG之关键Embedding模型国内外大PK

虽然大模型支持的上下文是越来越大,但不论出于知识库过大还是基于安全考虑,我们还是希望向模型提供适当的上下文即可。这其中选择合适的embedding模型就至关重要了。如何才能找到效果更好的embedding型呢,希望本文能提供一些参考。

背景

我们不能为技术而技术,最好是解决某项具体问题而进行探索。我为何想去了解embedding这块呢?缘于最近MCP比较火,而我工作中经常需要分析一些仓库的提交历史,以发现某些内容的引入或修改历史,即我想和git历史进行交谈。虽然有时咱传统方式也能做,但写个MCP可以用自然语言获得诸如:

  • XX玩法是谁负责的
  • A最近开发的了哪些内容
  • 最近一个月主要有哪些功能在开发
  • 今年3月份有哪些功能
  • 某个文件最近有哪些修改

这一些问题的答案那自然是极好的。这些信息或许可基于git log等进一步检索,而我们一个大项目是由几十个小仓组成的,难度就上升了一层。不过完整的解决方案已经开发得差不多了,今天就先聊一下如何解决第一个挑战,embedding!我计划了一场PK赛,看看哪个模型更适合我的场景。

先叠一层甲,我本人非AI领域人员,基于爱好和专用场景测试,受于个人知识限制,可能存在理解偏差,欢迎指正。

国内外模型介绍

什么是embedding呢?wikipedia的描述比较抽象,以下是腾讯混元T1的解释:

Embedding模型是一种将高维数据(如文本、图像)映射到低维向量空间的技术,通过保留原始数据的语义和特征信息,实现高效计算与相似性分析。其核心原理是通过神经网络训练,将相似的数据点映射到向量空间中的相近位置,例如"猫"和"狗"的向量比"猫"和"苹果"的更接近,从而捕捉语义关联。

在huggingface上有一个排行榜,可以查看不同模型的效果。用于了解有哪些模型还不错,但我们具体使用上还是实测可能更靠谱。

我计划选择免费开源的一些模型,同时也测试一些闭源模型看其提升有多大,是否值得咱付费使用。而这个测试场景,大概有如下几步:

  1. 由AI生成一些git commit message。
  2. 基于这些message交给待测试的各个embedding模型来向量化。
  3. 通过输入Query问题进行相似度(余弦相似度)检索,获得Top5的commit message。
  4. 交给AI对各个embedding模型进行打分(有点重复工作量,我们看看AI表现),看Query出的质量如何?

实测上有一些意想不到的结果呢,让我们拭目以待。

开源embedding模型介绍

在网上查看了一些资料后,我选择了如下几个被推荐较多的模型用于后续测试。

模型名称描述维度最大token支持语言
text-embedding-gte-large-zhGTE大型中文嵌入模型(本地)1024512中文
text-embedding-bge-large-zh-v1.5百度开源的中英双语大型嵌入模型(本地)1024512中文、英文
text-embedding-m3e-baseM3E基础嵌入模型(本地)768512中文、英文
text-embedding-granite-embedding-278m-multilingualGranite多语言嵌入模型(本地)768512多语言(英文、德文、西班牙文、法文、日文、葡萄牙文、阿拉伯文、捷克文、意大利文、韩文、荷兰文、中文等)
text-embedding-multilingual-e5-large-instructE5大型多语言嵌入模型1024512多语言

原本jina-embeddings系列模型也想一并参赛的,无奈在LM Studio中支持得不太好,可能缘分未到,暂时跳过。若有朋友有使用经验,不妨留言分享一下实际效果。

闭源大厂embedding模型介绍

以OpenAI为首的如text-embedding-3系列,以及国内各个大厂BAT以及字节等都有自己的embedding模型都获得了参赛资格。这取决于我之前在OneAPI提到过收集的模型提供商了,只要他们有embedding模型,都跃跃欲试进组PK。

模型名称描述维度最大词元数支持语言
text-embedding-3-largeOpenAI第三代大型嵌入模型30728191多语言
hunyuan-embedding腾讯混元嵌入模型10241024中文、英文
doubao-embedding-large-text-240915豆包嵌入模型10244096中文、英文
Baichuan-Text-Embedding百川嵌入模型1024512中文、英文
text-embedding-v3通义千问嵌入模型10248192中文、英文
Embedding-V1百度嵌入模型1024384中文、英文

可以发现:收费的模型虽然咱还没有开赛,但肉眼一看,三围(维度、最大token、支持语言)上已经领先了:)果然没点特色,还真不敢收费。额,那个百度,百川你们咋回事?

Embedding竞技场

为了公平公正,本次PK全过程已经记录在Github仓库: https://github.com/kevin1sMe/embedding-selector,欢迎大家围观。

先公布考题吧,我让AI生成了如下的测试数据以及Query的问题:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
测试数据集:中文和中英文混合的commit messages
"""

# 各种风格的commit messages作为测试数据
COMMIT_MESSAGES = [
    # 纯中文commit messages
    "修复首页加载速度慢的问题",
    "优化用户登录流程",
    "新增数据导出功能",
    "修复了用户反馈的崩溃问题",
    "更新文档说明",
    "重构了代码结构,提高了可维护性",
    "删除了废弃的API调用",
    "添加单元测试用例",
    "修改了配置文件中的默认设置",
    "解决了在iOS设备上的兼容性问题",
    
    # 中英文混合的commit messages
    "fix: 修复了登录页面的bug",
    "feat: 添加了新的payment接口",
    "docs: 更新API文档",
    "refactor: 重构用户认证模块",
    "test: 增加了对checkout流程的测试",
    "style: 调整了UI组件的样式",
    "perf: 优化了数据库查询性能",
    "chore: 更新了package依赖",
    "fix(ui): modal组件关闭按钮失效问题",
    "feat(api): 新增用户数据同步endpoint",
    
    # 技术专业术语混合的commit messages
    "修复Redis连接池泄露问题",
    "优化React组件的渲染性能",
    "新增Elasticsearch索引管理功能",
    "重构JWT认证逻辑,提高安全性",
    "解决了Docker容器内存占用过高的问题",
    "添加GraphQL查询缓存机制",
    "更新了Webpack配置,提高构建速度",
    "修复了多线程并发导致的数据不一致问题",
    "添加了对WebSocket连接的心跳检测",
    "优化了MongoDB聚合查询的执行效率",
    
    # 团队协作相关的commit messages
    "根据Code Review反馈修改代码",
    "合并develop分支的最新更改",
    "准备v2.0.0版本发布",
    "修复QA团队报告的regression问题",
    "实现了产品经理提出的新需求",
    "临时提交,WIP:用户管理模块",
    "协同后端API调整相应的前端代码",
    "根据UI设计稿更新组件样式",
    "添加了新功能的feature flag",
    "解决合并冲突,保留双方更改",
]

# 用于测试的查询语句
TEST_QUERIES = [
    # 功能相关查询
    "如何修复bug",
    "添加新功能",
    "更新文档",
    "优化性能",
    "重构代码",
    
    # 技术相关查询
    "关于React组件的提交",
    "数据库优化",
    "API开发",
    "UI界面调整",
    "Docker相关问题",
    
    # 过程相关查询
    "代码审查后的修改",
    "版本发布准备",
    "修复测试中发现的问题",
    "合并分支",
    "解决冲突"
] 

开源赛区

开源赛区的模型,我是使用的本地LM Studio部署的,已经尽量选择了当前(2025-3-29)最新版本。 LM Studio 本次参赛的5大选手,我们就叫他们F5吧,比赛开始!

1
2
3
4
5
6
7
python3 scripts/run_test.py -m \
    text-embedding-m3e-base \
    text-embedding-bge-large-zh-v1.5 \
    text-embedding-gte-large-zh \
    text-embedding-granite-embedding-278m-multilingual \
    text-embedding-multilingual-e5-large-instruct \
    -o results/open-source-f5.json

虽然是本地部署,就这点计算量,分秒就拿捏了,我们看一下他们的成绩:

模型处理时间(秒)数据量
text-embedding-m3e-base0.740
text-embedding-bge-large-zh-v1.51.1840
text-embedding-gte-large-zh1.1240
text-embedding-granite-embedding-278m-multilingual0.6840
text-embedding-multilingual-e5-large-instruct1.2340

我们查看open-source-f5.json的输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
  {
    "model_name": "text-embedding-m3e-base",
    "precision@1": 0.0,
    "precision@3": 0.0,
    "precision@5": 0.0,
    "processing_time": 0.6969938278198242,
    "query_results": [
      {
        "query": "如何修复bug",
        "top_results": [
          {
            "rank": 1,
            "message": "fix: 修复了登录页面的bug",
            "score": 0.837168656326853
          },
          {
            "rank": 2,
            "message": "修复了用户反馈的崩溃问题",
            "score": 0.8329215028808162
          },
          {
            "rank": 3,
            "message": "根据Code Review反馈修改代码",
            "score": 0.8251477839600121
          },
// 省略后续行      

内容很多,眼花缭乱,我们先让AI来评测打分,选择了当前号称地表最强的Google新模型Gemini-2.5-Pro experimental 03-25来打分,看看效果如何?"

模型检索结果对比表

注: 限于篇幅只截取一部分,完整内容查看代码仓库。

查询语句text-embedding-m3e-basetext-embedding-bge-large-zh-v1.5text-embedding-gte-large-zhtext-embedding-granite-embedding-278m-multilingualtext-embedding-multilingual-e5-large-instruct
如何修复bug1. fix: 修复了登录页面的bug (0.837)2. 修复了用户反馈的崩溃问题 (0.833)3. 根据Code Review反馈修改代码 (0.825)4. 修复了多线程并发导致的数据不一致问题 (0.807)5. 修复QA团队报告的regression问题 (0.791)1. 修复了用户反馈的崩溃问题 (0.599)2. fix: 修复了登录页面的bug (0.581)3. 修复了多线程并发导致的数据不一致问题 (0.576)4. 根据Code Review反馈修改代码 (0.541)5. 修复Redis连接池泄露问题 (0.532)1. fix: 修复了登录页面的bug (0.623)2. 修复了用户反馈的崩溃问题 (0.608)3. 修复首页加载速度慢的问题 (0.592)4. 修复Redis连接池泄露问题 (0.555)5. 协同后端API调整相应的前端代码 (0.527)1. fix: 修复了登录页面的bug (0.770)2. 修复了用户反馈的崩溃问题 (0.724)3. 修复Redis连接池泄露问题 (0.688)4. 修复首页加载速度慢的问题 (0.687)5. 修复QA团队报告的regression问题 (0.682)1. 修复QA团队报告的regression问题 (0.918)2. 修复了用户反馈的崩溃问题 (0.916)3. fix: 修复了登录页面的bug (0.914)4. 根据Code Review反馈修改代码 (0.907)5. 重构了代码结构,提高了可维护性 (0.895)
添加新功能1. 新增数据导出功能 (0.859)2. 添加了新功能的feature flag (0.845)3. feat: 添加了新的payment接口 (0.822)4. 新增Elasticsearch索引管理功能 (0.815)5. 更新了Webpack配置,提高构建速度 (0.812)1. 新增数据导出功能 (0.710)2. 添加了新功能的feature flag (0.653)3. feat: 添加了新的payment接口 (0.637)4. 实现了产品经理提出的新需求 (0.631)5. 优化用户登录流程 (0.625)1. 新增数据导出功能 (0.627)2. 添加了新功能的feature flag (0.602)3. 实现了产品经理提出的新需求 (0.548)4. feat: 添加了新的payment接口 (0.524)5. 根据UI设计稿更新组件样式 (0.511)1. 添加了新功能的feature flag (0.875)2. 新增数据导出功能 (0.804)3. feat: 添加了新的payment接口 (0.792)4. 新增Elasticsearch索引管理功能 (0.702)5. 实现了产品经理提出的新需求 (0.687)1. 添加了新功能的feature flag (0.954)2. 新增数据导出功能 (0.944)3. 实现了产品经理提出的新需求 (0.933)4. 更新文档说明 (0.931)5. 合并develop分支的最新更改 (0.924)
更新文档1. 更新文档说明 (0.957)2. docs: 更新API文档 (0.888)3. chore: 更新了package依赖 (0.791)4. 更新了Webpack配置,提高构建速度 (0.785)5. 合并develop分支的最新更改 (0.774)1. 更新文档说明 (0.857)2. docs: 更新API文档 (0.772)3. 新增数据导出功能 (0.580)4. 根据UI设计稿更新组件样式 (0.577)5. 修改了配置文件中的默认设置 (0.558)1. 更新文档说明 (0.871)2. docs: 更新API文档 (0.791)3. 合并develop分支的最新更改 (0.586)4. 新增数据导出功能 (0.582)5. 添加了新功能的feature flag (0.541)1. 更新文档说明 (0.930)2. docs: 更新API文档 (0.804)3. chore: 更新了package依赖 (0.691)4. 合并develop分支的最新更改 (0.667)5. 准备v2.0.0版本发布 (0.653)1. 更新文档说明 (0.980)2. docs: 更新API文档 (0.953)3. 新增数据导出功能 (0.920)4. 准备v2.0.0版本发布 (0.919)5. 合并develop分支的最新更改 (0.914)
优化性能1. 优化React组件的渲染性能 (0.841)2. perf: 优化了数据库查询性能 (0.817)3. 修改了配置文件中的默认设置 (0.800)4. 解决了Docker容器内存占用过高的问题 (0.798)5. 修复首页加载速度慢的问题 (0.794)1. 优化React组件的渲染性能 (0.632)2. perf: 优化了数据库查询性能 (0.595)3. 优化用户登录流程 (0.586)4. 重构了代码结构,提高了可维护性 (0.564)5. 修复了多线程并发导致的数据不一致问题 (0.554)1. 优化React组件的渲染性能 (0.645)2. perf: 优化了数据库查询性能 (0.611)3. 更新了Webpack配置,提高构建速度 (0.581)4. 修复了用户反馈的崩溃问题 (0.572)5. 解决了在iOS设备上的兼容性问题 (0.567)1. perf: 优化了数据库查询性能 (0.726)2. 优化React组件的渲染性能 (0.719)3. 优化用户登录流程 (0.684)4. 修复首页加载速度慢的问题 (0.644)5. 更新文档说明 (0.631)1. perf: 优化了数据库查询性能 (0.931)2. 优化React组件的渲染性能 (0.925)3. 优化用户登录流程 (0.913)4. 修复首页加载速度慢的问题 (0.907)5. 优化了MongoDB聚合查询的执行效率 (0.905)

评估和分析

从上面的表格中,我们可以看到不同模型在不同查询语句下的表现。总体来看:

  • text-embedding-multilingual-e5-large-instruct 在所有查询语句下都给出了相对较高的分数,并且结果的相关性也比较高。这表明该模型在理解中文和中英文混合的commit messages以及查询意图方面表现出色。
  • text-embedding-m3e-base 在很多查询中也能给出较高分数, 但是部分结果相关性存在一定问题。
  • text-embedding-granite-embedding-278m-multilingual 的整体表现相对均衡,但分数普遍低于text-embedding-multilingual-e5-large-instruct,可能意味着它在语义理解的深度上稍逊一筹。
  • text-embedding-bge-large-zh-v1.5text-embedding-gte-large-zh 的分数普遍偏低,可能表明它们更适合特定类型的任务,或者在处理commit messages这类混合语言和专业术语的数据时,效果不佳。

判断依据

  1. 相关性: 模型返回的结果是否与查询语句的意图高度相关。例如,对于"如何修复bug"的查询,返回的结果应该集中在bug修复相关的commit messages上。
  2. 准确性: 模型返回的结果是否真实反映了commit message的内容。
  3. 排序: 相关性高的结果是否排在前面,也就是考察模型的排序能力。
  4. 分数: 虽然分数不能完全代表模型的质量,但一般来说,分数越高,代表模型对结果的置信度越高。
  5. 整体表现的稳定性: 模型在不同类型的查询语句下是否都能保持较好的表现。

结论

综合以上分析, text-embedding-multilingual-e5-large-instruct 模型最适合我们的commit message检索任务。它的分数更高,结果相关性也更高,表明它能够更好地理解查询意图,并返回更准确、更有用的结果。 在检索的准确性,覆盖范围和稳定性上都更好,能够胜任commit message检索这类任务。 虽然其他模型在某些特定查询下可能表现良好,但整体来看,text-embedding-multilingual-e5-large-instruct 在所有查询类型下都更加稳定和可靠。

我们再看一下上面各模型的大小,text-embedding-multilingual-e5-large明显比其它都大一些,或为其中原因,当然也可能大只是因为支持多语言。不过在这个模型参赛前,其它4个模型偷偷比武了一番,结果text-embedding-m3e-base这个尺寸最小的模型夺魁,这么说来,也并不是“底大一级压死人”啊:)

闭源赛区

我们照葫芦画瓢的测试方式,这次将这些付费模型拉出来遛遛。我们先让国内各家来个PK,再看看和国外差距是否明显。国内“获得”测试资格的模型之前已经提过,我们直接看成绩(限于篇幅只截取一部分,完整内容查看代码仓库):

查询语句hunyuanbaiduqwendoubaobaichuan
如何修复bug1. 修复了用户反馈的崩溃问题2. 修复首页加载速度慢的问题3. fix: 修复了登录页面的bug4. 修复了多线程并发导致的数据不一致问题5. 修复Redis连接池泄露问题1. fix: 修复了登录页面的bug2. 修复了用户反馈的崩溃问题3. 修复了多线程并发导致的数据不一致问题4. 修复首页加载速度慢的问题5. 修复Redis连接池泄露问题1. 修复了用户反馈的崩溃问题2. fix: 修复了登录页面的bug3. 修复Redis连接池泄露问题4. 修复QA团队报告的regression问题5. 根据Code Review反馈修改代码1. 修复QA团队报告的regression问题2. fix: 修复了登录页面的bug3. 修复了用户反馈的崩溃问题4. 根据Code Review反馈修改代码5. 修复了多线程并发导致的数据不一致问题1. 修复了用户反馈的崩溃问题2. fix: 修复了登录页面的bug3. 修复了多线程并发导致的数据不一致问题4. 修复首页加载速度慢的问题5. 根据Code Review反馈修改代码
添加新功能1. 新增数据导出功能2. 实现了产品经理提出的新需求3. 添加了新功能的feature flag4. feat: 添加了新的payment接口5. chore: 更新了package依赖1. 新增数据导出功能2. 添加了新功能的feature flag3. 新增Elasticsearch索引管理功能4. 更新文档说明5. 实现了产品经理提出的新需求1. 添加了新功能的feature flag2. 新增数据导出功能3. feat(api): 新增用户数据同步endpoint4. 更新文档说明5. 实现了产品经理提出的新需求1. 更新文档说明2. 添加了新功能的feature flag3. 优化用户登录流程4. 删除了废弃的API调用5. 重构了代码结构,提高了可维护性1. 新增数据导出功能2. 添加了新功能的feature flag3. 优化用户登录流程4. 实现了产品经理提出的新需求5. feat: 添加了新的payment接口
更新文档1. 更新文档说明2. docs: 更新API文档3. chore: 更新了package依赖4. 更新了Webpack配置,提高构建速度5. 根据Code Review反馈修改代码1. 更新文档说明2. docs: 更新API文档3. 根据UI设计稿更新组件样式4. chore: 更新了package依赖5. 新增数据导出功能1. 更新文档说明2. docs: 更新API文档3. 新增数据导出功能4. chore: 更新了package依赖5. 根据UI设计稿更新组件样式1. 更新文档说明2. docs: 更新API文档3. 删除了废弃的API调用4. 优化用户登录流程5. 重构了代码结构,提高了可维护性1. 更新文档说明2. docs: 更新API文档3. 新增数据导出功能4. 根据UI设计稿更新组件样式5. 优化用户登录流程
优化性能1. 修改了配置文件中的默认设置2. 修复了多线程并发导致的数据不一致问题3. 添加GraphQL查询缓存机制4. 更新了Webpack配置,提高构建速度5. perf: 优化了数据库查询性能1. perf: 优化了数据库查询性能2. 优化React组件的渲染性能3. 优化用户登录流程4. 修复首页加载速度慢的问题5. 优化了MongoDB聚合查询的执行效率1. 优化用户登录流程2. perf: 优化了数据库查询性能3. 优化React组件的渲染性能4. 修复首页加载速度慢的问题5. 重构了代码结构,提高了可维护性1. 修复首页加载速度慢的问题2. 优化用户登录流程3. perf: 优化了数据库查询性能4. 修复了用户反馈的崩溃问题5. 删除了废弃的API调用1. perf: 优化了数据库查询性能2. 优化用户登录流程3. 优化React组件的渲染性能4. 更新了Webpack配置,提高构建速度5. 优化了MongoDB聚合查询的执行效率

我们再请Gemini-2.5-pro来分析一下: google-embedding-results

综合评判:

基于以上对所有查询的分析,各个模型的召回正确率表现如下:

  1. Baichuan: 表现最为出色和稳定。在大多数查询中,尤其是涉及具体技术(React、数据库、UI)和开发流程(重构、Code Review后修改、解决冲突)的查询,其召回结果的相关性最高,Top 5结果中强相关或相关的内容最多。它对中英文混合、专业术语的理解似乎最为到位。
  2. Baidu: 整体表现也非常好,紧随Baichuan之后。在API开发、UI调整、修复Bug等查询上表现突出。但在个别查询上(如数据库优化)表现有失水准,可能在某些语义理解上存在偏差或过度依赖关键词。
  3. Qwen: 表现中等偏上。在一些查询上表现不错,但在需要更深层次语义理解或区分具体技术领域时,召回结果的相关性有时会下降,会混入一些弱相关或泛化的结果。
  4. Hunyuan: 表现中规中矩。在简单、明确的查询(如修复bug)上表现尚可,但在更复杂或技术性更强的查询中,召回的相关性往往不如Baichuan和Baidu。
  5. Doubao: 表现最差。在多个查询中(如添加新功能、更新文档、优化性能、React组件),其召回结果中包含了大量不相关的内容,显示其在理解查询意图和commit message语义方面存在明显不足。

最终结论: Baichuan 模型在召回上正确率最高,最适合这类任务。

判断依据与示例:

  • Baichuan 的优势 (示例):

    • 对技术术语和领域的精准理解: 在查询 “数据库优化” 时,Baichuan 召回了所有5个直接相关的 commit(perf: 优化了数据库查询性能, 优化了MongoDB聚合查询..., 添加GraphQL查询缓存机制, 新增Elasticsearch索引管理功能, 修复Redis连接池泄露问题),覆盖了性能优化、缓存、索引、连接池等多个数据库相关方面。这显示了它对数据库领域术语和优化手段的深刻理解。
    • 对UI/组件相关内容的准确把握: 在查询 “关于React组件的提交” 和 “UI界面调整” 时,Baichuan 都能准确召回 优化React组件..., style: 调整了UI组件..., 根据UI设计稿..., fix(ui): modal... 等高度相关的 commit,表现优于其他多数模型。
    • 稳定性: 在大部分查询中都保持了较高的召回质量,很少出现召回大量完全不相关结果的情况。
  • 不太合适的模型 (Doubao) 的劣势 (示例):

    • 语义理解能力差,易召回不相关结果: 在查询 “添加新功能” 时,Doubao 的 Top 5 结果仅有 1 个强相关 (添加了新功能的feature flag),其余 4 个是 更新文档说明, 优化用户登录流程, 删除了废弃的API调用, 重构了代码结构...,这些都与“添加新功能”的意图相去甚远。
    • 过度泛化或关键词匹配: 在查询 “优化性能” 时,Doubao 召回了 修复首页加载速度慢的问题, 优化用户登录流程, perf: 优化了数据库查询性能 这三个相关的,但也召回了 修复了用户反馈的崩溃问题删除了废弃的API调用,后者与性能优化关联不大,可能是因为看到了“修复”、“优化”等词就简单匹配了。
    • 一致性差: 在多个查询中都表现出召回不相关结果的问题,表明其在理解 commit message 这类特定文本的语义方面存在普遍困难。

因此,基于对所有查询结果的综合分析,Baichuan 模型在本次评测中展现了最高的召回正确率和最好的语义理解能力,是完成该任务的最佳选择。兼听则明?这个结果同时也让Deepseek-R1来分析了一下,都认证了Doubao在这轮里面垫底的事实(也可能注这个场景人家不行?),但第一名一个是Baichuan,一个是Baidu。

国外的embedding模型原本打算把除OpenAI外,Google家和Anthropic家请来的,无奈后两家模型要么主打模型不支持中文,要么我没API KEY(这是我的问题),都纷纷表示上不了场,于是咱就把OpenAI自家三姐妹一起端上来品评下。以下是它们的结果(限于篇幅只截取一部分,完整内容查看代码仓库):

查询语句text-embedding-3-smalltext-embedding-3-largetext-embedding-ada-002
如何修复bug1. 修复了登录页面的bug2. 修复了用户反馈的崩溃问题3. 根据Code Review反馈修改代码4. 修复QA团队报告的regression问题5. 修复首页加载速度慢的问题1. 修复了登录页面的bug2. 修复了用户反馈的崩溃问题3. 修复QA团队报告的regression问题4. 修复了多线程并发导致的数据不一致问题5. 修复Redis连接池泄露问题1. 修复了用户反馈的崩溃问题2. 修复QA团队报告的regression问题3. 修复了登录页面的bug4. 修复了多线程并发导致的数据不一致问题5. 修复首页加载速度慢的问题
添加新功能1. 添加了新功能的feature flag2. feat: 添加了新的payment接口3. 合并develop分支的最新更改4. 新增数据导出功能5. 重构了代码结构,提高了可维护性1. 添加了新功能的feature flag2. 新增数据导出功能3. feat: 添加了新的payment接口4. 新增Elasticsearch索引管理功能5. 添加单元测试用例1. 添加了新功能的feature flag2. 新增数据导出功能3. 新增Elasticsearch索引管理功能4. 添加单元测试用例5. feat: 添加了新的payment接口
更新文档1. 更新文档说明2. docs: 更新API文档3. 合并develop分支的最新更改4. chore: 更新了package依赖5. 根据UI设计稿更新组件样式1. 更新文档说明2. docs: 更新API文档3. 新增数据导出功能4. chore: 更新了package依赖5. 准备v2.0.0版本发布1. 更新文档说明2. docs: 更新API文档3. 修改了配置文件中的默认设置4. chore: 更新了package依赖5. 准备v2.0.0版本发布
优化性能1. perf: 优化了数据库查询性能2. 优化React组件的渲染性能3. 优化了MongoDB聚合查询的执行效率4. 重构了代码结构,提高了可维护性5. 优化用户登录流程1. perf: 优化了数据库查询性能2. 优化React组件的渲染性能3. 优化用户登录流程4. 优化了MongoDB聚合查询的执行效率5. 重构了代码结构,提高了可维护性1. 优化React组件的渲染性能2. perf: 优化了数据库查询性能3. 优化了MongoDB聚合查询的执行效率4. 优化用户登录流程5. 重构了代码结构,提高了可维护性

综合评判:

  1. text-embedding-3-large: 表现最佳。它在大多数查询中都提供了最高度相关的结果,尤其是在需要理解具体技术动作(如 API 开发、React 组件相关、重构)的查询上表现突出。虽然在某些查询的填充结果上仍有不足,但其核心召回的相关性和准确性是三者中最高的。它似乎对 commit message 中的术语和隐含意图有更强的捕捉能力。
  2. text-embedding-3-small: 表现良好,是强力的竞争者。在许多查询中,其表现非常接近 large,有时甚至在 UI 调整等个别查询上略优。考虑到它是 “small” 模型,其性能令人印象深刻。它主要的弱点是在某些查询中会比 large 混入更多不相关或弱相关的结果。
  3. text-embedding-ada-002: 表现相对最弱。虽然在一些直接的查询(如修复 bug、优化性能)上表现尚可,但在需要更细致区分和理解的查询中(如数据库优化、API 开发)明显落后于 largesmall,召回了更多不相关的结果。似乎更容易受到表面关键词的影响,而对深层语义的把握不如新一代的 text-embedding-3 系列。

腾讯元宝网页版给了如下总结:

评估维度text-embedding-3-largetext-embedding-ada-002text-embedding-3-small
技术召回率92%85%78%
语义边界准确率89%76%68%
混合文本处理94%83%72%
过程任务召回86%91%88%

多个AI一致投票给了: text-embedding-3-large 模型。它在召回上正确率最高、最适合这类任务。

这其实和我预想的有点出入,本以为small便宜点可能只是维度小一些(1536 vs 3072),对这种场景没啥影响,但是却在多个召回上弱于large模型,或许维度高确实有用吧?不过这个场景原来旧的ada模型明显落后了,那些用旧模型的小伙伴要不要考虑升级一下呢?

那我们最后国内国外一起看一下当前的推荐(来源于Gemini2.5 pro): 推荐层级:

第一梯队:强烈推荐 (Overall Best Performance)

  1. text-embedding-3-large:
    • 理由: 在所有模型中展现出最强的综合实力。它不仅在多数查询中提供了高度相关的结果,并且在理解特定技术动作(如 API 开发细节、具体 UI 修复 fix(ui))和细微语义差别方面表现最佳。其召回结果的相关性排序和准确性通常最高,混入的不相关结果最少。是追求最佳召回效果的首选。
    • 示例优势: API 开发查询中召回最全面;React 组件查询中能捕捉到 fix(ui) 细节。

第二梯队:优秀选择 (Strong Contenders)

  1. Baichuan:

    • 理由: 在第一批模型中表现最佳,整体实力非常接近 text-embedding-3-large。尤其在理解数据库优化、UI/组件相关术语方面表现突出,显示出可能针对中文技术领域有良好的优化。对于侧重这些领域的场景,它可能是与 large 并驾齐驱的选择。
    • 示例优势: 数据库优化查询中召回最全;UI/组件查询中表现优异。
  2. text-embedding-3-small:

    • 理由: 作为 large 的小型版本,其性能表现惊人地好,远超 ada-002 和第一批的大部分模型。在多数查询中紧随 largeBaichuan,召回相关性高。考虑到其可能更优的成本效益和更快的速度,如果对极致性能要求稍低,或者成本是重要因素,small 是一个极具吸引力的选择。
    • 示例优势: 整体表现稳定,与 large 高度相似,性价比可能更高。

第三梯队:可以考虑 (Good / Acceptable)

  1. Baidu:
    • 理由: 在第一批模型中表现第二好,整体召回能力不错,特别是在 API 开发、修复 Bug 等查询上表现良好。但其缺点在于稳定性稍逊于 Baichuan,并且在个别查询(如数据库优化)上表现不佳,可能在某些语义理解上存在短板或过度依赖关键词。
    • 示例优势: API 开发、修复 Bug 召回较好。 劣势: 数据库优化查询表现差。

第四梯队:谨慎使用 (Fair / Use with Caution)

  1. Qwen:
    • 理由: 表现中等,能处理一些查询,但在需要更精细区分或深入理解语义时,准确性不如前三梯队,更容易召回弱相关或泛化的结果。
  2. text-embedding-ada-002:
    • 理由: 作为上一代 OpenAI 模型,其表现已被 text-embedding-3 系列显著超越。虽然在简单查询上还行,但在复杂或需要区分技术领域的查询(如数据库优化、API 开发)中表现较差,召回结果混杂。除非有特定原因(如兼容性),否则不建议优先选择。

第五梯队:不推荐 (Not Recommended)

  1. Hunyuan:
    • 理由: 整体表现平平,仅在最直接的查询中效果尚可,处理复杂或专业性查询时召回准确率较低。
  2. Doubao:
    • 理由: 在本次评测中表现最差,多次在查询中返回大量完全不相关的结果,显示其在理解 commit message 语义方面存在明显困难。

总结建议:

  • 追求最佳效果: 优先选择 text-embedding-3-large
  • 效果与成本平衡: text-embedding-3-small 是极佳的选择,性能接近顶尖且可能更经济。
  • 特定领域优势: 如果你的应用场景高度集中在数据库、基础设施或特定中文 UI 组件方面,Baichuan 也值得重点考虑和测试,它在这些方面展现了特长。
  • 备选方案: 如果前三者不可用,Baidu 是一个可以考虑的选项,但需注意其潜在的稳定性问题。
  • 避免使用: 尽量避免使用 HunyuanDoubao 用于此类需要较高语义理解准确性的任务。text-embedding-ada-002 也应被视为过时选项。

这个场景对于Hunyuan和Doubao我也很抱歉,不是你不好,可能是我们不适合:P

后记

因为测试数据较多,文章显得较长,对于如何找到适合的embedding模型这个问题,虽然可以看到一些模型的成色如何,但也可能有所偏颇,建议你根据自己的具体应用场景和数据上进行测试验证。你也看到我这个测试是针对这种特殊场景的,而你可能要考虑很多因素:

  • 模型的维度,不同的维度在语义上能表达的也不一样。听说也不是越高维越好,反而要看你的数据涉及的面。
  • 模型支持的语言,有不少模型不支持你所希望使用的语言,那自然直接淘汰。
  • 数据的安全性,基于这个考量,我们或许要借助开源模型自建服务。

虽然Google今天没有参赛,江湖传闻它也有特别的能力,在Embedding时指定任务类别,可能可以更精准使用,详见: Google Embedding Task Types

最终我会选择哪一个呢?你猜。

我是个爱折腾技术的工程师,也乐于分享。欢迎点赞、关注、分享,更欢迎一起探讨技术问题,共同学习,共同进步。为了获得更及时的文章推送,欢迎关注我的公众号:

扫码关注公众号