Embedding 模型深度解析:文本嵌入技术原理与 MTEB 评估体系
摘要
本文深入解析文本 Embedding 模型的技术原理,从基础概念到主流模型架构,全面探讨 MTEB 评估体系的设计与应用。读者将理解 Embedding 如何将文本转换为向量表示,掌握模型选型策略与评估方法。
引言
背景介绍
文本 Embedding(嵌入)是自然语言处理的核心技术,它将离散的文本转换为连续的向量表示,使得文本之间的语义关系可以在向量空间中计算。从早期的 Word2Vec 到现代的 BGE、Cohere 等模型,Embedding 技术已成为 RAG、搜索、推荐等应用的基础设施。
问题陈述
- Embedding 模型的核心原理是什么?
- 如何评估不同模型的性能表现?
- 如何在实际应用中选择合适的 Embedding 模型?
文章结构预览
本文将从以下方面展开:
- Embedding 的基础概念与数学原理
- 主流 Embedding 模型架构解析
- MTEB 评估体系详解
- 模型选型与实践应用
Embedding 基础概念与数学原理
什么是文本 Embedding
文本 Embedding 是将文本映射到高维向量空间的过程:
输入: "人工智能正在改变世界"
输出: [0.23, -0.45, 0.67, ..., 0.12] (768维向量)
核心思想:
- 语义相近的文本,向量距离接近
- 语义无关的文本,向量距离较远
数学基础:向量空间模型
相似度计算
Embedding 的核心应用是计算文本相似度:
python
def cosine_similarity(vec_a: np.ndarray, vec_b: np.ndarray) -> float:
"""
余弦相似度 - 最常用的 Embedding 相似度度量
公式: cos(A, B) = (A · B) / (||A|| * ||B||)
范围: [-1, 1]
- 1: 完全相似
- 0: 无关
- -1: 完全相反
"""
dot_product = np.dot(vec_a, vec_b)
norm_a = np.linalg.norm(vec_a)
norm_b = np.linalg.norm(vec_b)
return dot_product / (norm_a * norm_b)
# 示例
embedding1 = model.encode("人工智能")
embedding2 = model.encode("机器学习")
embedding3 = model.encode("天气预报")
sim1 = cosine_similarity(embedding1, embedding2) # 0.85 (语义相近)
sim2 = cosine_similarity(embedding1, embedding3) # 0.15 (语义无关)
距离度量对比
| 度量方式 | 公式 | 特点 | 适用场景 |
|---|---|---|---|
| 余弦相似度 | cos(A,B) | 不受向量长度影响 | 文本语义相似 |
| 欧氏距离 | A-B | ||
| 曼哈顿距离 | Σ | Ai-Bi | |
| 点积 | A·B | 计算最快 | 已归一化向量 |
Embedding 的维度选择
python
# 不同模型的典型维度
dimensions = {
"Word2Vec": 300, # 传统词向量
"BERT-base": 768, # Transformer 基础维度
"BERT-large": 1024, # 大模型维度
"BGE-large": 1024, # 中文优化模型
"Cohere-v3": 1024, # 商业 API 模型
"OpenAI-3-large": 3072, # 大维度高精度
}
维度权衡:
- 高维度:表达能力更强,但计算成本高
- 低维度:效率高,但可能损失语义细节
- 实际选择:根据任务需求和计算资源平衡
关键要点
- Embedding 将文本映射为向量,语义关系转化为空间距离
- 余弦相似度是最常用的度量方式
- 维度选择需要在表达能力和计算效率间平衡
主流 Embedding 模型架构解析
模型演进历程
| 时代 | 代表模型 | 核心技术 | 主要突破 |
|---|---|---|---|
| 2013 | Word2Vec | Skip-gram/CBOW | 静态词向量 |
| 2018 | BERT | Transformer | 上下文动态表示 |
| 2021 | Sentence-BERT | Siamese Network | 句子级 Embedding |
| 2023 | BGE | Contrastive Learning | 中文优化 |
| 2024 | Cohere-v4 | 多任务训练 | 商业 API |
BERT 系列 Embedding
架构原理
BERT 作为 Embedding 模型的基本原理:
python
class BertEmbedding:
"""
BERT Embedding 提取方式
三种常见策略:
1. CLS Token: 使用第一个 token 的输出
2. Mean Pooling: 所有 token 输出的平均
3. Max Pooling: 所有 token 输出的最大值
"""
def __init__(self, model_name="bert-base-chinese"):
self.model = BertModel.from_pretrained(model_name)
def encode_cls(self, text: str) -> np.ndarray:
"""CLS Token 方式"""
inputs = self.tokenize(text)
outputs = self.model(**inputs)
cls_embedding = outputs.last_hidden_state[0, 0, :] # 第一个 token
return cls_embedding.numpy()
def encode_mean_pooling(self, text: str) -> np.ndarray:
"""Mean Pooling 方式(推荐)"""
inputs = self.tokenize(text)
outputs = self.model(**inputs)
# 考虑 attention mask,忽略 padding
token_embeddings = outputs.last_hidden_state
attention_mask = inputs["attention_mask"]
mean_embedding = torch.sum(
token_embeddings * attention_mask.unsqueeze(-1), dim=1
) / torch.sum(attention_mask, dim=1, keepdim=True)
return mean_embedding.numpy()[0]
Sentence-BERT 改进
SBERT 通过 Siamese 结构改进 Embedding 质量:
python
class SentenceBERT:
"""
Sentence-BERT 架构
核心改进:
- 使用孪生网络结构
- 对比学习训练目标
- 直接输出句子级表示
"""
def __init__(self, model_name="sentence-transformers/paraphrase-multilingual"):
self.model = SentenceTransformer(model_name)
def encode_batch(self, sentences: list) -> np.ndarray:
"""批量编码,高效处理"""
embeddings = self.model.encode(sentences)
return embeddings
def similarity_matrix(self, sentences: list) -> np.ndarray:
"""计算句子间的相似度矩阵"""
embeddings = self.encode_batch(sentences)
similarity = cosine_similarity(embeddings, embeddings)
return similarity
BGE 模型系列
BGE(BAAI General Embedding)是中文领域表现最优的 Embedding 模型:
BGE 模型家族
| 模型 | 维度 | 特点 | MTEB 排名 |
|---|---|---|---|
| BGE-small-zh | 512 | 轻量高效 | 中文任务优秀 |
| BGE-base-zh | 768 | 平衡性能 | 开源首选 |
| BGE-large-zh | 1024 | 高精度 | 中文最优 |
| BGE-M3 | 1024 | 多语言 | 全球领先 |
BGE 核心技术
python
"""
BGE 的核心技术:
1. 对比学习训练(Contrastive Learning)
- 正样本:语义相似的文本对
- 负样本:语义不同的文本对
2. 批内负采样(In-batch Negatives)
- 利用 batch 内其他样本作为负样本
- 提高训练效率
3. 多任务联合训练
- 检索、分类、聚类等任务统一优化
"""
def contrastive_loss(pos_embeddings, neg_embeddings, temperature=0.05):
"""
InfoNCE 对比学习损失函数
核心:拉近正样本,推远负样本
"""
pos_sim = torch.matmul(pos_embeddings, pos_embeddings.T) / temperature
neg_sim = torch.matmul(pos_embeddings, neg_embeddings.T) / temperature
logits = torch.cat([pos_sim, neg_sim], dim=-1)
labels = torch.arange(len(pos_embeddings))
loss = torch.nn.functional.cross_entropy(logits, labels)
return loss
BGE 使用实践
python
from sentence_transformers import SentenceTransformer
# 加载模型
model = SentenceTransformer('BAAI/bge-large-zh-v1.5')
# 编码中文文本
texts = [
"人工智能技术的快速发展",
"机器学习算法的应用研究",
"天气预报预测模型"
]
embeddings = model.encode(texts)
# 计算相似度
from sklearn.metrics.pairwise import cosine_similarity
sim_matrix = cosine_similarity(embeddings)
print(sim_matrix)
# 输出:[[1.00, 0.82, 0.15],
# [0.82, 1.00, 0.18],
# [0.15, 0.18, 1.00]]
商业 API Embedding
Cohere Embedding
python
import cohere
co = cohere.Client("your-api-key")
# Cohere embed-v4 特点:
# - 多语言支持
# - 高质量向量表示
# - 支持 truncate 参数控制维度
response = co.embed(
texts=["人工智能技术", "机器学习算法"],
model="embed-v4",
input_type="search_document", # 文档索引场景
truncate="END" # 截断方式
)
embeddings = response.embeddings
OpenAI Embedding
python
from openai import OpenAI
client = OpenAI()
# OpenAI text-embedding-3 特点:
# - 支持 dimensions 参数降维
# - 高 MTEB 排名
# - 中文支持较弱
response = client.embeddings.create(
input=["人工智能技术", "机器学习算法"],
model="text-embedding-3-large",
dimensions=1024 # 可选降维
)
embeddings = [item.embedding for item in response.data]
关键要点
- BERT 系列:基于 Transformer,支持上下文动态表示
- BGE:中文最优选择,对比学习训练
- 商业 API:高质量但成本高,选型需考虑语言支持
MTEB 评估体系详解
什么是 MTEB
MTEB(Massive Text Embedding Benchmark)是目前最权威的 Embedding 模型评估体系:
- 覆盖范围:8 大任务类别,56+ 数据集
- 多语言:支持 112+ 语言
- 开源评估:可本地运行评估流程
MTEB 任务类别
| 任务类别 | 评估内容 | 典型数据集 |
|---|---|---|
| Retrieval | 信息检索能力 | MSMARCO, BEIR |
| Classification | 文本分类 | AmazonReviews, Bank |
| Clustering | 文本聚类 | ArxivClustering |
| Reranking | 重排序 | AskUbuntuDuplicates |
| STS (Semantic Textual Similarity) | 语义相似度 | STS Benchmark |
| Pair Classification | 对分类 | QuoraDuplicates |
| Summarization | 摘要聚类 | SummEval |
| Instruction Retrieval | 指令检索 | Retrieval-20Q |
MTEB 评估流程
python
import mteb
from sentence_transformers import SentenceTransformer
# 创建评估任务
tasks = mteb.get_tasks(
tasks=["Retrieval", "Classification", "STS"]
)
# 加载模型
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
# 运行评估
evaluation = mteb.MTEB(tasks=tasks)
results = evaluation.run(model)
# 查看结果
for task_result in results:
print(f"Task: {task_result.task_name}")
print(f"Score: {task_result.get_score()}")
MTEB Leaderboard 排名
截至 2025 年的 Top Embedding 模型排名:
| 模型 | Overall Score | Retrieval | Classification | 特点 |
|---|---|---|---|---|
| Cohere embed-v4 | 65.2 | 65.0 | 70.5 | 商业 API,多语言 |
| OpenAI text-3-large | 64.6 | 64.2 | 69.8 | API,可降维 |
| BGE-M3 | 63.0 | 62.8 | 68.5 | 开源,多语言 |
| Gemini Embedding 2 | 66.1 | 65.5 | 71.2 | Google API |
| Qwen3-Embedding | 62.5 | 61.8 | 67.5 | 开源,中文优 |
中文 MTEB:C-MTEB
python
"""
C-MTEB 是针对中文文本的评估基准
包含:
- 中文检索任务
- 中文分类任务
- 中文相似度任务
"""
# 运行中文评估
tasks = mteb.get_tasks(tasks=["CMTEBRetrieval", "CMTEBClassification"])
results = evaluation.run(model)
评估指标详解
Retrieval 任务指标
python
"""
检索任务的核心指标:
- NDCG@k (Normalized Discounted Cumulative Gain)
考虑排序位置的加权评分
- Recall@k
前 k 个结果中正确文档的召回率
- MRR (Mean Reciprocal Rank)
第一个正确结果的位置倒数均值
"""
def compute_ndcg_at_k(retrieved_ids, relevant_ids, k=10):
"""计算 NDCG@k"""
dcg = 0
for i, doc_id in enumerate(retrieved_ids[:k]):
if doc_id in relevant_ids:
dcg += 1 / np.log2(i + 2)
# 理想 DCG
ideal_dcg = sum(1 / np.log2(i + 2) for i in range(min(k, len(relevant_ids))))
return dcg / ideal_dcg if ideal_dcg > 0 else 0
Classification 任务指标
python
"""
分类任务的评估:
- Accuracy
准确率
- F1 Score
精确率和召回率的调和平均
- 使用 Embedding + Logistic Regression/KNN 进行分类
"""
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, f1_score
def evaluate_classification(train_embeddings, train_labels,
test_embeddings, test_labels):
"""评估 Embedding 的分类能力"""
clf = LogisticRegression()
clf.fit(train_embeddings, train_labels)
predictions = clf.predict(test_embeddings)
accuracy = accuracy_score(test_labels, predictions)
f1 = f1_score(test_labels, predictions, average='weighted')
return {"accuracy": accuracy, "f1": f1}
关键要点
- MTEB 是 Embedding 模型的权威评估基准
- 不同任务类型反映 Embedding 的不同能力维度
- 中文场景推荐使用 C-MTEB 进行评估
模型选型与实践应用
选型决策框架
选型考虑因素:
├── 语言支持
│ ├── 中文为主 → BGE-large-zh, Qwen-Embedding
│ ├── 英文为主 → OpenAI-3-large, Cohere
│ └── 多语言 → BGE-M3, Cohere-v4
│
├── 使用方式
│ ├── 本地部署 → BGE, Sentence-BERT
│ ├── API 调用 → OpenAI, Cohere
│ └── 离线处理 → 本地模型
│
├── 性能需求
│ ├── 高精度 → 大维度模型 (1024+)
│ ├── 高效率 → 小维度模型 (512)
│ ├── 平衡 → 中等维度 (768)
│
└── 成本考量
├── 免费 → 开源模型
├── 低成本 → 轻量模型
└── 高预算 → 商业 API
RAG 应用最佳实践
python
class RAGEmbeddingPipeline:
"""
RAG 系统中的 Embedding 应用
关键步骤:
1. 文档 Embedding 生成
2. 向量数据库存储
3. Query Embedding 与检索
4. 重排序优化
"""
def __init__(self, model_name="BAAI/bge-large-zh-v1.5"):
self.embed_model = SentenceTransformer(model_name)
self.vector_db = VectorDB() # 如 FAISS, Milvus
def index_documents(self, documents: list):
"""索引文档"""
# 批量编码
embeddings = self.embed_model.encode(
documents,
batch_size=32,
show_progress_bar=True
)
# 存入向量数据库
self.vector_db.add(documents, embeddings)
def retrieve(self, query: str, top_k: int = 10) -> list:
"""检索相关文档"""
# 编码查询
query_embedding = self.embed_model.encode(query)
# 向量检索
results = self.vector_db.search(query_embedding, top_k)
# 可选:重排序
reranked = self._rerank(query, results)
return reranked
def _rerank(self, query: str, candidates: list) -> list:
"""使用重排序模型优化结果"""
# Cross-Encoder 重排序(精度更高)
reranker = SentenceTransformer("cross-encoder/ms-marco-MiniLM-L-6-v2")
pairs = [(query, doc) for doc in candidates]
scores = reranker.predict(pairs)
# 按分数排序
ranked = sorted(zip(candidates, scores), key=lambda x: -x[1])
return [doc for doc, score in ranked]
搜索应用实践
python
class SemanticSearch:
"""
语义搜索引擎实现
区别于关键词搜索:
- 支持语义匹配而非字面匹配
- 可处理同义词、近义表达
"""
def __init__(self, model_name="BAAI/bge-large-zh-v1.5"):
self.model = SentenceTransformer(model_name)
self.index = None
self.documents = []
def build_index(self, documents: list):
"""构建搜索索引"""
self.documents = documents
embeddings = self.model.encode(documents)
# 使用 FAISS 构建索引
import faiss
dimension = embeddings.shape[1]
self.index = faiss.IndexFlatIP(dimension) # 内积索引
self.index.add(embeddings.astype('float32'))
def search(self, query: str, top_k: int = 5) -> list:
"""语义搜索"""
query_embedding = self.model.encode(query)
# FAISS 搜索
distances, indices = self.index.search(
query_embedding.reshape(1, -1).astype('float32'),
top_k
)
results = [
(self.documents[idx], distances[0][i])
for i, idx in enumerate(indices[0])
]
return results
效果评估
在不同应用场景下的模型效果对比:
| 应用场景 | 推荐模型 | 效果指标 |
|---|---|---|
| 中文 RAG | BGE-large-zh | Retrieval NDCG@10: 68.5% |
| 英文搜索 | OpenAI-3-large | Retrieval NDCG@10: 64.2% |
| 多语言检索 | BGE-M3 | Cross-lingual: 62.8% |
| 文本分类 | Sentence-BERT | Accuracy: 85%+ |
总结
核心要点回顾
-
向量表示原理:Embedding 将文本转换为向量,语义关系转化为空间距离,余弦相似度是核心度量
-
主流模型选择:BERT 系列支持上下文表示,BGE 是中文最优,商业 API 提供高质量服务
-
MTEB 评估体系:8 大任务类别全面评估 Embedding 能力,C-MTEB 针对中文场景
-
选型决策框架:根据语言、使用方式、性能需求、成本综合考量
最佳实践建议
- 中文应用首选 BGE:开源、高质量、持续优化
- 商业场景考虑 API:OpenAI、Cohere 提供稳定服务
- RAG 系统结合重排序:Embedding + Cross-Encoder 提升精度
- 本地评估模型性能:使用 MTEB 验证选型决策
扩展阅读
- MTEB Benchmark 官方文档
- BGE 模型技术报告
- Sentence Transformers 文档