news 2026/9/20 14:26:04

sentence-transformers 预训练 CrossEncoder 模型全指南:从 MS MARCO 重排序到多模态 Reranker

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
sentence-transformers 预训练 CrossEncoder 模型全指南:从 MS MARCO 重排序到多模态 Reranker
  • 人工智能
  • NLP
  • Embedding
  • 微调

【免费下载链接】sentence-transformers

State-of-the-Art Embeddings, Retrieval, and Reranking

项目地址:https://gitcode.com/gh_mirrors/se/sentence-transformers
点击查看免费下载

本文基于仓库中的 docs/cross_encoder/pretrained_models.md,系统梳理 sentence-transformers 生态中官方与社区发布的预训练 CrossEncoder(交叉编码器 / Reranker)模型:涵盖模型库的获取方式、各任务方向的模型清单与评测指标、加载与推理代码,并结合 cross_encoder/model.py 等源码讲解predict/rank/activation_fn等核心机制。读完本文,你将能按任务(重排序、语义相似度、重复问题检测、NLI、多模态排序)正确选型预训练模型,并写出可直接运行的推理代码。

CrossEncoder(也称 Reranker)不产生单个句子的 embedding,而是把查询与候选文档拼接成对同时送入 Transformer,输出一个相关性分数。由于两段文本共享注意力计算,它的精度通常高于双塔式的 SentenceTransformer,代价是必须对每个 (query, document) 对单独计算一次,速度更慢。因此在实际检索系统中,CrossEncoder 几乎总是作为第二阶段,用于对召回结果做精细化重排序。

sentence-transformers 的 CrossEncoder 将查询与文档拼接后一次性送入 Transformer,输出 0~1 的相关性分数(图片来源:仓库 docs/img/CrossEncoder.png)。

快速上手:一行代码加载预训练模型

官方通过 CrossEncoder Hugging Face 组织发布了多种预训练模型,社区也贡献了大量公开模型。所有模型都可以用同一套接口加载与推理:

from sentence_transformers import CrossEncoder import torch # 加载 https://huggingface.co/cross-encoder/ms-marco-MiniLM-L6-v2 model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2", activation_fn=torch.nn.Sigmoid()) scores = model.predict([ ("How many people live in Berlin?", "Berlin had a population of 3,520,031 registered inhabitants in an area of 891.82 square kilometers."), ("How many people live in Berlin?", "Berlin is well known for its museums."), ]) # => array([0.9998173 , 0.01312432], dtype=float32)

从源码看,CrossEncoder 的构造函数会先按model_name_or_path判断加载方式:本地路径直接加载;否则尝试从 Hugging Face Hub 下载预训练模型。加载时它自动识别两类架构:

  • 序列分类架构Transformer(transformer_task="sequence-classification"),即 BERT / RoBERTa / DeBERTa 等带分类头的经典 encoder,直接输出分数,无需额外模块(见 model.py 中的_load_default_modules);
  • 生成式架构(CausalLM):以text-generation任务加载因果语言模型,并用 LogitScore 模块 取出最后一个 token 位置处"yes"/"no"的 logit 差值作为相关性分数(见 model.py 的 CausalLM 分支)。

CrossEncoder 的输入必须是成对的(文本对、图文对等多模态组合均可),输出是一个分数(回归,num_labels=1)或类别概率(分类,num_labels>1)。它不支持单句输入,也不为单个文本计算 embedding——这是它与 SentenceTransformer 最本质的区别。此外,predict的默认batch_size=32,且推理时会按输入长度排序分批(见 model.py 的_inference),在正式跑大数据量前,建议先在小样本上基准测试几个 batch size 以找到当前硬件上的最优值。

模型库与 Hugging Face 生态:如何找到合适的模型

官方与社区模型都托管在 Hugging Face Hub 上,搜索时需要注意 tag 规则:

  • 官方原版模型:CrossEncoder 官方组织下的模型,搜索sentence-transformers库标签并限定作者为cross-encoder即可;
  • 社区模型:搜索所有带sentence-transformers库标签且 pipeline 为text-ranking的模型。

