Embedding 模型选型与对比:bge、e5 与 OpenAI 嵌入

文本 Embedding 是把句子、段落甚至整篇文档压缩成一串固定长度浮点向量的技术。向量越接近,语义越相似。它是一切语义检索、聚类、分类与去重系统的底座。本文以「选型」为主线,对比 OpenAI、bge、e5 等主流模型的真实差异,并给出可直接运行的 Python 示例。

Embedding 是什么

给定一个文本 t,Embedding 模型输出一个向量 v ∈ R^d。下游任务通过向量间的距离(常用余弦相似度或内积)衡量文本关系:

  • 检索增强生成(RAG):把知识库切片向量化,按查询向量召回最相关片段。
  • 聚类:把成千上万条用户反馈按语义归堆。
  • 分类与去重:用向量做近邻判断,替代关键词规则。

需要强调的是,不同模型产出的向量空间彼此不兼容。用 bge 生成的向量,不能用 OpenAI 的向量去做相似度比对,必须保证索引与查询使用同一模型。

衡量指标:MTEB

选择模型不能只看厂商宣传,要看统一基准。MTEB(Massive Text Embedding Benchmark)是当前最广泛采用的评测体系,覆盖检索、聚类、分类、重排、句对打分等多类任务,用单一综合分数(平均值)横向比较模型。

该榜单由 Hugging Face 团队维护,在线地址为 https://huggingface.co/spaces/mteb/leaderboard。阅读榜单时需要注意三点:

  1. 综合分数高不代表每项都强,要看你关心的子任务(例如中文检索应参考 C-MTEB)。
  2. 榜单随时间变化,本文引用的是模型家族层面的稳定结论,具体排名以页面实时数据为准。
  3. 模型参数量、维度、是否支持多语言,往往比综合分数更影响你的工程取舍。

主流模型对比

下面列出工程中最常遇到的几类文本 Embedding 模型。维度与定位为各模型家族的公开信息,精确分数请以上述 MTEB 榜单为准。

OpenAI 文本嵌入

OpenAI 第三代嵌入模型通过 API 调用,无需本地算力:

  • text-embedding-3-small:默认 1536 维,性价比高,是大多数英文 RAG 的起步选择。
  • text-embedding-3-large:默认 3072 维,综合质量更高,适合对召回精度敏感的场景。

两者均支持通过 dimensions 参数缩短向量(例如降到 1024 或 256),在损失极小精度的前提下节省向量库成本。

BAAI bge 系列

bge(BAAI General Embedding)由智源研究院(BAAI)发布,对应论文为 C-Pack(arXiv:2309.07597)。其代表模型包括:

  • bge-large-en-v1.5:英文强模型,开源可本地部署。
  • bge-large-zh-v1.5:中文场景表现优秀。
  • bge-m3:支持稠密、稀疏、多向量三种检索范式,并覆盖 100 多种语言,是多语言与混合检索的热门选择。

bge 系列通常需要对查询文本加上前缀 Represent this sentence for searching relevant passages: 以获得最佳检索效果,这是使用时容易忽略的细节。

intfloat e5 系列

e5 由微软团队提出,对应论文为 Text Embeddings by Weakly-Supervised Contrastive Pre-training(arXiv:2212.03533)。特点是用弱监督对比学习从大规模文本对训练,零样本迁移能力突出。代表模型:

  • multilingual-e5-large:多语言覆盖广,是跨语言检索的常用开源方案。
  • e5-large-v2:英文任务表现稳定。

e5 同样有输入格式约定:查询需加 query: 前缀,文档需加 passage: 前缀,否则效果会明显下降。

其他常见选择

  • Cohere Embed:通过 API 提供 embed-englishembed-multilingual 系列,企业级稳定性好,支持按需调整维度。
  • Jina Embeddings:提供 jina-embeddings-v2-base 等支持 8192 token 长上下文的开源与 API 模型,适合长文档场景。

维度与归一化

向量维度直接决定存储与计算成本。维度越高,通常表达力越强,但向量库的内存占用与检索延迟也线性上升。实践经验:

  • 768 维左右的开源模型(如 bge-base、e5-base)已能满足多数中文业务检索。
  • 1536 维(text-embedding-3-small)是英文 RAG 的甜点区间。
  • 3072 维(text-embedding-3-large)仅在精度敏感且预算充足时使用,或配合 dimensions 缩短。

