Skip to content

嵌入模型对比 — 从 Word2Vec 到现代 Embedding ​

#嵌入模型 · #Embedding · #bge · #m3e · #向量检索 · #语义搜索

嵌入模型是 RAG 和语义搜索的基石。选错嵌入模型,再好的检索架构也白搭。本文对比主流通用嵌入模型和中文嵌入模型的性能、维度和适用场景。


嵌入模型的核心作用 ​

mermaid
graph LR
    subgraph "嵌入模型的角色"
        DOC1["文档: Go 的 GMP 调度模型..."] --> ENC["嵌入模型<br/>Encoder"]
        DOC2["文档: Python async/await..."] --> ENC
        QUERY["查询: goroutine 如何调度?"] --> ENC

        ENC --> V1["向量₁<br/>[0.12, -0.45, 0.78, ...]"]
        ENC --> V2["向量₂<br/>[0.89, 0.32, -0.11, ...]"]
        ENC --> V3["向量₃<br/>[0.15, -0.42, 0.75, ...]"]

        V3 --> SIM["余弦相似度<br/>sim(V3, V1) = 0.92 ✅<br/>sim(V3, V2) = 0.18 ❌"]
        V1 --> SIM
        V2 --> SIM
    end

    style ENC fill:#e74c3c,color:#fff

嵌入模型的核心任务:把变长的自然语言文本映射到固定维度的稠密向量,使语义相似的文本在向量空间中距离更近。


嵌入模型的关键指标 ​

指标含义影响
维度输出向量的长度维度越高表达能力越强,但存储和检索成本越大
最大长度能处理的最大 Token 数决定能否一次编码长文档
MTEB 得分Massive Text Embedding Benchmark 综合分通用嵌入质量的权威指标
C-MTEB 得分中文版 MTEB中文嵌入质量指标
推理速度tokens/s 或 sentences/s大批量索引时的吞吐
模型大小参数量和磁盘占用影响部署成本和启动速度

国际主流嵌入模型 ​

模型对比总览 ​

模型维度最大长度MTEB 均分模型大小推理速度特点
text-embedding-3-large3072/256/1024819164.6闭源⭐⭐⭐⭐⭐OpenAI 旗舰,支持维度缩减
text-embedding-3-small1536/512819162.3闭源⭐⭐⭐⭐⭐性价比最高
voyage-3-large10243200066.8闭源⭐⭐⭐⭐超长上下文
voyage-3-lite5123200063.0闭源⭐⭐⭐⭐⭐轻量高速
bge-large-en-v1.5102451264.21.3 GB⭐⭐⭐开源标杆
bge-m31024819264.42.2 GB⭐⭐⭐多语言 + 稠密+稀疏混合
gte-Qwen2-7B-instruct35843276869.514 GB⭐⭐最强开源(需 GPU)
e5-mistral-7b-instruct40963276866.614 GB⭐⭐Mistral 基座

各模型详细分析 ​

text-embedding-3 (OpenAI) ​

python
from openai import OpenAI

client = OpenAI()

# 亮点: 支持动态维度缩减,不损失太多质量
response = client.embeddings.create(
    model="text-embedding-3-large",
    input="Go 语言的 goroutine 是一种轻量级线程",
    dimensions=256,  # 从 3072 压缩到 256,存储省 12 倍
)

vector = response.data[0].embedding
print(f"向量维度: {len(vector)}")  # 256
维度MTEB 得分存储 (1M 条)
3072 (原始)64.6~12 GB
102464.1~4 GB
25662.0~1 GB

voyage-3 (Anthropic) ​

突出优势是超长上下文(32K tokens),适合直接编码整个文档而无需切分:

python
import voyageai

vo = voyageai.Client()

# 获取嵌入
result = vo.embed(
    texts=["Go 语言的 GMP 调度模型...(长文档)"],
    model="voyage-3-large",
    input_type="document",  # 文档模式: 全局摘要
)
# 查询时用 input_type="query" 获得更精准的匹配

中文嵌入模型 ​

模型对比 ​

模型维度最大长度C-MTEB 均分模型大小特点
bge-large-zh-v1.5102451264.51.3 GB中文开源首选
bge-m31024819266.22.2 GB多语言混合训练
m3e-large102451262.8430 MB轻量中文专用
m3e-base76851260.7210 MB最轻量中文
stella-large-zh-v3-1792d1792102467.21.3 GB中文最高分
gte-large-zh102451266.71.3 GB阿里通义系
text2vec-large-chinese102451259.31.3 GB老牌中文模型
Conan-embedding-v11792409663.51.3 GB专为检索优化

bge-m3 详解 ​

bge-m3 是目前最强的中文开源嵌入模型之一,支持三种检索模式:

python
from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel("BAAI/bge-m3", use_fp16=True)

