Embedding模型选择:让你的AI”看懂”文本

这篇文章解决什么问题

你的RAG系统检索效果不好?可能是Embedding模型选错了。这篇文章帮你搞懂各种Embedding模型的特点,学会怎么选、怎么用、怎么调优。

前言:Embedding到底是啥

先来一个灵魂拷问:Embedding是什么?

我用大白话解释一下。Embedding就是把文字变成一串数字的过程。为什么要变?因为计算机处理数字比处理文字在行。

举个例子,“深度学习”这四个字,Embedding模型会把它变成一串数字,比如[0.123, -0.456, 0.789, ...]。语义相近的词,转换后的数字也会”比较接近”。

这就是向量检索的核心原理:把问题也变成向量,然后在数据库里找和它”距离最近”的文档。

0.1 Embedding质量直接决定检索效果

你可能遇到这种情况:

  • 问”机器学习”能找到相关内容
  • 但问”ML”就找不到
  • 问”machine learning”也不行

这就是Embedding模型没选对。好的模型应该能理解这些词之间的”亲戚关系”。

一、主流Embedding模型盘点

1.1 BGE系列(国产之光)

BGE是北京智源开源的Embedding模型,中文支持非常棒。

一句话介绍:国产最强中文Embedding模型,免费开源,中文场景首选。

from FlagEmbedding import BGEM3FlagModel
 
# 加载模型
model = BGEM3FlagModel(
    "BAAI/bge-m3",
    use_fp16=True
)
 
# 编码
sentences = ["深度学习是机器学习的分支", "DL是deep learning的缩写"]
result = model.encode(sentences)
 
# 获取稠密向量
dense_vecs = result["dense_vecs"]

BGE系列全家福

模型向量维度中文支持特点推荐场景
BGE-Large-ZH1024★★★★★中文最强中文高精度需求
BGE-M31024★★★★☆多语言+多功能国际化、中英混合
BGE-Base-ZH768★★★★☆平衡之选通用场景
BGE-Small-ZH512★★★☆☆轻量快速资源受限场景

我的推荐:中文场景直接用BGE-Large-ZH,免费且效果好。

1.2 OpenAI Embedding

from openai import OpenAI
 
client = OpenAI(api_key="your-key")
 
# 获取embedding
response = client.embeddings.create(
    model="text-embedding-3-small",
    input="深度学习教程"
)
 
embedding = response.data[0].embedding

一句话介绍:贵但是稳,大厂背书,闭源服务。

优点

  • 模型质量稳定
  • 托管服务,不用自己跑模型
  • 支持维度缩减(3-large可减到256/1024/3072维度)

缺点

  • 要钱!大概0.00013美元/1000 tokens
  • 数据送第三方(隐私敏感场景慎用)
  • 可能有网络延迟

适用场景:预算充足、追求稳定性、懒得运维。

1.3 Cohere Embedding

import cohere
 
co = cohere.Client(api_key="your-key")
 
# 多语言embedding
response = co.embed(
    texts=["机器学习", "Machine Learning"],
    model="embed-multilingual-v3.0",
    input_type="search_document"
)
 
embeddings = response.embeddings.float_

一句话介绍:企业级多语言支持,做海外业务的首选。

优点

  • 100+种语言支持
  • 企业级稳定性
  • 有免费额度

缺点

  • 也要钱
  • 中文支持不如BGE

适用场景:国际化业务、多语言混合检索。

1.4 GTE(阿里巴巴)

from sentence_transformers import SentenceTransformer
 
model = SentenceTransformer("thenlper/gte-large-zh")
 
sentences = ["深度学习入门", "DL基础教程"]
embeddings = model.encode(sentences)

一句话介绍:阿里开源,中文不错,免费。

优点

  • 开源免费
  • 中文支持好
  • 容易上手

缺点

  • 精度略逊于BGE
  • 模型更新不如BGE频繁

适用场景:预算有限、追求免费、中文为主。

1.5 MiniLM(微软)

from sentence_transformers import SentenceTransformer
 
# 英文高速版
model = SentenceTransformer("all-MiniLM-L6-v2")
 
# 多语言版
model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
 
embedding = model.encode("Machine learning is great")

一句话介绍:超快超轻,适合追求速度的场景。

优点

  • 速度极快
  • 体积小(几百MB)
  • 资源消耗低

缺点

  • 英文为主
  • 中文效果一般
  • 精度略低

