首页
/ vLLM 打分(Scoring)模型实践指南:Cross-Encoder / Late-Interaction / Bi-Encoder 相似度计算与 Rerank 在线服务详解

vLLM 打分(Scoring)模型实践指南:Cross-Encoder / Late-Interaction / Bi-Encoder 相似度计算与 Rerank 在线服务详解

2026-09-06 19:05:41作者:段琳惟

本文以仓库文档 docs/models/pooling_models/scoring.md 为主体,结合 vllm/entrypoints/pooling/scoring/protocol.pyvllm/pooling_params.pyexamples/pooling/score 下的可运行示例,系统讲解 vLLM 如何为两段文本(query 与 document)计算相似度/相关性分数。

读完本篇,你将掌握:三种打分模型类型(score_type)的适用范围与计算函数;哪些开源 re-ranker / ColBERT / Embedding 模型可以直接或经 --convert classify 转换后使用;通过离线 API LLM.score 与在线 API(/score/rerank 等)完成单条、批量甚至图文多模态打分/重排序请求的完整实操方法,以及 Score Template 等高级特性的配置方式。

一、Scoring 能力定位:vLLM 在 RAG 中扮演的"打分"角色

Scoring 模型(打分模型)的设计目标非常单一:计算两段输入提示词(prompt)之间的相似度分数。它不生成文本,而是输出一个可比较的标量,最常见的落地场景是 RAG 检索管线的**重排序(rerank)**环节——先用廉价的召回方式取回若干候选文档,再交给打分模型精细打分排序。

值得注意的是 vLLM 对该能力的边界有清晰界定:vLLM 只承担 RAG 管线中模型推理这一部分(如向量生成与重排序);更上层的 RAG 编排应交给 LangChain 等集成框架。同时,从 docs/models/pooling_models/README.md 的说明看,pooling 模型在 vLLM 中目前主要定位为便利性支持,不承诺相对直接使用 Hugging Face Transformers / Sentence Transformers 有性能提升。

1.1 三种 Score Type 及其 Pooling 任务

打分能力横跨三类模型,恰好复用了 vLLM pooling 体系中三个既有的 pooling 任务,可以用一张表概括(这也是文档的 Summary 表):

Score Type Pooling Task Scoring Function 说明
cross-encoder classify(注意点) linear classifier(线性分类器) 两段文本拼接后一起编码,逐对计算相关度
late-interaction token_embed late interaction (MaxSim) 双塔分别产出 token 向量,再按 token 最大化匹配求和
bi-encoder embed cosine similarity(余弦相似度) 双塔独立编码为单个向量,直接算余弦相似度

下图直观地展示了三种打分函数的工作原理(来源:docs/assets/models/pooling_models/score_types.svg):

vLLM 三种 Score Type(cross-encoder / late-interaction / bi-encoder)的打分计算方式示意图

三个核心结论需要明确:

  • 离线 APILLM.score(由 PoolingOfflineMixin.score 提供,输出句子对之间的相似度分数)。
  • 在线 APIScore API/score/v1/score)与 Cohere Rerank API/rerank/v1/rerank/v2/rerank)。
  • 一个硬性前提cross-encoder 打分能力建立在 classify 任务之上,只有当分类模型输出的 num_labels 等于 1 时,它才能作为打分模型使用并启用打分 API。这也解释了为什么 re-ranker 本质上是"输出维度为 1 的二分类器"。

二、支持的模型清单与加载方式

2.1 Cross-Encoder(re-ranker)模型

Cross-encoder(也叫 re-ranker)是分类模型的一个子集:输入两段 prompt,输出 num_labels == 1 的标量分数。在 vLLM 中,它默认走 classify pooling 任务,后端把两段文本拼成一个输入序列进行单次编码。

纯文本模型

下表总结了当前支持的纯文本 cross-encoder 架构、代表模型、所需 Score Template、LoRA 与流水线并行(PP)支持情况。其中 <sup>C</sup> 表示该架构属于生成式模型,需通过 --convert classify 自动转换为分类模型(转换机制详见 Pooling 模型总览文档中的 Model Conversion 一节)。

