Sentence Transformers 完全指南:从 Embeddings 到 Retrieval 与 Reranking 的四类模型实战
2026/9/20 18:35:58 网站建设 项目流程

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 中,通过SentenceTransformerCrossEncoderSparseEncoderMultiVectorEncoder四个类向用户开放,并同时导出SentenceTransformerTrainerCrossEncoderTrainerSparseEncoderTrainerMultiVectorEncoderTrainer及对应的TrainingArgumentsModelCardData等训练与模型卡片组件。

四种模型各有定位,适用于不同阶段与场景:

模型类型类名(顶层导出)输入 → 输出典型用途计算开销
Sentence Transformer(Bi-Encoder)SentenceTransformer文本/图像/音频/视频 → 单个固定维度稠密向量语义搜索、语义相似度、聚类、句对挖掘每段文本编码一次,相似度计算极快
Cross Encoder(Reranker)CrossEncoder输入对 → 单个相似度分数对 top-k 候选做重排(reranking)、语义文本相似度每对输入都要前向计算,较慢但更准
Sparse EncoderSparseEncoder文本 → 词表维度的稀疏向量大规模稀疏检索、与稠密向量互补的混合检索稀疏表示、可解释、利于倒排索引
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_embeddingsexport_optimized_onnx_modelexport_dynamic_quantized_onnx_modelexport_static_quantized_openvino_modelmine_hard_negatives等工具函数,表明现代版本在推理后端(ONNX/OpenVINO)与量化方向上有完整支持,相关内容可继续阅读 docs/sentence_transformer/usage/efficiency.md。

Embedding Models:用 Sentence Transformer 计算稠密向量

Sentence Transformer(又称 bi-encoder)模型具有如下特性(见 docs/quickstart.rst):

  1. 针对文本、图像、音频或视频,计算固定大小的向量表示(embedding)
  2. 向量计算通常高效,而基于向量的相似度计算非常快
  3. 适用任务极广:语义文本相似度、语义搜索、聚类、分类、句对挖掘等;
  4. 常作为两阶段检索流程的第一步,由 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_sizeshow_progress_barconvert_to_numpyconvert_to_tensornormalize_embeddingsprecision(可选float32int8uint8binaryubinary,见同文件 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)模型的特点是:

  1. 针对成对的输入(通常是文本,也可以是图像等其他模态)计算一个相似度分数
  2. 相比 bi-encoder 通常准确率更高
  3. 更慢——因为它需要对每一对输入单独做前向计算,而不是对每个文本算一次;
  4. 因此实践中通常只对 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_fnpredict时作用于 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 的稀疏向量,其特性为:

  1. 计算稀疏向量表示,向量维度对应词表大小,大部分维度为 0;
  2. 因为稀疏,在大规模检索系统中效率极高(天然适配倒排索引);
  3. 比稠密向量更具可解释性——非零维度直接对应具体的 token;
  4. 与稠密向量互补,可构建同时发挥两者优势的混合检索系统。
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 风格)模型的特点:

  1. 对每个输入计算一串 token 级向量,而不是单个固定向量;
  2. 使用MaxSim 算子打分:对每个 query token,取它与所有 document token 相似度的最大值,再跨 query token 求和;
  3. 保留了token 级匹配信息(单向量模型会丢弃这些信息),通常检索更强,但索引体积更大;
  4. 近年基于 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_transformercross_encodersparse_encodermulti_vector_encoderbasebackendutil等模块组织,例如 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询