一个容易混淆的细节:sentence-transformers库标签被全部四类模型(Sentence Transformer、CrossEncoder、Sparse Encoder、Multi-Vector Encoder)共用,而 CrossEncoder 是其中唯一没有单一干净过滤条件的类型。社区模型链接使用的text-rankingpipeline 标签只覆盖重排序模型,并不包括本页下方提到的分类模型(如 QNLI、STSbenchmark、Quora、NLI)。此外,用较新版本训练出的模型还会额外带有cross-encoder标签,不过本页列出的大部分模型早于该标签出现。相应地,sparsemulti-vector标签分别对应 Sparse Encoder 与 Multi-Vector Encoder 模型,而稠密 Sentence Transformer 模型构成了该库标签返回结果的主体。

下文按训练数据集/任务方向逐一介绍官方发布的预训练模型。所有表格中的指标均来自模型官方模型卡中报告的数据,请以对应模型页面的最新信息为准。

MS MARCO:面向搜索系统的重排序模型

MS MARCO Passage Retrieval 是一个大规模数据集,包含来自 Bing 搜索引擎的真实用户查询以及人工标注的相关文本段落。在此数据集上训练的模型非常适合作为搜索系统的Reranker

模型名NDCG@10(TREC DL 19)MRR@10(MS Marco Dev)Docs / Sec
cross-encoder/ms-marco-TinyBERT-L2-v269.8432.569000
cross-encoder/ms-marco-MiniLM-L2-v271.0134.854100
cross-encoder/ms-marco-MiniLM-L4-v273.0437.702500
cross-encoder/ms-marco-MiniLM-L6-v274.3039.011800
cross-encoder/ms-marco-MiniLM-L12-v274.3139.02960
cross-encoder/ms-marco-electra-base71.9936.41340

表中最常用的是加粗的cross-encoder/ms-marco-MiniLM-L6-v2:在精度(NDCG@10 74.30)与吞吐(约 1800 docs/sec)之间取得了很好的平衡。从表中可以清晰看到模型规模与速度的权衡:TinyBERT-L2 最快(9000 docs/sec)但精度最低;MiniLM-L12 与 L6 精度几乎持平但速度几乎减半;ELECTRA-base 精度反而不如 MiniLM 系列,速度也最慢。

重要提示:MS MARCO 系列模型默认输出的是logits(原始分数,合理取值范围约在 -10 到 10 之间),而非 0~1 的分数。若希望强制输出 0~1 之间的分数,需要显式传入activation_fn=torch.nn.Sigmoid()。注意这只会缩放分数数值,不会改变排序结果(见 docs/cross_encoder/usage/usage.rst 的说明)。

从源码看,activation_fn的默认解析逻辑位于 model.py 的get_default_activation_fn:优先读取模型配置config.sentence_transformers["activation_fn"](并兼容 v4.0 之前的sbert_ce_default_activation_function字段);若配置中不存在,则在num_labels == 1时回退到nn.Sigmoid(),否则使用nn.Identity()。这解释了为什么不同模型加载后默认输出分布不同——MS MARCO 模型通常保存了 Identity,而 STSb 等模型保存了 Sigmoid。

用 rank() 对候选文档排序

MS MARCO 模型最常见的用法是重排序。CrossEncoder.rank(query, documents)内部会把查询与每个文档拼成对、调用predict、按分数降序排序并返回{"corpus_id", "score", "text"}列表(见 model.py 的rank实现):

from sentence_transformers import 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 is well known for its museums.", "The urban area of Berlin comprised about 4.1 million people in 2014, making it the seventh most populous urban area in the European Union.", "The city of Paris had a population of 2,165,423 people within its administrative city limits as of January 1, 2019", ] ranks = model.rank(query, passages) for rank in ranks: print(f"{rank['score']:.2f}\t{passages[rank['corpus_id']]}")