Architecture Models Example HF Models Score template LoRA PP
BertForSequenceClassification BERT-based cross-encoder/ms-marco-MiniLM-L-6-v2 N/A
GemmaForSequenceClassification Gemma-based BAAI/bge-reranker-v2-gemma bge-reranker-v2-gemma.jinja
GteNewForSequenceClassification mGTE-TRM Alibaba-NLP/gte-multilingual-reranker-base N/A
LlamaBidirectionalForSequenceClassificationC Llama-based(双向注意力) nvidia/llama-nemotron-rerank-1b-v2 nemotron-rerank.jinja
ModernBertForSequenceClassification ModernBERT-based Alibaba-NLP/gte-reranker-modernbert-base N/A
Qwen2ForSequenceClassificationC Qwen2-based mixedbread-ai/mxbai-rerank-base-v2 mxbai_rerank_v2.jinja
Qwen3ForSequenceClassificationC Qwen3-based tomaarsen/Qwen3-Reranker-0.6B-seq-clsQwen/Qwen3-Reranker-0.6B qwen3_reranker.jinja
RobertaForSequenceClassification RoBERTa-based cross-encoder/quora-roberta-base N/A
XLMRobertaForSequenceClassification XLM-RoBERTa-based BAAI/bge-reranker-v2-m3 N/A
*ModelC*ForCausalLMC 生成式模型 N/A N/A * *

其中 * 表示特性支持与原模型一致(即把任意生成式大模型转成二分类打分头使用)。

关于加载注意点,仓库文档明确给出了几条实操指引:

  1. 部分模型对 prompt 格式有硬性要求,需要配套的 Score Template。每个 HF 示例模型对应的模板都存放在 examples/pooling/score/template,并提供了 离线在线 两种示例。
  2. 官方原始 BAAI/bge-reranker-v2-gemma(其仓库权重本身没有声明为 GemmaForSequenceClassification 架构)需要用 --hf_overrides 强制指定架构、分类头取词位置和打分后处理方法:
vllm serve BAAI/bge-reranker-v2-gemma --hf_overrides '{"architectures": ["GemmaForSequenceClassification"],"classifier_from_token": ["Yes"],"method": "no_post_processing"}'
  1. 第二代 GTE(mGTE-TRM)架构命名:由于 Hugging Face 上该模型家族名为 NewForSequenceClassification,过于通用,需要显式指定:
vllm serve Alibaba-NLP/gte-multilingual-reranker-base --hf-overrides '{"architectures": ["GteNewForSequenceClassification"]}'
  1. 官方原始 mixedbread-ai/mxbai-rerank-v2:通过 classifier_from_token 指定取 "0""1" 两个位置的 token,并用 from_2_way_softmax 方式把二路 softmax 分数规约为相关性:
vllm serve mixedbread-ai/mxbai-rerank-base-v2 --hf_overrides '{"architectures": ["Qwen2ForSequenceClassification"],"classifier_from_token": ["0", "1"], "method": "from_2_way_softmax"}'
  1. 官方原始 Qwen3-Reranker:需要同时打开 is_original_qwen3_reranker 开关,完整用法可参考 qwen3_reranker_offline.pyqwen3_reranker_online.py
vllm serve Qwen/Qwen3-Reranker-0.6B --hf_overrides '{"architectures": ["Qwen3ForSequenceClassification"],"classifier_from_token": ["no", "yes"],"is_original_qwen3_reranker": true}'

从源码角度可以印证这些 --hf_overrides 的语义:例如 examples/pooling/score/using_template_offline.py 中维护了一张"模型名 → overrides"的映射表,bge-reranker-v2-gemmaQwen3-Rerankermxbai-rerank-* 等生成式权重正是在加载时通过 get_hf_overrides(model) 被"翻译"成分类模型,再配合 runner="pooling" 进入打分流程。