归一化方面,多数现代模型(bge、e5、OpenAI 第三代)默认输出已归一化或接近单位向量,此时余弦相似度与内积等价,向量库可用内积换取更快检索。sentence-transformers 默认会对输出做 L2 归一化;使用 OpenAI SDK 时建议自行归一化后再入库,避免不同批次结果尺度不一致。

本地开源 vs 云 API 取舍

维度本地开源(bge / e5)云 API(OpenAI / Cohere)
数据合规数据不出内网,适合敏感业务文本需发往第三方
成本结构一次性显卡投入,调用零边际成本按 token 计费,规模越大越贵
运维负担需部署与维护推理服务免运维,随调随用
多语言bge-m3、e5 多语言覆盖好OpenAI 第三代多语言强
迭代速度自行升级模型厂商持续更新,自动生效

简言之:数据敏感、调用量大、已有 GPU,优先本地开源;快速验证、跨语言、不想运维,优先云 API。

选型决策清单

按以下顺序逐项确认,可快速收敛到合适模型:

  1. 数据是否允许出内网?不允许则排除云 API。
  2. 主力语言是中文、英文还是多语言?中文看重 bge-zh,多语言看重 bge-m3 或 multilingual-e5。
  3. 是否有 GPU 与运维人力?都没有则选 OpenAI / Cohere API。
  4. 向量库对维度有无上限?有则优先支持 dimensions 缩短的模型。
  5. 检索还是聚类为主?检索看重 MTEB 检索子项,聚类看重聚类子项。
  6. 预算上限多少?先用小维模型跑通,再决定是否升级 large 版本。

Python 调用示例

下面给出两个可直接运行的片段。运行前请安装依赖:pip install sentence-transformers openai

本地开源模型(sentence-transformers)

from sentence_transformers import SentenceTransformer
import numpy as np

# 使用 bge 英文模型,中文可换 bge-large-zh-v1.5
model = SentenceTransformer("BAAI/bge-large-en-v1.5")

query = "Represent this sentence for searching relevant passages: How to fine-tune a language model?"
docs = [
    "Fine-tuning adapts a pretrained model to a specific task with labeled data.",
    "The weather today is sunny and warm.",
]

query_vec = model.encode(query, normalize_embeddings=True)
doc_vecs = model.encode(docs, normalize_embeddings=True)

# 归一化后内积即余弦相似度
scores = doc_vecs @ query_vec
ranked = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
for text, score in ranked:
    print(f"{score:.4f}  {text}")

云 API 模型(OpenAI SDK)

from openai import OpenAI
import numpy as np

client = OpenAI()

def embed(texts, model="text-embedding-3-small", dim=1024):
    resp = client.embeddings.create(
        model=model,
        input=texts,
        dimensions=dim,  # 缩短维度以节省向量库成本
    )
    return np.array([d.embedding for d in resp.data], dtype=np.float32)

query_vec = embed(["How to fine-tune a language model?"])
doc_vecs = embed([
    "Fine-tuning adapts a pretrained model to a specific task.",
    "The weather today is sunny and warm.",
])

scores = doc_vecs @ query_vec.T
print(scores)

注意:同一应用内索引与查询必须使用同一模型与同一维度,否则向量空间不可比。

小结

文本 Embedding 是语义检索、聚类与分类的基础能力。选型时,先用 MTEB 看综合与子任务表现,再结合数据合规性、语言覆盖、维度成本与运维能力做决策。中文与多语言场景可优先 bge 系列与 e5 多语言版,英文快速验证可选 OpenAI text-embedding-3 系列。无论选哪种,务必保证索引与查询同模型、同维度,并对输出向量做归一化以统一相似度尺度。

参考与延伸阅读

  1. MTEB 在线排行榜,Hugging Face Spaces,https://huggingface.co/spaces/mteb/leaderboard
  2. BAAI bge 论文:Shitao Xiao 等,C-Pack: Packed Resources For General Chinese Embeddings,arXiv:2309.07597
  3. 微软 e5 论文:Liang Wang 等,Text Embeddings by Weakly-Supervised Contrastive Pre-training,arXiv:2212.03533
  4. OpenAI 官方 Embeddings 文档,text-embedding-3-small 与 text-embedding-3-large,https://platform.openai.com/docs/guides/embeddings
  5. BAAI FlagEmbedding 项目仓库,https://github.com/FlagOpen/FlagEmbedding
本文累计阅读