适用场景:延迟敏感、英文为主、边缘设备部署。

二、选型决策

2.1 先问自己几个问题

  1. 主要语言是什么?

    • 中文 → BGE系列
    • 英文 → OpenAI/MiniLM
    • 多语言 → Cohere/BGE-M3
  2. 预算多少?

    • 免费 → BGE/GTE/MiniLM开源版
    • 付费 → OpenAI/Cohere API
  3. 对精度要求高吗?

    • 极高 → OpenAI text-embedding-3-large
    • 一般 → BGE-Large-ZH(免费里最强)
  4. 对延迟敏感吗?

    • 敏感 → MiniLM/本地部署
    • 不敏感 → 都可以

2.2 懒人推荐

场景推荐模型理由
中文RAGBGE-Large-ZH免费、中文最强
中英混合BGE-M3多语言支持
企业级稳定OpenAI embed-3-large贵但稳
国际化业务Cohere embed-3多语言首选
个人项目/学习GTE-large-zh免费、易上手
边缘设备MiniLM-L6超轻超快

2.3 我的选择

个人开发者/小团队

BGE-Large-ZH 本地部署,免费且效果好。

中小团队

BGE-M3 中文+英文双版本,或者直接上OpenAI API省心。

企业用户

OpenAI embed-3-large,追求稳定性。

三、实战代码

3.1 本地部署BGE

# 安装
pip install FlagEmbedding
 
# 下载模型(首次使用会自动下载)
python -c "from FlagEmbedding import BGEM3FlagModel; model = BGEM3FlagModel('BAAI/bge-large-zh-v1.5')"
from FlagEmbedding import BGEM3FlagModel
import numpy as np
 
# 加载模型
model = BGEM3FlagModel(
    "BAAI/bge-large-zh-v1.5",
    use_fp16=True,  # 半精度,加速省显存
    device="cuda"   # GPU加速
)
 
# 文本编码
texts = [
    "机器学习是人工智能的核心技术",
    "深度学习是机器学习的一个分支",
    "Python是一门编程语言"
]
 
# 单条编码
embedding = model.encode("深度学习入门")["dense_vecs"][0]
 
# 批量编码
results = model.encode(texts)
vectors = results["dense_vecs"]
 