多模态模型

跨编码器家族也扩展到了图文多模态 re-ranker。多模态输入的相关规范见 支持的多模态语言模型列表,其输入类型标记中 T 为文本、I 为图像、V 为视频、E+ 表示可多个。支持矩阵如下:

Architecture Models Inputs Example HF Models LoRA PP
JinaVLForSequenceClassification JinaVL-based T + IE+ jinaai/jina-reranker-m0
LlamaNemotronVLForSequenceClassification Llama Nemotron Reranker + SigLIP T + IE+ nvidia/llama-nemotron-rerank-vl-1b-v2
Qwen3VLForSequenceClassification Qwen3-VL-Reranker T + IE+ + VE+ Qwen/Qwen3-VL-Reranker-2B

多模态 re-ranker 同样存在"官方权重需 overrides 才能按分类架构加载"的情况。以 Qwen3-VL-Reranker 为例:

vllm serve Qwen/Qwen3-VL-Reranker-2B --hf_overrides '{"architectures": ["Qwen3VLForSequenceClassification"],"classifier_from_token": ["no", "yes"],"is_original_qwen3_reranker": true}'

仓库文档还提醒了一个工程细节:Qwen3-VL 官方使用 qwen_vl_utils 做图像预处理,而 vLLM 使用 transformersvideo_processing_qwen3_vl,因此推理结果与官方 Hugging Face 仓库示例相比会存在轻微数值差异——这属于预期的、可接受的实现差异,而非 bug。

2.2 Late-Interaction 模型

任何支持 token_embed(token 级嵌入)任务的模型,都可以通过计算两段输入的 late interaction(MaxSim) 来产出相似度分数——这是 ColBERT / ColQwen / ColModernBERT 一类"后交互"检索模型的核心思想,具体做法是逐 query token 与 document token 求最大相似度后累加。模型清单与 embed 类似,凡是支持 token embedding 的模型均可直接使用打分 API,详见 Token Embedding 用法。仓库在 examples/pooling/score 下提供了 colbert_rerank_online.pycolqwen3_rerank_online.py 等可直接运行的 ColBERT 家族示例。

2.3 Bi-Encoder 模型

任何支持 embed(序列级嵌入)任务的模型,都可以通过计算两段输入 embedding 的余弦相似度打分。这类打分的典型使用方式就是传统双塔向量模型 + 向量检索库的粗排/精排。模型清单详见 Embedding 用法

需要强调的是:与 cross-encoder 不同,late-interaction 与 bi-encoder 的打分没有 Score Template 参与(详情见本文第六节),也不限制 num_labels

三、离线推理:Pooling 参数与 LLM.score

3.1 仅对 cross-encoder 生效的 Pooling 参数

离线打分复用 PoolingParams。下面的 pooling 参数 中,打分相关的核心参数仅对 cross-encoder 模型生效,对 late-interaction 与 bi-encoder 无效(这两类分别走 token_embed / embed 的参数逻辑):

# common-pooling-params(来自 vllm/pooling_params.py)
use_activation: bool | None = None   # 是否对 pooler 输出应用激活函数
                                     # None 表示使用 pooler 默认值,绝大多数情况为 True

vllm/pooling_params.py 源码可以看到 PoolingParams.valid_parametersclassify 任务只接受 ["use_activation"];同时 verify() 内部会把显式传入的参数与 pooler_config 做合并解析。此外要注意:历史版本中曾被广泛使用的 normalize 参数已被移除,统一由 use_activation 表达(在线协议层遇到 normalize 会直接抛出 VLLMValidationError,见 vllm/entrypoints/pooling/base/protocol.pyreject_removed_pooling_parameters)。

对于 re-ranker(本质是二分类打分头)而言,use_activation 决定输出的是激活后的 0~1 概率分数还是裸 logits——默认会按模型的 problem_type / label 数量选择 sigmoid(二分类场景),这是决定重排序结果可比性的关键开关。

