Bi-Encoder 是 Sentence-Transformers 库中的核心架构,与 CrossEncoder 形成对比,是处理文本嵌入(embeddings)和语义相似度的主要方法。
基本概念 #
Bi-Encoder 是一种双塔结构的神经网络模型,它:
- 分别编码两个输入文本
- 生成固定维度的向量表示(embedding)
- 通过比较向量距离(如余弦相似度)计算相似性
核心特点 #
| 特性 | 说明 |
|---|---|
| 独立编码 | 两个输入文本被分别编码,互不干扰 |
| 高效检索 | 适合大规模场景,可预先计算存储嵌入 |
| 通用性强 | 生成的嵌入可复用(聚类/分类/检索等) |
| 交互有限 | 相比CrossEncoder,准确度稍低 |
典型应用场景 #
graph LR
A[Bi-Encoder] --> B[语义搜索]
A --> C[大规模检索]
A --> D[文本聚类]
A --> E[相似问题匹配]
A --> F[推荐系统]
基本使用示例 #
from sentence_transformers import SentenceTransformer
# 加载预训练模型(典型的Bi-Encoder)
model = SentenceTransformer('all-MiniLM-L6-v2')
# 编码单个句子
embedding1 = model.encode("How many people live in Berlin?")
# 编码多个句子
sentences = [
"Berlin has 3.5 million inhabitants",
"Paris has about 2.1 million residents"
]
embeddings = model.encode(sentences)
# 计算余弦相似度
from sklearn.metrics.pairwise import cosine_similarity
similarity = cosine_similarity([embedding1], embeddings)常见预训练模型 #
HuggingFace 上的热门 Bi-Encoder 模型:
all-MiniLM-L6-v2:通用小型模型(推荐入门)all-mpnet-base-v2:高精度通用模型multi-qa-mpnet-base-dot-v1:问答专用paraphrase-multilingual-MiniLM-L12-v2:多语言支持
与 CrossEncoder 工作流程对比 #
Bi-Encoder 工作流程:
文本A → 独立编码 → 向量A
文本B → 独立编码 → 向量B
计算: cosine(向量A, 向量B)CrossEncoder 工作流程:
[文本A, 文本B] → 联合编码 → 直接输出相似分数高级用法 #
1. 自定义相似度计算 #
import torch.nn.functional as F
# 使用PyTorch计算相似度
emb1 = torch.tensor(embedding1)
emb2 = torch.tensor(embedding2)
cos_sim = F.cosine_similarity(emb1, emb2, dim=0)2. 微调训练 #
from sentence_transformers import InputExample, losses
train_examples = [
InputExample(texts=['Query 1', 'Positive Passage 1'], label=1.0),
InputExample(texts=['Query 1', 'Negative Passage 1'], label=0.0)
]
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
loss = losses.CosineSimilarityLoss(model)
model.fit(train_objectives=[(train_dataloader, loss)], epochs=3)3. 语义搜索实现 #
from sentence_transformers.util import semantic_search
# 预编码所有文档
corpus_embeddings = model.encode(corpus_texts)
# 查询处理
query_embedding = model.encode(user_query)
hits = semantic_search(query_embedding, corpus_embeddings, top_k=5)性能优化技巧 #
- 批量处理:
model.encode()支持批量输入 - 量化加速:使用
quantize_model()减少模型大小 - GPU加速:
model.to('cuda') - 缓存机制:对稳定文本预先计算嵌入
选择建议 #
✅ 使用 Bi-Encoder 当:
- 需要处理大规模数据(>10,000条)
- 要求低延迟响应
- 需要复用文本嵌入
❌ 改用 CrossEncoder 当:
- 数据量小但要求高精度
- 需要复杂的文本交互理解
- 做精细的重排序(reranking)
Bi-Encoder 是现代NLP系统中实现语义相似度计算的基石技术,平衡了效率和效果,是构建搜索/推荐系统的首选方案。