注意两点:一是rank只对num_labels=1的模型生效,多标签分类模型需要改用predict(源码在 model.py 的rank开头做了校验);二是排序是分数相对大小决定的,与是否套 Sigmoid 无关。

Retrieve & Re-Rank 完整流水线

MS MARCO 模型在真实系统中的标准用法是两阶段检索流水线:先用 SentenceTransformer(Bi-Encoder)快速召回约 100 个候选,再用 CrossEncoder 精排。

Retrieve & Re-Rank 流程:Bi-Encoder 快速召回候选集,CrossEncoder 对候选逐一打分精排(图片来源:仓库 docs/img/InformationRetrieval.png)。

仓库提供了完整可运行的示例与 Notebook:examples/sentence_transformer/applications/retrieve_rerank/README.md,其中包括:

  • retrieve_rerank_simple_wikipedia.ipynb:以 Simple English Wikipedia 为文档库,Bi-Encoder 召回 + CrossEncoder 精排后返回 Top-5 段落;
  • in_document_search_crossencoder.py:段落规模较小时可跳过召回阶段,直接用 CrossEncoder 对全文段落打分(适合单文档内搜索)。

SQuAD(QNLI):问答段落相关性模型

QNLI 基于 SQuAD 数据集,由 GLUE Benchmark 提出:标注者针对维基百科段落编写了可由该段落回答的问题。这类模型对「段落能否回答该问题」输出更高分数,适合用于问答系统的证据段落筛选。

模型名QNLI dev 集准确率
cross-encoder/qnli-distilroberta-base90.96
cross-encoder/qnli-electra-base93.21

其中qnli-electra-base的准确率更高(93.21),适合对精度要求更高的问答场景;qnli-distilroberta-base则更轻量。

STSbenchmark:句子对语义相似度模型

STSbenchmark(Semantic Textual Similarity)模型输出 0~1 的分数,表示给定句子对的语义相似程度

from sentence_transformers import CrossEncoder model = CrossEncoder("cross-encoder/stsb-roberta-base") scores = model.predict([("It's a wonderful day outside.", "It's so sunny today!"), ("It's a wonderful day outside.", "He drove to work earlier.")]) # => array([0.60443085, 0.00240758], dtype=float32)
模型名STSbenchmark Test 性能
cross-encoder/stsb-TinyBERT-L485.50
cross-encoder/stsb-distilroberta-base87.92
cross-encoder/stsb-roberta-base90.17
cross-encoder/stsb-roberta-large91.47

从表中可以看到清晰的规模-精度梯度:从 TinyBERT-L4 的 85.50 到 roberta-large 的 91.47。与 MS MARCO 模型不同,STSb 模型保存了 Sigmoid 激活配置,因此默认就输出 0~1 的相似度分数。这类模型可直接用于小规模语料上的成对相似度打分,例如去重、文本匹配等场景。

Quora Duplicate Questions:重复问题检测模型

这类模型在 Quora 重复问题数据集 上训练,用法与 STSb 模型相同,输出 0~1 的分数表示两个问题是重复问题的概率。

模型名dev 集 Average Precision
cross-encoder/quora-distilroberta-base87.48
cross-encoder/quora-roberta-base87.80
cross-encoder/quora-roberta-large87.91

重要提示:这类模型不适用于问题相似度判断。例如 "How to learn Java?" 与 "How to learn Python?" 虽然语义上都是"如何学习编程",但它们不是重复问题,因此得分会很低。如果要做的是问题相似度(而非重复检测),应该使用在 Quora 数据集上训练的 SentenceTransformer(Bi-Encoder)模型,其相似度结果会更有意义。

NLI:自然语言推理模型

NLI(Natural Language Inference)模型回答的问题是:给定两个句子,它们是矛盾(contradiction)蕴含(entailment)还是中性(neutral)关系?以下模型在 SNLI 和 MultiNLI 数据集上训练:

模型名MNLI mismatched 集准确率
cross-encoder/nli-deberta-v3-base90.04
cross-encoder/nli-deberta-base88.08
cross-encoder/nli-deberta-v3-xsmall87.77
cross-encoder/nli-deberta-v3-small87.55
cross-encoder/nli-roberta-base87.47
cross-encoder/nli-MiniLM2-L6-H76886.89
cross-encoder/nli-distilroberta-base83.98

NLI 模型是多标签分类模型(num_labels=3),因此predict返回每个类别的 logits,需要配合argmax映射为标签:

from sentence_transformers import CrossEncoder model = CrossEncoder("cross-encoder/nli-deberta-v3-base") scores = model.predict([ ("A man is eating pizza", "A man eats something"), ("A black race car starts up in front of a crowd of people.", "A man is driving down a lonely road."), ]) # Convert scores to labels label_mapping = ["contradiction", "entailment", "neutral"] labels = [label_mapping[score_max] for score_max in scores.argmax(axis=1)] # => ['entailment', 'contradiction']

从源码角度补充一个细节:当num_labels > 1时,predict支持apply_softmax=True参数,对每个样本的各类别分数做 softmax 使其和为 1(见 model.py 的_inference);不传时输出原始 logits,argmax即可得到类别索引。这也是 NLI 场景的标准写法。

Multimodal Rerankers:跨模态重排序模型

多模态 Reranker 可以对不同模态组合的输入对打分,例如「文本查询 × 图片文档」「图片查询 × 文本候选」等,覆盖图像、视频、音频与文本。从源码结构看,这类模型与纯文本的 CausalLM CrossEncoder 使用相同的模块化架构——Transformer+LogitScore——区别仅在于底层 backbone 换成了能通过 chat template 同时处理图像与文本的视觉语言模型(见 docs/cross_encoder/usage/usage.rst 与 LogitScore 源码)。

加载模型后,可以用model.modalities属性列出支持的全部模态,用model.supports(...)检查某个模态或模态组合是否受支持:

from sentence_transformers import CrossEncoder model = CrossEncoder("Qwen/Qwen3-VL-Reranker-2B") # List all supported modalities print(model.modalities) # ['text', 'image', 'video', 'message'] # Check for a specific modality print(model.supports("image")) # True print(model.supports(("image", "text"))) # True

仓库列出的一些社区多模态 Reranker 包括:

  • Qwen/Qwen3-VL-Reranker-2B
  • Qwen/Qwen3-VL-Reranker-8B
  • nvidia/llama-nemotron-rerank-vl-1b-v2
  • jinaai/jina-reranker-m0

多模态 Reranker 的文档输入可以是图片 URL、本地文件路径、纯文本,甚至是「文本 + 图片」的组合字典(详见 docs/input_formats.rst 对输入表示、元数据与批处理的定义)。推理与调优资源同样齐全:使用示例见 Cross Encoder > Usage,训练脚本位于 examples/cross_encoder/training/multimodal/,其中展示了两种多模态训练架构:

  • Any-to-Any + LogitScore(training_doodles_any_to_any.py):以transformer_task="any-to-any"加载带 LM head 的完整因果语言模型,用生成下一个 token 的 log-odds 作为相关性分数,精度高但显存占用大;
  • Feature Extraction + Pooling + Dense(training_doodles_feature_extraction.py):只加载 base 模型(不带 LM head),用lasttoken池化加 Dense 投影得到分数,显存占用更省,且 Dense 层权重可用embed("1") - embed("0")初始化以近似 LogitScore 行为。

两种方案在 doodles 数据集上都使用BinaryCrossEntropyLoss配合 1:4 的正负样本比例与多数据集训练,产出可比较的结果;大模型场景下若 GPU 显存紧张,优先考虑 Feature Extraction 方案。

更多社区模型推荐