3.2 LLM.score 最小可用示例

LLM.score 直接输出句子对(query-document pair)的相似度分数。使用 cross-encoder 模型时必须显式指定 runner="pooling"

from vllm import LLM

llm = LLM(model="BAAI/bge-reranker-v2-m3", runner="pooling")
(output,) = llm.score(
    "What is the capital of France?",
    "The capital of Brazil is Brasilia.",
)

score = output.outputs.score
print(f"Score: {score}")

上面的两段文本构成一个"句子对",返回单个分数。更完整、支持多候选文档的批量示例见 examples/basic/offline_inference/score.py(其内部就是 llm.score(query, documents) 后逐条读取 output.outputs.score 并打印)。从源码调用链看,LLM.score 会把请求转换成 PoolingParams(task="classify", use_activation=...) 提交给引擎,即打分在任务层复用的正是 classification 推理路径——这与"只有 num_labels==1 的分类模型才能打分"的约束在实现上完全自洽(见 protocol.py 中的 to_pooling_params)。

对于需要特定 prompt 格式的 re-ranker(如 Gemma / Qwen3 / mxbai 系),离线调用需额外传入对应模板,例如:

llm.score(
    query,
    documents,
    chat_template=get_chat_template(args.model),   # 从 jinja 文件读取的模板字符串
)

模型名与模板的映射可复用 using_template_offline.py 中维护的映射表 或直接使用仓库预置的模板文件(参见 examples/pooling/score/template)。

四、在线服务:Score API 与 Cohere Rerank API

通过 vllm serve 拉起一个 cross-encoder(或其他支持打分)的 pooling 模型后,即可获得与离线 LLM.score 语义一致、但走 HTTP 的两套在线接口。文档在 在线服务章节 中说明了其 chat template 相关配置方式。

