Sentence Transformers 完全指南:从 Embeddings 到 Retrieval 与 Reranking 的四类模型实战
【免费下载链接】sentence-transformersState-of-the-Art Embeddings, Retrieval, and Reranking项目地址: https://gitcode.com/gh_mirrors/se/sentence-transformers
本指南以 sentence-transformers 仓库的 README.md 为核心骨架,系统讲解该框架如何用统一的 API 计算向量(Embeddings)、检索(Retrieval)与重排(Reranking):你将掌握 Sentence Transformer(双塔编码器)、Cross Encoder(重排器)、Sparse Encoder(稀疏编码器)与 Multi-Vector Encoder(晚期交互编码器)四种模型的加载、推理、相似度计算与后续训练微调方案,并了解底层源码实现与仓库内对应的文档、示例和测试路径,可直接落地到语义搜索、语义文本相似度、句对挖掘等真实场景。
图:Bi-Encoder(左,分别编码 query 与 passage 后计算相似度)与 Cross-Encoder(右,将 pair 拼接后联合编码输出分数)的核心架构差异,对应仓库 docs/img/Bi_vs_Cross-Encoder.png。
框架概览:一个 API,四种模型
Sentence Transformers 提供了一个统一且易于上手的方法来使用与训练嵌入(embedding)模型和重排(reranker)模型,其顶层入口全部集中在 sentence_transformers/init.py 中,通过SentenceTransformer、CrossEncoder、SparseEncoder、MultiVectorEncoder四个类向用户开放,并同时导出SentenceTransformerTrainer、CrossEncoderTrainer、SparseEncoderTrainer、MultiVectorEncoderTrainer及对应的TrainingArguments、ModelCardData等训练与模型卡片组件。
四种模型各有定位,适用于不同阶段与场景:
| 模型类型 | 类名(顶层导出) | 输入 → 输出 | 典型用途 | 计算开销 |
|---|---|---|---|---|
| Sentence Transformer(Bi-Encoder) | SentenceTransformer | 文本/图像/音频/视频 → 单个固定维度稠密向量 | 语义搜索、语义相似度、聚类、句对挖掘 | 每段文本编码一次,相似度计算极快 |
| Cross Encoder(Reranker) | CrossEncoder | 输入对 → 单个相似度分数 | 对 top-k 候选做重排(reranking)、语义文本相似度 | 每对输入都要前向计算,较慢但更准 |
| Sparse Encoder | SparseEncoder | 文本 → 词表维度的稀疏向量 | 大规模稀疏检索、与稠密向量互补的混合检索 | 稀疏表示、可解释、利于倒排索引 |
| Multi-Vector Encoder(Late-Interaction) | MultiVectorEncoder | 文本/图像 → 每个 token 一个向量(序列) | ColBERT 风格检索、OCR 免提取的文档检索 | 索引占用更大,但保留 token 级匹配信息 |
README 明确指出:这套框架"为访问、使用和训练先进的 embedding 与 reranker 模型提供了简便方法",覆盖了语义搜索、语义文本相似度(STS)与句对挖掘(paraphrase mining)等大量应用场景。
安装与环境要求
README 推荐的运行环境为Python 3.10+、PyTorch 2.2+以及transformers v5.0+。直接通过 pip 安装即可:
pip install -U sentence-transformers除基础安装外,文档还提供了 uv、conda、源码安装与可编辑安装(editable install)等多种方式,以及 CUDA 环境配置和可选 extras(附加依赖组),包括[image]、[audio]、[video]、[train]、[onnx]、[openvino]、[dev]——例如多模态模型需要额外的pip install -U "sentence-transformers[image]"以启用图像支持。完整说明见 docs/installation.md。
值得说明的是,仓库当前版本号在 sentence_transformers/init.py 中标注为6.2.0.dev0,且导出quantize_embeddings、export_optimized_onnx_model、export_dynamic_quantized_onnx_model、export_static_quantized_openvino_model、mine_hard_negatives等工具函数,表明现代版本在推理后端(ONNX/OpenVINO)与量化方向上有完整支持,相关内容可继续阅读 docs/sentence_transformer/usage/efficiency.md。
Embedding Models:用 Sentence Transformer 计算稠密向量
Sentence Transformer(又称 bi-encoder)模型具有如下特性(见 docs/quickstart.rst):
- 针对文本、图像、音频或视频,计算固定大小的向量表示(embedding);
- 向量计算通常高效,而基于向量的相似度计算非常快;
- 适用任务极广:语义文本相似度、语义搜索、聚类、分类、句对挖掘等;
- 常作为两阶段检索流程的第一步,由 Cross Encoder(reranker)对 bi-encoder 产出的 top-k 结果做重排。
最小可用示例
from sentence_transformers import SentenceTransformer # 1. 加载预训练模型 model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium.", ] # 2. 调用 model.encode() 计算向量 embeddings = model.encode(sentences) print(embeddings.shape) # => (3, 384) # 3. 计算所有句子两两之间的相似度 similarities = model.similarity(embeddings, embeddings) print(similarities) # tensor([[1.0000, 0.6660, 0.1046], # [0.6660, 1.0000, 0.1411], # [0.1046, 0.1411, 1.0000]])其中sentence-transformers/all-MiniLM-L6-v2是一个在超过 10 亿训练句对上微调过的 MiniLM 模型。语义相近的句子(前两句)相似度明显高于无关句子,这正是稠密向量语义编码的核心价值。
源码级解读:encode 与 similarity 的实现细节
从 sentence_transformers/sentence_transformer/model.py 可以看到该类的关键能力:
encode_query/encode_document(model.py#L225-L330、model.py#L388-L492):针对需要区分 query 与 passage 的检索场景提供不对称编码入口,二者内部会自动套用对应的 prompt(例如{"query": "query: ", "passage": "passage: "});encode(model.py#L562-L751):核心推理入口,支持batch_size、show_progress_bar、convert_to_numpy、convert_to_tensor、normalize_embeddings、precision(可选float32、int8、uint8、binary、ubinary,见同文件 model.py#L34 的ALLOWED_PRECISIONS)、truncate_dim等参数;多进程编码能力已整合进encode本身(旧的encode_multi_process被标记为 deprecated);similarity(model.py#L1056-L1075):返回形状为[num_embeddings_1, num_embeddings_2]的相似度矩阵;similarity_fn_name未显式设置时默认惰性初始化为"cosine"(余弦相似度),可选"cosine"、"dot"、"euclidean"、"manhattan";similarity_pairwise(model.py#L1077-L1095):按位置逐对计算embeddings1[i]与embeddings2[i]的相似度,返回一维张量;truncate_dim:可将输出向量截断到指定维度(Matryoshka 风格模型),便于在精度与存储成本之间权衡。
构造函数本身(model.py#L37-L111)还支持丰富的加载参数,值得在生产中关注:
device:如"cuda"、"cpu"、"mps"、"npu";若在model_kwargs中传入device_map,则以device_map为准;prompts/default_prompt_name:注入或覆盖指令前缀,例如{"query": "query: ", "passage": "passage: "},传入{"query": "", "document": ""}可禁用已保存的 prompt;cache_folder:也可通过环境变量SENTENCE_TRANSFORMERS_HOME指定;trust_remote_code:仅在信任的 Hub 仓库中设为True;revision/local_files_only/token:版本控制、离线加载与私有模型鉴权;model_kwargs:透传给 Transformers 的AutoModel.from_pretrained,常用的包括torch_dtype(如torch.float16/bfloat16/"auto")、attn_implementation("eager"/"sdpa"/"flash_attention_2",默认在可用时取"sdpa")、device_map、后端相关参数provider/file_name/export;backend:推理后端,可选"torch"(默认)、"onnx"、"openvino"。
多模态扩展
同一类还支持将图像等模态编码进同一向量空间,例如加载Qwen/Qwen3-VL-Embedding-2B后,可以直接对图片 URL 编码并与文本 query 做跨模态相似度计算(示例见 docs/quickstart.rst 的 Multimodal 标签页)。仓库还提供了完整的图像搜索、图像聚类与重复检测 Notebook:examples/sentence_transformer/applications/image-search。
Reranker Models:用 Cross Encoder 做重排
Cross Encoder(又称 reranker)模型的特点是:
- 针对成对的输入(通常是文本,也可以是图像等其他模态)计算一个相似度分数;
- 相比 bi-encoder 通常准确率更高;
- 但更慢——因为它需要对每一对输入单独做前向计算,而不是对每个文本算一次;
- 因此实践中通常只对 bi-encoder 召回的前 top-k 结果做重排。
其用法与 Sentence Transformer 非常相似:
from sentence_transformers import CrossEncoder # 1. 加载预训练 CrossEncoder 模型 model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2") # 待打分/排序的文本对 query = "How many people live in Berlin?" passages = [ "Berlin had a population of 3,520,031 registered inhabitants in an area of 891.82 square kilometers.", "Berlin has a yearly total of about 135 million day visitors, making it one of the most-visited cities in the European Union.", "In 2013 around 600,000 Berliners were registered in one of the more than 2,300 sport and fitness clubs.", ] # 2a. 直接预测 (query, passage) 文本对的分数 scores = model.predict([(query, passage) for passage in passages]) print(scores) # => [8.607139 5.506266 6.352977]也可以让框架替你完成重排(不必手动排序):
# 2b. 对某个 query 的候选文档列表直接排序 ranks = model.rank(query, passages, return_documents=True) print("Query:", query) for rank in ranks: print(f"- #{rank['corpus_id']} ({rank['score']:.2f}): {rank['text']}") """ Query: How many people live in Berlin? - #0 (8.61): Berlin had a population of 3,520,031 registered inhabitants in an area of 891.82 square kilometers. - #2 (6.35): In 2013 around 600,000 Berliners were registered in one of the more than 2,300 sport and fitness clubs. - #1 (5.51): Berlin has a yearly total of about 135 million day visitors, making it one of the most-visited cities in the European Union. """CrossEncoder.rank返回的每条记录包含corpus_id(在原始documents列表中的下标)、score与可选的text字段,可直接接入下游。
源码级解读:predict 与 rank
predict(sentence_transformers/cross_encoder/model.py#L354-L449):接收(query, passage)形式的输入对序列,返回每个 pair 的分数(默认batch_size=32);rank(model.py#L641):封装了"对每对打分 → 排序 → 截取 top_k"的完整流程,参数包括top_k(默认返回全部排序结果)与return_documents(是否把文档文本一并返回);- 构造参数中,
num_labels决定输出形式:num_labels=1时为回归模型输出连续分数;>1时输出多个 logits,可 softmax 为各类别概率。activation_fn在predict时作用于 logits,默认在num_labels=1时使用nn.Sigmoid(),否则使用nn.Identity();还可通过max_length控制截断长度(见 model.py#L32-L113 的类 docstring)。
多模态重排
Cross Encoder 同样支持多模态输入:Qwen/Qwen3-VL-Reranker-2B可以接收纯文本文档、图片 URL/本地路径,甚至{"text": ..., "image": ...}组合文档,对它们按与 query 的相关性排序(示例见 docs/quickstart.rst)。
完整的检索-重排(retrieve & re-rank)实战示例位于 examples/sentence_transformer/applications/retrieve_rerank 与 examples/cross_encoder/applications,其中 cross_encoder_reranking.py 演示了"bi-encoder 召回 + cross-encoder 重排"的标准两阶段管线。
Sparse Encoder Models:可解释的稀疏向量
Sparse Encoder 模型输出的是绝大多数维度为 0 的稀疏向量,其特性为:
- 计算稀疏向量表示,向量维度对应词表大小,大部分维度为 0;
- 因为稀疏,在大规模检索系统中效率极高(天然适配倒排索引);
- 比稠密向量更具可解释性——非零维度直接对应具体的 token;
- 与稠密向量互补,可构建同时发挥两者优势的混合检索系统。
from sentence_transformers import SparseEncoder # 1. 加载预训练 SparseEncoder 模型(SPLADE 系列) model = SparseEncoder("naver/splade-cocondenser-ensembledistil") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium.", ] # 2. 调用 model.encode() 计算稀疏向量 embeddings = model.encode(sentences) print(embeddings.shape) # [3, 30522] - 词表大小的稀疏表示 # 3. 计算稀疏向量之间的相似度(默认使用点积) similarities = model.similarity(embeddings, embeddings) print(similarities) # tensor([[ 35.629, 9.154, 0.098], # [ 9.154, 27.478, 0.019], # [ 0.098, 0.019, 29.553]]) # 4. 查看稀疏度统计 stats = SparseEncoder.sparsity(embeddings) print(f"Sparsity: {stats['sparsity_ratio']:.2%}") # Sparsity: 99.84% print(f"Avg non-zero dimensions per embedding: {stats['active_dims']:.2f}")上述模型naver/splade-cocondenser-ensembledistil是 SPLADE 系列预训练模型。SPLADE(SparseLexicalAnDExpansion)利用 MLM 预测机制,对输入 token 进行词表层面的词汇扩展后生成稀疏表示,在信息检索任务上尤其有效。
源码级解读:sparsity 统计
SparseEncoder.sparsity(sentence_transformers/sparse_encoder/model.py#L1149-L1196)返回一个包含两个键的字典:
active_dims:每个向量中非零维度的均值;sparsity_ratio:零元素占比的均值(示例中约为 99.86%)。
其实现要求输入为 1D 或 2D 的torch.Tensor,内部先将 1D 升维为 2D,再通过to_sparse_csr()将向量转为 CSR 稀疏格式以 O(1) 获取每行非零计数(在 MPS 设备上会回退到 CPU 计算),可见稀疏路径在实现层面也做了充分优化。
Sparse Encoder 的向量数据库集成、语义搜索示例位于 examples/sparse_encoder/applications/semantic_search,其中包含向量数据库搜索的相关示例代码。
Multi-Vector Encoder Models:ColBERT 风格的晚期交互
Multi-Vector Encoder(又称 late-interaction / ColBERT 风格)模型的特点:
- 对每个输入计算一串 token 级向量,而不是单个固定向量;
- 使用MaxSim 算子打分:对每个 query token,取它与所有 document token 相似度的最大值,再跨 query token 求和;
- 保留了token 级匹配信息(单向量模型会丢弃这些信息),通常检索更强,但索引体积更大;
- 近年基于 VLM 的变体(ColPali、ColQwen2、ColModernVBert 等)将这一范式扩展到图像文档(每个图像 patch 相当于一个 "token"),实现无需 OCR 的端到端文档检索。
from sentence_transformers import MultiVectorEncoder # 1. 加载预训练 late-interaction 模型 model = MultiVectorEncoder("lightonai/GTE-ModernColBERT-v1") queries = ["What is the capital of France?"] documents = [ "Paris is the capital of France.", "Berlin is the capital of Germany.", ] # 2. 注意 query 与 document 使用不对称的编码入口 query_embeddings = model.encode_query(queries) document_embeddings = model.encode_document(documents) print(query_embeddings[0].shape, document_embeddings[0].shape) # (10, 128) (9, 128) # 每个 token 一个 128 维向量,长度因输入而异 # 3. 使用晚期交互(MaxSim)打分 scores = model.similarity(query_embeddings, document_embeddings) print(scores) # tensor([[9.6037, 9.4055]])MultiVectorEncoder类定义于 sentence_transformers/multi_vector_encoder/model.py#L62,其类 docstring 明确说明了与SentenceTransformer(单向量)的差异:encode_query/encode_document分别产出每个输入的 2D 张量(num_tokens_i, embedding_dim),长度可变,similarity则在其上执行 MaxSim 打分。
多模态:免 OCR 的文档检索
将文档从"文本"替换为"图片"即可实现 ColPali 风格的图像文档检索:例如加载vidore/colqwen2.5-v0.2后,query 为文本、文档为扫描页/幻灯片图片(URL、本地路径或 PIL 图像均可),一页图像会产出数百个 patch 向量,再用 MaxSim 与 query 的 token 向量打分(示例见 docs/quickstart.rst)。仓库内对应的训练与推理示例位于 examples/multi_vector_encoder,其中 applications/retrieve_rerank.py 与 applications/semantic_search.py 演示了检索与重排的完整用法,vidore/colqwen2的微调脚本见 examples/multi_vector_encoder/training/multimodal/finetuning_colqwen2.py。
预训练模型生态
仓库提供了覆盖100 多种语言的大量预训练模型:部分为通用模型,部分针对特定场景(如 MS MARCO 检索、STS、NLI、多语种等)专门微调。按模型类型分类的清单位于:
- Sentence Transformer(稠密嵌入)预训练模型
- Cross Encoder(重排器)预训练模型
- Sparse Encoder(稀疏嵌入)预训练模型
- Multi-Vector Encoder(晚期交互)预训练模型
配套的预训练模型细目文档还包括 MS MARCO 系列(v1/v2/v3/v5)、DPR、NQ、STS、NLI、维基百科章节等专项模型说明,见 docs/pretrained-models。
训练:微调出自己的嵌入与重排模型
框架的核心价值之一在于可训练:你可以针对自己的任务微调出特定领域的 embedding 模型、reranker 模型、稀疏编码模型或多向量编码模型。
给 AI 编码 Agent 的提示:如果你使用 Claude Code、Codex、Cursor、Gemini CLI 等 AI 编码代理,可以安装仓库内置的
train-sentence-transformersHugging Face Agent Skill,让代理直接基于你的数据完成微调:hf skills add train-sentence-transformers [--claude] [--global]该 Skill 的完整说明与参考文档见 skills/train-sentence-transformers/SKILL.md,其 references 目录下包含模型架构选型、数据集格式、损失函数、评估器、训练参数与故障排查等专题文档。
按模型类型划分的训练入口:
- 嵌入模型(Embedding Models)
- Sentence Transformer > 训练总览
- Sentence Transformer > 训练示例,仓库内对应示例位于 examples/sentence_transformer/training
- 重排模型(Reranker Models)
- Cross Encoder > 训练总览
- Cross Encoder > 训练示例,仓库内对应示例位于 examples/cross_encoder/training
- 稀疏嵌入模型(Sparse Embedding Models)
- Sparse Encoder > 训练总览
- Sparse Encoder > 训练示例,仓库内对应示例位于 examples/sparse_encoder/training
- 多向量(晚期交互)模型(Multi-Vector / Late-Interaction Models)
- Multi-Vector Encoder > 训练总览
- 训练示例位于 examples/multi_vector_encoder/training
各类训练的共同亮点(README 明确列出):
- 支持多种 transformer 骨干网络:BERT、RoBERTa、XLM-R、DistilBERT、Electra、BART 等;
- 支持多语言与多任务联合训练;
- 训练过程中实时评估以挑选最优模型;
- 损失函数选择丰富:嵌入模型提供20+ 种损失函数(详见 docs/sentence_transformer/loss_overview.md),重排模型提供10+ 种(docs/cross_encoder/loss_overview.md),稀疏嵌入模型提供10+ 种(docs/sparse_encoder/loss_overview.md),可针对语义搜索、句对挖掘、语义相似度比较、聚类、三元组损失、对比损失等不同目标精细调优。
训练 API 方面,SentenceTransformerTrainer/CrossEncoderTrainer等基于 TransformersTrainer风格封装,配合对应的TrainingArguments使用,相关实现见 sentence_transformers/sentence_transformer/trainer.py 与 sentence_transformers/sentence_transformer/training_args.py。
应用场景示例
README 将框架的典型应用归纳如下,每个场景在仓库中都有可直接运行的示例:
- 计算句子向量:稠密向量见 examples/sentence_transformer/applications/computing-embeddings,稀疏向量见 examples/sparse_encoder/applications/computing_embeddings;
- 语义文本相似度(STS):稠密版见 docs/sentence_transformer/usage/semantic_textual_similarity.rst,稀疏版见 examples/sparse_encoder/applications/semantic_textual_similarity;
- 语义搜索(Semantic Search):稠密版见 examples/sentence_transformer/applications/semantic-search,稀疏版见 examples/sparse_encoder/applications/semantic_search;
- 检索与重排(Retrieve & Re-Rank):纯稠密检索与稀疏/稠密/混合检索均见 examples/sentence_transformer/applications/retrieve_rerank;
- 聚类(Clustering):见 examples/sentence_transformer/applications/clustering;
- 句对挖掘(Paraphrase Mining):见 examples/sentence_transformer/applications/paraphrase-mining;
- 平行句挖掘(Translated Sentence Mining):见 examples/sentence_transformer/applications/parallel-sentence-mining;
- 多语言图像搜索、聚类与重复检测:见 examples/sentence_transformer/applications/image-search。
此外,examples/sentence_transformer/applications/embedding-quantization 提供 Faiss、USearch 上的向量量化与检索基准示例,docs/sentence_transformer/usage/efficiency.rst 则给出将推理提速 2x–3x 的具体手段(如 ONNX/OpenVINO 后端、批量策略等)。
开发环境搭建与测试
若要在本仓库中进行开发(而非仅安装使用),README 给出了标准流程。克隆仓库后,在虚拟环境中执行:
python -m pip install -e ".[dev]" pre-commit install然后运行测试:
pytest仓库的完整测试套件位于 tests 目录,按sentence_transformer、cross_encoder、sparse_encoder、multi_vector_encoder、base、backend、util等模块组织,例如 tests/sentence_transformer/test_compute_embeddings.py、tests/cross_encoder/test_model.py 等,可作为理解各模型行为与回归保障的参考。依赖与打包配置见 pyproject.toml。
引用与致谢
如果本框架对你的工作有帮助,README 建议引用如下论文:
@inproceedings{reimers-2019-sentence-bert, title = "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks", author = "Reimers, Nils and Gurevych, Iryna", booktitle = "Proceedings of the 2019 Conference on Empirical Methods in Natural Language Processing", month = "11", year = "2019", publisher = "Association for Computational Linguistics", url = "https://arxiv.org/abs/1908.10084", }如果使用了多语种模型,可同时引用知识蒸馏相关的论文:
@inproceedings{reimers-2020-multilingual-sentence-bert, title = "Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation", author = "Reimers, Nils and Gurevych, Iryna", booktitle = "Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing", month = "11", year = "2020", publisher = "Association for Computational Linguistics", url = "https://arxiv.org/abs/2004.09813", }更多被整合进框架的出版物清单见 docs/publications.md。该项目最初由达姆施塔特工业大学(TU Darmstadt)的 UKP 实验室开发,目前由 Hugging Face 维护;仓库内同时声明其包含实验性软件,发布目的在于为相应论文提供补充背景细节。
下一步建议
从 README.md 出发,推荐的深入学习路径是:先对照 docs/quickstart.rst 跑通四种模型的 Hello World,再按任务类型进入对应模型的 usage 文档与 examples 目录实践完整管线,最后通过训练总览与 loss 总览针对自己的数据集做微调,并结合 docs/sentence_transformer/usage/efficiency.rst 做推理侧的性能优化,即可构建一套从向量化、检索到重排的完整生产级语义系统。
【免费下载链接】sentence-transformersState-of-the-Art Embeddings, Retrieval, and Reranking项目地址: https://gitcode.com/gh_mirrors/se/sentence-transformers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考