候选模型先看硬指标

选 embedding 别只看排行榜总分,维度决定存储和内存、最大 token 决定要不要切长文档、训练和评测语料决定中文表现。下面是自建知识库里最常拿来比的几个,按 2026 年能直接下载到的版本列。

模型维度最大 token中文部署
BAAI/bge-m310248192强,兼多语本地 / API
bge-large-zh-v1.51024512短句强本地
m3e-base768512中本地
jina-embeddings-v310248192好本地 / API
阿里 text-embedding-v31024 或 20488192好仅 API
text-embedding-3-small15368191中仅 API

评测别只信 MTEB 总分,中文要看 C-MTEB 里 retrieval 的 nDCG@10 和 STS 的 Spearman 相关。更靠谱的是从自己业务日志里抽 20 到 50 条真实 query,人工标出应该命中的文档,算 recall@5,这个数和线上体感最贴合。

本地跑起来只要几行

Ollama 现在把 embedding 也纳入同一套服务,pull 之后走 /api/embed,省掉自己装 torch 的麻烦;需要精细控制或批量离线处理就用 sentence-transformers / FlagEmbedding。

ollama pull bge-m3
curl http://localhost:11434/api/embed -d '{
  "model": "bge-m3",
  "input": ["Ollama 的 num_ctx 设置", "向量检索的分块策略"]
}'
from sentence_transformers import SentenceTransformer
m = SentenceTransformer("BAAI/bge-large-zh-v1.5")
# 归一化后点积即余弦,存库前一定要做
v = m.encode(["上下文窗口与长文档处理"], normalize_embeddings=True)
print(v.shape)

取舍判断

  • 中文为主、含长文档、中英混排:bge-m3。8192 token 能吃下整节文档,还同时输出稀疏向量,可以和关键词检索混排,长文档召回明显稳。
  • 纯中文短句、显存小:bge-large-zh-v1.5 或 m3e-base,512 token 限制下先切块再编码,速度更快。
  • 不想运维、能接受计费与数据合规评估:阿里 text-embedding-v3,维度可选,按 token 计费。
  • 已有 OpenAI 链路:text-embedding-3-small 够用,中文略逊但省事。

这里有个几乎人人踩过的细节:bge-large-zh 和 bge-base 系列做非对称检索时,query 侧要加指令前缀"为这个句子生成表示以用于检索相关文章:",文档侧不加;bge-m3 不需要。忘记加前缀,相似度会整体偏低 0.1 到 0.2,表现成"明明相关却排不上去",很难查。对称任务(算两句相似度)则两边都不加。

QUERY_PREFIX = "为这个句子生成表示以用于检索相关文章:"
q_vec = m.encode([QUERY_PREFIX + query], normalize_embeddings=True)
d_vec = m.encode(documents, normalize_embeddings=True)
sims = d_vec @ q_vec[0]

最后一个硬约束:换 embedding 模型等于换了一套坐标系,必须全量重建索引。新旧向量混在一个库里,相似度数值没有可比性,阈值和排序全乱。把"模型名 + 维度 + 分块参数"写进 collection 名或元数据,是后面能做灰度迁移的前提。