4.1 Score API(/score/v1/score

Score API 与 LLM.score 一一对应,用于计算两段输入之间的相似度分数。请求体的全部参数定义在 vllm/entrypoints/pooling/scoring/protocol.py(Score 相关)与 vllm/entrypoints/pooling/base/protocol.py(pooling 通用参数),汇总如下:

Pooling 通用参数(pooling-common-params + pooling-common-extra-params

参数 类型 / 默认值 说明
model str | None 模型名(通常必须指定)
user str | None 终端用户名(用于监控/审计)
truncate_prompt_tokens int | None(≥ -1) 截断到前 N 个 token(拼接后的整体)
padding "max_length" | "do_not_pad" | None 是否按最大长度 pad。像 SigLIP 这类"定长训练且无 attention mask"的模型必须用 max_length,否则 embedding 不可比较
truncation_side "left" | "right" | None 截断方向:right 保留前 N 个 token,left 保留后 N 个 token
request_id str 请求 ID,不传则服务端随机生成,并贯穿推理与响应
priority int(默认 0) 请求优先级(数值越小越早处理),非 0 优先级要求服务端启用了优先级调度
mm_processor_kwargs dict | None 透传给 HF processor 的额外参数
cache_salt str | None 前缀缓存加盐字符串,用于多租户下防 prompt 猜测攻击

分类/打分通用参数

参数 类型 / 默认值 说明
use_activation bool | None 是否对 pooler 输出应用激活;None 走 pooler 默认(多为 True)
max_tokens_per_query int(默认 0) 每条 query 的最大 token 数,超长截断;0 表示不按 query 级别截断
max_tokens_per_doc int(默认 0) 每条 document 的最大 token 数,超长截断;0 表示不按 document 级别截断
instruction str | None 通过 chat template 前置到每个待打分 pair 的任务指令;等价于传 chat_template_kwargs={'instruction': ...}
chat_template_kwargs dict | None 传给 chat/score template 渲染器的额外关键字参数

Score 请求体参数(score-request-params

参数 类型 说明
queries ScoreInput | list[ScoreInput] 查询文本(或其列表)
documents ScoreInput | list[ScoreInput] 候选文档文本(或其列表)

从协议定义看,ScoreRequest 是多种请求体形状的联合类型(详见 protocol.py):除了最常用的 queries + documents,还兼容 queries + itemsdata_1 + data_2text_1 + text_2 等字段命名变体,方便不同生态的客户端直接对接。

另外,instruction 在请求校验阶段会被合并进 chat_template_kwargs(显式写在 chat_template_kwargs 中的同名键优先级更高,见 _merge_instruction_into_kwargs),因此在线请求可以使用便捷字段 instruction,模板内统一通过 chat_template_kwargs['instruction'] 访问。

场景一:单条推理(query/document 各传一个字符串)

curl -X 'POST' \
  'http://127.0.0.1:8000/score' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "BAAI/bge-reranker-v2-m3",
  "encoding_format": "float",
  "queries": "What is the capital of France?",
  "documents": "The capital of France is Paris."
}'

响应(object: "list",每个元素 object: "score"):

{
  "id": "score-request-id",
  "object": "list",
  "created": 693447,
  "model": "BAAI/bge-reranker-v2-m3",
  "data": [
    {
      "index": 0,
      "object": "score",
      "score": 1
    }
  ],
  "usage": {}
}

场景二:批量推理——单个 query × 多个 documents(笛卡尔式逐对打分)

queries 传字符串、documents 传列表时,会以 querydocuments 中每一个元素分别构造成句子对,总对数 = len(documents)

curl -X 'POST' \
  'http://127.0.0.1:8000/score' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "BAAI/bge-reranker-v2-m3",
  "queries": "What is the capital of France?",
  "documents": [
    "The capital of Brazil is Brasilia.",
    "The capital of France is Paris."
  ]
}'

响应中的两个分数按 documents 顺序对齐:完全匹配的 pair 分数为 1,不匹配的 pair 分数接近 0(0.00109…)。

{
  "id": "score-request-id",
  "object": "list",
  "created": 693570,
  "model": "BAAI/bge-reranker-v2-m3",
  "data": [
    { "index": 0, "object": "score", "score": 0.001094818115234375 },
    { "index": 1, "object": "score", "score": 1 }
  ],
  "usage": {}
}

场景三:批量推理——query 列表 × documents 列表(zip 式逐对打分)

queriesdocuments 都是列表时,第 i 个 pair 由 queries[i]documents[i] 构成(行为类似 zip()),总对数同样为 len(documents)

curl -X 'POST' \
  'http://127.0.0.1:8000/score' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "BAAI/bge-reranker-v2-m3",
  "encoding_format": "float",
  "queries": [
    "What is the capital of Brazil?",
    "What is the capital of France?"
  ],
  "documents": [
    "The capital of Brazil is Brasilia.",
    "The capital of France is Paris."
  ]
}'

响应按 query/document 下标一一对应,两对都匹配因此分数均为 1:

{
  "id": "score-request-id",
  "object": "list",
  "created": 693447,
  "model": "BAAI/bge-reranker-v2-m3",
  "data": [
    { "index": 0, "object": "score", "score": 1 },
    { "index": 1, "object": "score", "score": 1 }
  ],
  "usage": {}
}

提示:从参数语义看,"多 query 单 document"这种反向组合并不在 queries/documents 列表语义内,如需对多个 query 重排同一批文档,应分别发请求或使用 rerank 语义的接口。

场景四:多模态打分(图片参与比对)

当打分的 document 是图片时,把字符串 documents 换成带 content 结构的字典列表,content 内每个元素与 Chat Completions 的多模态消息一致(type: "image_url" 等)。由于该请求 schema 不是 OpenAI 客户端定义的,文档推荐用底层 requests 直发:

import requests