# 计算相似度
def cosine_sim(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
 
# 问"机器学习"应该和前两条更接近
q = model.encode(["机器学习"])["dense_vecs"][0]
print(f"与'机器学习'的相似度:")
print(f"  '机器学习是人工智能的核心技术': {cosine_sim(q, vectors[0]):.4f}")
print(f"  '深度学习是机器学习的分支': {cosine_sim(q, vectors[1]):.4f}")
print(f"  'Python是一门编程语言': {cosine_sim(q, vectors[2]):.4f}")

3.2 OpenAI API调用

from openai import OpenAI
import numpy as np
 
client = OpenAI(api_key="your-api-key")
 
def get_embedding(text, model="text-embedding-3-small"):
    """获取文本embedding"""
    response = client.embeddings.create(
        model=model,
        input=text
    )
    return response.data[0].embedding
 
def batch_embeddings(texts, model="text-embedding-3-small"):
    """批量获取embedding(更高效)"""
    response = client.embeddings.create(
        model=model,
        input=texts  # 最多2048条
    )
    return [item.embedding for item in response.data]
 
# 使用
texts = ["机器学习", "深度学习", "Python"]
embeddings = batch_embeddings(texts)
print(f"获取了{len(embeddings)}个embedding")

3.3 语义搜索示例

from FlagEmbedding import BGEM3FlagModel
import numpy as np
 
# 加载模型
model = BGEM3FlagModel("BAAI/bge-large-zh-v1.5")
 
# 文档库
documents = [
    "深度学习是机器学习的分支,使用神经网络模型",
    "卷积神经网络CNN主要用于图像识别任务",
    "Python的异步编程使用asyncio模块",
    "循环神经网络RNN适合处理序列数据",
    "强化学习通过奖励机制训练智能体"
]
 
# 用户问题
query = "什么是深度学习?和机器学习有什么关系?"
 
# 编码
doc_vectors = model.encode(documents)["dense_vecs"]
query_vector = model.encode([query])["dense_vecs"][0]
 
# 计算相似度并排序
similarities = []
for i, doc in enumerate(documents):
    sim = np.dot(doc_vectors[i], query_vector) / (
        np.linalg.norm(doc_vectors[i]) * np.linalg.norm(query_vector)
    )
    similarities.append((i, doc, sim))
 
# 按相似度排序
similarities.sort(key=lambda x: x[2], reverse=True)
 
# 输出结果
print("检索结果(按相关性排序):")
for i, (idx, doc, sim) in enumerate(similarities[:3]):
    print(f"{i+1}. [{sim:.4f}] {doc}")

四、Embedding微调

4.1 什么时候需要微调

通用Embedding模型可能不够用的情况:

  • 你的知识库有大量专业术语(医疗、法律、技术文档)
  • 通用模型在特定任务上效果不好
  • 你有足够的领域标注数据

4.2 微调数据集准备

from sentence_transformers import InputExample
import pandas as pd
 
# 准备训练数据(格式:query, positive, negative)
train_data = []
 
# 方式1:从CSV加载
df = pd.read_csv("train_data.csv")
for _, row in df.iterrows():
    train_data.append(InputExample(
        texts=[row["query"], row["positive"], row["negative"]],
        label=1.0 if row.get("relevant", True) else 0.0
    ))
 
# 方式2:手动添加
train_data.append(InputExample(
    texts=["室上性心动过速", "房室结折返性心动过速", "肺炎"]
))
train_data.append(InputExample(
    texts=["阿司匹林用法", "解热镇痛抗炎", "咖啡因代谢"]
))

4.3 微调代码

from sentence_transformers import SentenceTransformer, evaluation
from torch.utils.data import DataLoader
 
# 加载基座模型
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
 
# 创建DataLoader
train_dataloader = DataLoader(
    train_data,
    shuffle=True,
    batch_size=16
)
 
# 评估器(可选)
evaluators = [
    evaluation.EmbeddingAccuracyEvaluator.from_input_examples(
        eval_data,
        name="eval"
    )
]
 
# 开始微调
model.fit(
    train_objectives=[(train_dataloader, None)],
    evaluator=evaluation.SequentialEvaluator(evaluators),
    epochs=3,
    warmup_steps=100,
    output_path="./finetuned_model",
    save_best_model=True,
    show_progress_bar=True
)
 
# 使用微调后的模型
finetuned_model = SentenceTransformer("./finetuned_model")
query_emb = finetuned_model.encode("室上性心动过速")

五、常见问题

5.1 向量维度怎么选

维度适用场景存储占用
256存储受限、精度要求一般最小
512平衡之选中等
768通用场景较大
1024高精度需求
1536+追求极致精度很大

建议:大多数场景768或1024就够了,不用盲目追求高维度。

5.2 中文分词问题

有些Embedding模型没有针对中文优化,可能影响效果。

解决方案

  • 用BGE系列(专门针对中英文优化)
  • 或者用jieba提前分词
  • 检查模型是否支持中文

5.3 批量处理优化

# 正确方式:批量编码
# ❌ 错误:逐条编码
for doc in documents:
    vec = model.encode([doc])  # 慢!
 
# ✅ 正确:批量编码
vectors = model.encode(documents)  # 快10-100倍

5.4 模型版本更新

BGE等开源模型会持续更新,新版本通常更好:

# 检查是否有新版本
# huggingface上有标注
 
# 定期更新模型
model = BGEM3FlagModel("BAAI/bge-m3")  # 会自动下载最新版本

六、性能对比

6.1 精度对比(中文MTEB基准)

模型中文检索多语言英文
BGE-Large-ZH68.565.262.1
BGE-M366.867.564.8
OpenAI embed-3-large65.269.868.5
GTE-Large-ZH64.262.560.8
Cohere embed-363.568.267.5

6.2 速度对比

模型延迟(单条)吞吐量
MiniLM-L6~8ms125/s
BGE-Large-ZH~45ms22/s
OpenAI API~150ms7/s
GTE-Large-ZH~55ms18/s

七、总结

Embedding模型选择建议:

  1. 中文场景:BGE-Large-ZH,免费且效果好
  2. 多语言场景:BGE-M3或Cohere
  3. 追求稳定:OpenAI embed-3-large
  4. 追求速度:MiniLM
  5. 预算有限:开源模型本地部署

记住:没有最好的模型,只有最适合你场景的模型

相关主题


更新记录

  • 2026-04-24:改写完成,语言风格优化
  • 增加实战代码和选型建议