除官方模型外,社区还贡献了大量高质量 Reranker,仓库文档收录的 notable 模型包括:

  • BAAI/bge-reranker-base
  • BAAI/bge-reranker-large
  • BAAI/bge-reranker-v2-m3
  • BAAI/bge-reranker-v2-gemma
  • BAAI/bge-reranker-v2-minicpm-layerwise
  • jinaai/jina-reranker-v1-tiny-en
  • jinaai/jina-reranker-v1-turbo-en
  • mixedbread-ai/mxbai-rerank-xsmall-v1
  • mixedbread-ai/mxbai-rerank-base-v1
  • mixedbread-ai/mxbai-rerank-large-v1
  • maidalun1020/bce-reranker-base_v1
  • Alibaba-NLP/gte-reranker-modernbert-base
  • Alibaba-NLP/gte-multilingual-reranker-base

其中gte-multilingual-reranker-base面向多语言场景,bge-reranker-v2-gemmaminicpm-layerwise属于生成式/分层推理类 Reranker。所有这些社区模型都可以用与官方模型完全相同的方式加载与调用(CrossEncoder("模型名")),只需注意部分模型同样需要配合activation_fn=torch.nn.Sigmoid()或其他激活来得到 0~1 分数。

选型建议小结

综合本页内容,可以按任务快速选型:

  1. 搜索系统重排序:首选 MS MARCO 系列的cross-encoder/ms-marco-MiniLM-L6-v2(精度/速度均衡),追求极致吞吐选MiniLM-L2-v2,追求精度上限选MiniLM-L12-v2,并结合 Retrieve & Re-Rank 示例搭建完整流水线;
  2. 问答证据段落筛选:QNLI 系列的qnli-electra-base
  3. 句子对语义相似度:STSb 系列的stsb-roberta-base/stsb-roberta-large
  4. 重复问题检测:Quora 系列的quora-roberta-base(注意不要将其误用于相似度判断);
  5. 自然语言推理:NLI 系列的nli-deberta-v3-base,输出需配合argmax映射为 contradiction / entailment / neutral 标签;
  6. 图文等跨模态排序:使用 Qwen3-VL-Reranker 等多模态模型,并用modalities/supports()确认模态支持。

所有模型统一通过sentence_transformers.CrossEncoder加载;predict适用于任意成对打分,rank适用于单查询对多文档的排序(仅限num_labels=1)。在动手前,请务必确认目标模型是否自带 Sigmoid 激活(观察输出是否在 0~1 区间),从而决定是否需要显式传入activation_fn

  • 人工智能
  • NLP
  • Embedding
  • 微调

【免费下载链接】sentence-transformers

State-of-the-Art Embeddings, Retrieval, and Reranking

项目地址:https://gitcode.com/gh_mirrors/se/sentence-transformers
点击查看免费下载

相关推荐

上一篇:Umi-OCR:完全免费离线OCR软件使用全攻略
下一篇:Windows系统优化神器:Chris Titus Tech WinUtil 5分钟快速上手完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 14:25:31

二叉搜索树(BST)原理与工程实践优化

1. 二叉搜索树基础认知二叉搜索树(Binary Search Tree,简称BST)是我在数据结构教学中最常使用的活教材。这种看似简单的树形结构,实际上蕴含着算法设计与性能优化的精髓。BST本质上是一棵满足特定排序性质的二叉树:对于…

作者头像 李华
网站建设 2026/9/20 14:21:46

内容型平台运营方法论:从供给到闭环的系统框架

简介:这是一份关于内容型平台运营底层逻辑的方法论文档,面向互联网产品运营、内容运营、产品经理及对平台机制感兴趣的研究者。资源系统梳理了平台运营的三个关键要素:内容、用户与分发模式,并结合B站、西瓜视频等真实平台案例&am…

作者头像 李华
网站建设 2026/9/20 14:20:41

DeepAgent 的 write_todos 规划与子 Agent 并行,模型接入改走 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 14:20:40

从零掌握Skill编写:SKILL.md规范、目录设计与实战技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华