response = requests.post(
    "http://localhost:8000/v1/score",
    json={
        "model": "jinaai/jina-reranker-m0",
        "queries": "slm markdown",
        "documents": [
            {
                "content": [
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": "https://raw.githubusercontent.com/jina-ai/multimodal-reranker-test/main/handelsblatt-preview.png"
                        },
                    }
                ],
            },
            {
                "content": [
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": "https://raw.githubusercontent.com/jina-ai/multimodal-reranker-test/main/handelsblatt-preview.png"
                        },
                    }
                ]
            },
        ],
    },
)
response.raise_for_status()
response_json = response.json()
print("Scoring output:", response_json["data"][0]["score"])
print("Scoring output:", response_json["data"][1]["score"])

部署该服务使用 vllm serve jinaai/jina-reranker-m0 即可。完整的多模态 Score / Rerank 示例见 vision_score_api_online.pyvision_rerank_api_online.py

4.2 Cohere Rerank API(/rerank/v1/rerank/v2/rerank

Rerank 接口在协议层面兼容 Jina AI 的 rerank 接口Cohere 的 rerank 接口,从而可以直接对接这两个生态中的开源工具链。可直接运行的客户端示例见 rerank_api_online.pycohere_rerank_client.py

其参数 = pooling 通用参数(modelusertruncate_prompt_tokens 等)+ classify/打分通用参数(use_activationmax_tokens_per_querymax_tokens_per_docinstructionchat_template_kwargs)+ 下面 rerank 专用参数:

参数 类型 / 默认值 说明
query ScoreInput 单个查询文本
documents ScoreInput | list[ScoreInput] 待重排的候选文档
top_n int(默认 0,≥ 0) 返回最相关的前 N 条;可选,不传时默认等于 documents 的长度,即返回全部

与 Score API 的关键差异在于响应结构:结果按相关度降序排列(即已自动完成重排序),且每个结果携带 index 字段用于还原其在原 documents 中的位置:

curl -X 'POST' \
  'http://127.0.0.1:8000/v1/rerank' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "BAAI/bge-reranker-base",
  "query": "What is the capital of France?",
  "documents": [
    "The capital of Brazil is Brasilia.",
    "The capital of France is Paris.",
    "Horses and cows are both animals"
  ]
}'

响应中巴黎文案被排到第一位(index: 1relevance_score ≈ 0.9985),巴西文案(index: 0)与完全无关的动物文案被排到后面:

{
  "id": "rerank-fae51b2b664d4ed38f5969b612edff77",
  "model": "BAAI/bge-reranker-base",
  "usage": {
    "total_tokens": 56
  },
  "results": [
    {
      "index": 1,
      "document": { "text": "The capital of France is Paris." },
      "relevance_score": 0.99853515625
    },
    {
      "index": 0,
      "document": { "text": "The capital of Brazil is Brasilia." },
      "relevance_score": 0.0005860328674316406
    }
  ]
}

Rerank 响应模型(RerankResponse)与 Score 响应模型(ScoreResponse)的完整字段定义都可以在 scoring/protocol.py 中查到:RerankResultindex / document / relevance_score,其中 document 还可携带多模态内容(RerankDocument.text / RerankDocument.multi_modal),这保证了图文 re-ranker 同样能走 Rerank 接口。

五、更多可直接运行的示例

除上文已出现的文件外,仓库在 examples/pooling/score 目录下还维护了覆盖三种 score type 的完整示例集,可作为后续二次开发的起点:

  • qwen3_reranker_offline.py / qwen3_reranker_online.py:Qwen3-Reranker 的离/在线完整用法;
  • using_template_offline.py / using_template_online.py:演示为不同 re-ranker 绑定对应 Score Template;
  • rerank_api_online.py / cohere_rerank_client.py:Rerank API 的调用与 Cohere 兼容客户端示例;
  • colbert_rerank_online.pycolmodernvbert_rerank_online.pycolqwen3_rerank_online.pycolqwen3_5_rerank_online.py:late-interaction(ColBERT 系)打分示例;
  • vision_score_api_online.py / vision_rerank_api_online.py / vision_reranker_offline.py:多模态 re-ranker 的 Score / Rerank 调用;
  • convert_model_to_seq_cls.py:把生成式 LLM 权重转换为 sequence-classification 权重的参考脚本。