sentences = [
    "Go 语言的 GMP 调度模型详解",
    "Python 的 asyncio 异步编程",
    "goroutine 和 channel 的使用",
]

# 1. 稠密向量(Dense)— 通用语义检索
dense_embeddings = model.encode(sentences)["dense_vecs"]
print(f"稠密向量维度: {dense_embeddings.shape}")  # (3, 1024)

# 2. 稀疏向量(Lexical)— 关键词匹配
lexical_weights = model.encode(sentences)["lexical_weights"]
# 输出: [{"GMP": 0.8, "调度": 0.6, ...}, ...]
# 结合稠密向量做混合检索,解决专有名词召回问题

# 3. 多向量(ColBERT)— token 级交互
colbert_vecs = model.encode(sentences)["colbert_vecs"]
# 每个 token 一个向量,实现精细匹配
# 存储成本高,但检索精度最高
检索模式精度存储成本检索速度适用
稠密 (Dense)高低 (1024 float32/条)快通用场景
稀疏 (Lexical)中极低 (词表大小)极快专有名词/代码
多向量 (ColBERT)最高极高 (n_tokens × 1024)慢精度优先
混合 (Dense+Sparse)最高低+极低中推荐生产方案

嵌入模型选型决策 ​

mermaid
graph TD
    START["选择嵌入模型"] --> Q1{"语言?"}
    Q1 -->|"纯中文"| Q2{"数据量?"}
    Q1 -->|"多语言混合"| A1["bge-m3<br/>or voyage-3"]
    Q1 -->|"纯英文"| A2["text-embedding-3-large"]

    Q2 -->|"< 10万条"| A3["m3e-base<br/>210MB 轻量"]
    Q2 -->|"10-100万条"| A4["bge-large-zh-v1.5<br/>or stella-large"]
    Q2 -->|"> 100万条"| Q3{"需要长上下文?"}

    Q3 -->|"是 (长文档)"| A5["bge-m3 (8192 tokens)<br/>or voyage-3 (32K)"]
    Q3 -->|"否"| A6["bge-large-zh-v1.5<br/>+ 混合检索"]

    style A1 fill:#2ecc71,color:#fff
    style A5 fill:#e74c3c,color:#fff
    style A3 fill:#3498db,color:#fff

嵌入模型的训练范式 ​

mermaid
graph LR
    subgraph "对比学习 (Contrastive)"
        Q1["查询: 什么是GMP?"] --> ENC1["Encoder"]
        D1["正样本: GMP调度详解"] --> ENC1
        D2["负样本: Python异步"] --> ENC1
        ENC1 --> LOSS1["拉近正样本<br/>推远负样本"]
    end

    subgraph "预训练 → 微调"
        PT["预训练<br/>BERT/GTE/Qwen"] --> FT1["无监督对比<br/>SimCSE"]
        FT1 --> FT2["有监督对比<br/>标注数据"]
        FT2 --> FT3["指令微调<br/>任务描述前缀"]
    end

    style LOSS1 fill:#e74c3c,color:#fff
    style FT3 fill:#2ecc71,color:#fff

现代嵌入模型的标配:指令前缀 (Instruction Prefix)。同样的文本,带不同前缀可获得不同用途的向量。

python
# bge 和 gte 系列支持的指令前缀
task_prefixes = {
    "query": "为这个搜索查询生成表示: ",
    "document": "",  # 文档编码不需要前缀
    "classification": "为这段文本生成用于分类的表示: ",
    "clustering": "为这段文本生成用于聚类的表示: ",
    "pair": "为这段文本对生成表示: ",
}

# 使用
queries = ["Go GMP 调度"]
docs = ["Go 语言的 GMP 调度模型..."]

q_embs = model.encode(
    [task_prefixes["query"] + q for q in queries]
)
d_embs = model.encode(docs)  # 文档不加前缀

similarity = q_embs @ d_embs.T

性能基准实测 ​

中文检索精度 (MTEB Retrieval 子集) ​

模型NDCG@10推理速度 (sent/s)内存占用
stella-large-zh-v3-1792d71.3852.6 GB
bge-large-zh-v1.570.8922.4 GB
bge-m370.2584.4 GB
gte-large-zh69.5902.4 GB
m3e-large67.21201.2 GB
text2vec-large63.1952.4 GB

结论:stella 精度最高但不支持长文本;bge-m3 功能最全但速度最慢;m3e 速度最快但精度略低。实战中 bge-large-zh-v1.5 是性价比之选。

OpenAI vs 开源成本对比 (100 万条文档) ​

方案模型成本耗时
OpenAI APItext-embedding-3-large~$130~15 min
OpenAI APItext-embedding-3-small~$20~15 min
自建 GPUbge-large-zh~$0.5 (电费)~3 hours
自建 CPUm3e-base~$0.02 (电费)~6 hours

参考 ​

批注模式

💬 文章评论

暂无评论,来说点什么吧 👇

编程学习笔记