Embedding 模型选择与领域适配
Embedding 模型决定了向量的质量,直接影响检索准不准。中文场景选什么模型好?垂直领域(法律、医疗、技术)通用模型效果差怎么办?这篇讲主流 Embedding 模型对比、选型方法、以及领域适配的技巧。
大家好,我是黒漂技术佬。
RAG 检索准不准,Embedding 模型是核心因素之一。同样的文本,不同模型转出来的向量,检索效果差很多。
尤其是中文场景,直接用英文模型效果一般;垂直领域(法律、医疗、技术文档),通用模型又不够专业。
这篇讲主流 Embedding 模型怎么选、中文场景哪些好用、垂直领域怎么优化。
一、Embedding 是什么?
直观理解
把一段文本变成一串数字(向量),语义相近的文本,向量距离就近。
"怎么退货" → [0.12, -0.34, 0.56, ...]
"退换货流程" → [0.15, -0.31, 0.52, ...] ← 距离近,语义像
"产品价格" → [-0.22, 0.45, -0.18, ...] ← 距离远,语义不同
衡量标准
- 语义相似度:意思一样的文本,向量距离近
- 多语言支持:中英文都能用
- 向量维度:维度越高信息越多,但越慢
- 推理速度:生成向量的快慢,影响建库和检索速度
二、主流 Embedding 模型对比
闭源 API 类
| 模型 | 厂商 | 维度 | 中文效果 | 特点 |
|---|---|---|---|---|
| text-embedding-3-small | OpenAI | 1536 | 一般 | 便宜,通用 |
| text-embedding-3-large | OpenAI | 3072 | 较好 | 贵,效果好 |
| 通义千问 embedding | 阿里 | 1536 | 好 | 中文优化,便宜 |
| 文心一言 embedding | 百度 | 1024 | 较好 | 中文场景 |
| 智谱 embedding | 智谱AI | 1024 | 较好 | 中文支持 |
开源模型(中文友好)
| 模型 | 维度 | 中文效果 | 速度 | 特点 |
|---|---|---|---|---|
| bge-large-zh-v1.5 | 1024 | 很好 | 中 | 中文标杆,BAAI出品 |
| bge-base-zh-v1.5 | 768 | 好 | 快 | 平衡之选,推荐 |
| bge-small-zh-v1.5 | 512 | 较好 | 很快 | 轻量,速度优先 |
| m3e-large | 1024 | 很好 | 中 | 多任务训练,中文强 |
| m3e-base | 768 | 好 | 快 | 平衡 |
| text2vec-large-chinese | 1024 | 较好 | 中 | 老牌中文模型 |
| gte-large-zh | 1024 | 很好 | 中 | 阿里通义实验室开源 |
多语言模型
| 模型 | 维度 | 多语言 | 特点 |
|---|---|---|---|
| bge-m3 | 1024 | 100+语言 | 多语言强,支持长文本 |
| multilingual-e5-large | 1024 | 多语言 | 微软出品 |
| all-MiniLM-L6-v2 | 384 | 英文为主 | 极快,英文场景 |
怎么选?
中文为主,效果优先
- bge-large-zh-v1.5 或 m3e-large
- 中文 MTEB 榜单前列,效果好
中文为主,平衡速度和效果
- bge-base-zh-v1.5(768 维)
- 我最常用的,大部分场景够用,速度也不错
速度优先、数据量大
- bge-small-zh-v1.5(512 维)
- 速度快,省内存,百万级数据友好
中英混合
- bge-m3
- 多语言效果都不错
不想自己部署
- 通义千问 embedding API
- 中文好,价格便宜,调用方便
💡 我的经验:企业中文知识库,bge-base-zh-v1.5 是甜点,效果和速度平衡得很好。要求高就上 large,数据量大就用 small。
三、Embedding 模型的关键参数
1. 向量维度
- 384/512 维:轻量,速度快,适合大数据量
- 768 维:平衡,最常用
- 1024/1536 维:高精度,效果好但慢
维度不是越高越好,768 和 1024 在很多场景差距不大,但速度差不少。
2. 最大输入长度
每个模型有最大 token 限制:
- 一般 512 tokens(约 300-400 汉字)
- 长文本模型:1024、2048、8192
分块大小不能超过模型的最大长度,不然截断了效果差。
3. 指令(Instruction)
bge 系列支持加指令,查询时加一句提示,效果更好:
为这个句子生成表示以用于检索相关文章:用户的问题
检索时给 query 加 instruction,文档不用加。
4. 归一化
向量归一化后,余弦相似度和点积等价,点积计算更快。
一般使用时建议归一化。
四、垂直领域效果差怎么办?
通用模型在专业领域(法律、医疗、金融、技术)效果往往一般,因为训练数据里专业内容少。
优化方法
方法 1:领域微调(Fine-tuning)
拿领域内的文本对(相似/不相似)继续训练 Embedding 模型。
需要的数据:
- 正样本对:语义相似的句子对
- 负样本对:语义不同的句子对
效果:领域内检索效果提升明显,涨 5-15 个点很正常。
成本:需要标注数据,训练成本中等。
方法 2:领域预训练
用领域内的大量无标注文本继续预训练。效果更好,但成本高,数据量要求大。
一般项目不建议做,投入太大。
方法 3:微调不行就换模型
有些模型天生在某些领域表现好。比如:
- 法律场景:试试法律领域训练的 embedding
- 医疗场景:试试医疗领域模型
方法 4:后处理补救
检索效果不够,后面加重排序(Rerank)来补。下一篇会讲。
什么时候需要微调?
- 通用模型的召回率达不到要求
- 有足够的领域数据(几千对以上)
- 对检索精度要求高
如果通用模型 + 混合检索 + 重排序已经够用,就不用折腾微调。
五、微调 Embedding 的方法
数据准备
1. 监督数据(有标注)
相似句对:
(句子A, 句子B, 1) ← 相似
(句子A, 句子C, 0) ← 不相似
2. 弱监督数据(自动构造)
没有标注的话,从文档里自动构造:
- 同一段落的句子 → 正样本
- 不同文档的句子 → 负样本(困难负样本更好)
训练框架
推荐 sentence-transformers,微调很方便:
python
from sentence_transformers import SentenceTransformer, losses, InputExample
from torch.utils.data import DataLoader
model = SentenceTransformer('bge-base-zh-v1.5')
# 构造训练数据
train_examples = [
InputExample(texts=["怎么退货", "退换货流程"], label=1.0),
InputExample(texts=["怎么退货", "产品价格"], label=0.0),
# ... 更多样本
]
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=32)
train_loss = losses.CosineSimilarityLoss(model)
# 微调
model.fit(
train_objectives=[(train_dataloader, train_loss)],
epochs=3,
warmup_steps=100,
output_path='./finetuned_model'
)
困难负样本挖掘
普通负样本太简单,模型学不到东西。困难负样本(看起来像但实际不同)训练效果更好。
做法:
- 先用通用模型检索
- Top 10 里不是正确答案的,作为困难负样本
- 加入训练数据再微调
一轮一轮迭代,效果逐步提升。
六、模型效果怎么评估?
不能凭感觉选模型,要量化评估。
评估指标
Recall@K
Top K 检索结果里,有多少比例包含了正确答案。
Recall@5 = 相关文档出现在前5个的次数 / 总查询数
RAG 里最重要的指标,因为检索到了大模型才能答对。
MRR(平均倒数排名)
正确答案排在第几位。排第一得分最高,越靠后得分越低。
更看重排序质量的时候用。
NDCG
考虑排序位置的综合指标。
评估数据集
自己构造一个测试集:
- 100-1000 个问题
- 每个问题标注对应的正确文档
- 覆盖各种场景和类别
评估流程
- 准备测试集(问题 + 正确文档 ID)
- 每个问题生成 query 向量
- 检索 Top K
- 计算 Recall@K、MRR
- 对比不同模型的结果
不要只看榜单
MTEB 榜单上的分数是通用基准,不一定在你的领域表现好。一定要在自己的数据集上测。
七、部署与性能优化
部署方式
API 服务
- 用 sentence-transformers + FastAPI 封装
- 或者用 vLLM、Text Embeddings Inference 等推理框架
- 适合生产环境,支持并发
本地库调用
- 直接 import sentence-transformers
- 适合离线建索引、小数据量
性能优化
1. 批量处理
建索引的时候批量 embedding,比一条条快很多。
python
embeddings = model.encode(texts, batch_size=64, show_progress_bar=True)
2. GPU 加速
有 GPU 的话速度快 10-100 倍。数据量大建议上 GPU 建库。
3. 量化
模型量化(INT8),速度更快,内存更少,精度损失小。
4. 缓存
相同文本的 embedding 缓存起来,不用重复算。
速度参考(大概)
| 模型 | CPU 速度 | GPU 速度 |
|---|---|---|
| bge-small | ~500 条/秒 | ~10000 条/秒 |
| bge-base | ~200 条/秒 | ~5000 条/秒 |
| bge-large | ~80 条/秒 | ~2000 条/秒 |
十万条数据,GPU 建库几分钟,CPU 可能要几十分钟。
八、实际案例
企业技术知识库
场景:中文技术文档、产品手册、FAQ,约 30 万条
选型过程:
- 先试了 OpenAI text-embedding-ada-002,中文效果一般,还贵
- 试了 bge-base-zh-v1.5,中文效果明显更好
- 又试了 m3e-base,和 bge 差不多,选了 bge(生态更好)
- 用技术领域数据微调了一版,召回率再涨 6%
最终:bge-base-zh-v1.5 + 领域微调
- Recall@5:从 82% → 88%(微调后)
- 速度:GPU 建库半小时,查询毫秒级
选型建议
- 先上 bge-base-zh-v1.5,中文通用场景的基线
- 测一下你的数据上 Recall@K 够不够
- 不够的话:先换 large 试试 → 再加重排序 → 最后考虑微调
- 微调成本高,但提升也明显,精度要求高值得做
九、常见误区
误区 1:维度越高越好
1536 维不一定比 768 维好多少,但速度慢一倍,存储多一倍。先试 768,不够再升。
误区 2:只看 MTEB 榜单
通用榜单高分不代表你的领域高分。一定要在自己的测试集上评估。
误区 3:上来就微调
微调是大招,成本高。先把分块、检索策略、重排序这些优化了,还不够再微调。
误区 4:query 和文档用不同模型
query embedding 和 doc embedding 必须用同一个模型,不然向量空间不一样,距离没意义。
误区 5:长文本直接 embedding
超过模型最大长度的文本会被截断,后面的信息丢了。分块要控制在最大长度内。
十、本篇小结
- Embedding 模型决定检索质量,是 RAG 的核心组件
- 中文场景首选 bge 系列,base 版本平衡速度和效果
- 垂直领域效果差可以微调,困难负样本效果好
- 评估用 Recall@K,自己的测试集上测,别只看榜单
- 优化顺序:选对模型 → 优化分块 → 混合检索 → 重排序 → 微调
- 部署注意批量处理、GPU 加速、缓存,提升建库速度
下一篇讲检索策略优化:混合检索、重排序、查询改写,进一步提升召回率。
我是黒漂技术佬。