六、特性详解:Score Template 与 use_activation

6.1 特性边界:cross-encoder 与分类模型对齐

由于 cross-encoder 本质上是"接受两段输入、输出 num_labels == 1"的分类模型,其支持的特性与(sequence)分类完全一致;late-interaction / bi-encoder 的特性则分别对齐 token_embed / embed。分类支持的完整特性列表见 Classification 用法文档

6.2 Score Template:只在 cross-encoder 上生效

Score Template 仅对 cross-encoder 模型生效;若你用一个 embedding(bi-encoder)模型来打分,vLLM 不会应用 score template——因为双塔各自独立编码、两段文本不会拼成一个序列。

正如部分模型需要特定 prompt 格式,打分模型同样可以自定义模板,方式与 Chat Template 相同:通过 --chat-template 参数指定(参见 在线服务的 Chat Template 章节)。

Score Template 的输入也是 messages 列表,但与聊天不同,每条 message 的 role 只可能是 "query""document"。对于常规的 point-wise cross-encoder,模板应恰好收到两条 message:一条 query、一条 document。文档强烈建议用 Jinja 的 selectattr 按语义角色取内容,而不是用 messages[0] / messages[1] 按下标访问:

  • Query{{ (messages | selectattr("role", "eq", "query") | first).content }}
  • Document{{ (messages | selectattr("role", "eq", "document") | first).content }}

这种写法更健壮:一方面按语义角色定位内容、不依赖消息顺序;另一方面,未来即使 messages 中新增了其他类型的消息(例如多模态 content 扩展或系统指令),模板也不会因为下标错位而取错内容。

参考模板文件可直接阅读 examples/pooling/score/template/nemotron-rerank.jinja;仓库还预置了 bge-reranker-v2-gemma.jinjaqwen3_reranker.jinjaqwen3_vl_reranker.jinjamxbai_rerank_v2.jinjanemotron-vl-rerank.jinja 等模板文件,分别对应前文各型号 re-ranker。

6.3 激活函数开关:use_activation

use_activation 参数(离线为 PoolingParams.use_activation,在线为请求体的 use_activation)用来启用/禁用 pooler 输出的激活(对于 re-ranker 即 sigmoid/softmax 打分头)。该参数同样只对 cross-encoder 模型有效,取值为 None(跟随模型默认,通常为启用)或显式布尔值。设置 use_activation=False 时,打分 API 将返回未经激活的裸 logits,适合需要自行后处理分数的高级用法。

七、与任务/API 演进相关的注意事项

最后整理两条与打分模型相关的兼容性边界,避免在实际接入时踩坑:

  1. score 任务本身已被移除:在 vLLM v0.21 及以后,打分统一建立在 classify 任务之上(num_labels == 1 的分类模型才开放打分 API)。不要在 PoolerConfig(task=...) / --pooler-config.task 中试图指定一个独立的 score 任务,应使用 classify
  2. 模型 runner 一般无需手动指定vllm serve / LLM(...)--runner auto 会自动识别 pooling 模型;仅在自动识别失效时才需要显式 runner="pooling"。若模型不实现 pooling 接口,可借助 --convert <type>(如 classifyembed)按架构名自动转换——这也是前文大量 re-ranker 示例能直接服务的前提(转换细节见 Pooling 模型总览文档的 Model Conversion 小节)。

总而言之,vLLM 的 Scoring 能力是一套"复用分类/嵌入基础设施、向上层 RAG 提供统一打分语义"的完整方案:跨编码器负责逐对精排、双塔/后交互负责向量化粗排,三者通过统一的 LLM.score 离线接口与 /score/rerank 在线接口对外暴露。结合本文的模型加载 overrides、参数表和示例脚本,即可在自己的检索增强应用中快速接入一条高性能的重排序链路。

登录后查看全文
热门项目推荐
相关项目推荐