十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

vLLM 打分(Scoring)模型实践指南:Cross-Encoder / Late-Interaction / Bi-Encoder 相似度计算与 Rerank 在线服务详解 vLLM 打分Scoring模型实践指南Cross-Encoder / Late-Interaction / Bi-Encoder 相似度计算与 Rerank 在线服务详解【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm本文以仓库文档 docs/models/pooling_models/scoring.md 为主体结合 vllm/entrypoints/pooling/scoring/protocol.py、vllm/pooling_params.py 及 examples/pooling/score 下的可运行示例系统讲解 vLLM 如何为两段文本query 与 document计算相似度/相关性分数。读完本篇你将掌握三种打分模型类型score_type的适用范围与计算函数哪些开源 re-ranker / ColBERT / Embedding 模型可以直接或经--convert classify转换后使用通过离线 APILLM.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 TypePooling TaskScoring Function说明cross-encoderclassify注意点linear classifier线性分类器两段文本拼接后一起编码逐对计算相关度late-interactiontoken_embedlate interaction (MaxSim)双塔分别产出 token 向量再按 token 最大化匹配求和bi-encoderembedcosine similarity余弦相似度双塔独立编码为单个向量直接算余弦相似度下图直观地展示了三种打分函数的工作原理来源docs/assets/models/pooling_models/score_types.svg三个核心结论需要明确离线 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-Encoderre-ranker模型Cross-encoder也叫 re-ranker是分类模型的一个子集输入两段 prompt输出num_labels 1的标量分数。在 vLLM 中它默认走classifypooling 任务后端把两段文本拼成一个输入序列进行单次编码。纯文本模型下表总结了当前支持的纯文本 cross-encoder 架构、代表模型、所需 Score Template、LoRA 与流水线并行PP支持情况。其中supC/sup表示该架构属于生成式模型需通过--convert classify自动转换为分类模型转换机制详见 Pooling 模型总览文档中的 Model Conversion 一节。ArchitectureModelsExample HF ModelsScore templateLoRAPPBertForSequenceClassificationBERT-basedcross-encoder/ms-marco-MiniLM-L-6-v2等N/AGemmaForSequenceClassificationGemma-basedBAAI/bge-reranker-v2-gemmabge-reranker-v2-gemma.jinja✅✅GteNewForSequenceClassificationmGTE-TRMAlibaba-NLP/gte-multilingual-reranker-base等N/ALlamaBidirectionalForSequenceClassificationCLlama-based双向注意力nvidia/llama-nemotron-rerank-1b-v2等nemotron-rerank.jinja✅✅ModernBertForSequenceClassificationModernBERT-basedAlibaba-NLP/gte-reranker-modernbert-base等N/AQwen2ForSequenceClassificationCQwen2-basedmixedbread-ai/mxbai-rerank-base-v2等mxbai_rerank_v2.jinja✅✅Qwen3ForSequenceClassificationCQwen3-basedtomaarsen/Qwen3-Reranker-0.6B-seq-cls、Qwen/Qwen3-Reranker-0.6B等qwen3_reranker.jinja✅✅RobertaForSequenceClassificationRoBERTa-basedcross-encoder/quora-roberta-base等N/AXLMRobertaForSequenceClassificationXLM-RoBERTa-basedBAAI/bge-reranker-v2-m3等N/A*ModelC、*ForCausalLMC等生成式模型N/AN/A**其中*表示特性支持与原模型一致即把任意生成式大模型转成二分类打分头使用。关于加载注意点仓库文档明确给出了几条实操指引部分模型对 prompt 格式有硬性要求需要配套的 Score Template。每个 HF 示例模型对应的模板都存放在 examples/pooling/score/template并提供了 离线 与 在线 两种示例。官方原始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}第二代 GTEmGTE-TRM架构命名由于 Hugging Face 上该模型家族名为NewForSequenceClassification过于通用需要显式指定vllm serve Alibaba-NLP/gte-multilingual-reranker-base --hf-overrides {architectures: [GteNewForSequenceClassification]}官方原始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}官方原始Qwen3-Reranker需要同时打开is_original_qwen3_reranker开关完整用法可参考 qwen3_reranker_offline.py 与 qwen3_reranker_online.pyvllm 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-gemma、Qwen3-Reranker、mxbai-rerank-*等生成式权重正是在加载时通过get_hf_overrides(model)被翻译成分类模型再配合runnerpooling进入打分流程。多模态模型跨编码器家族也扩展到了图文多模态 re-ranker。多模态输入的相关规范见 支持的多模态语言模型列表其输入类型标记中T为文本、I为图像、V为视频、E表示可多个。支持矩阵如下ArchitectureModelsInputsExample HF ModelsLoRAPPJinaVLForSequenceClassificationJinaVL-basedT IEjinaai/jina-reranker-m0等✅✅LlamaNemotronVLForSequenceClassificationLlama Nemotron Reranker SigLIPT IEnvidia/llama-nemotron-rerank-vl-1b-v2Qwen3VLForSequenceClassificationQwen3-VL-RerankerT IE VEQwen/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 使用transformers的video_processing_qwen3_vl因此推理结果与官方 Hugging Face 仓库示例相比会存在轻微数值差异——这属于预期的、可接受的实现差异而非 bug。2.2 Late-Interaction 模型任何支持token_embedtoken 级嵌入任务的模型都可以通过计算两段输入的late interactionMaxSim来产出相似度分数——这是 ColBERT / ColQwen / ColModernBERT 一类后交互检索模型的核心思想具体做法是逐 query token 与 document token 求最大相似度后累加。模型清单与 embed 类似凡是支持 token embedding 的模型均可直接使用打分 API详见 Token Embedding 用法。仓库在 examples/pooling/score 下提供了 colbert_rerank_online.py、colqwen3_rerank_online.py 等可直接运行的 ColBERT 家族示例。2.3 Bi-Encoder 模型任何支持embed序列级嵌入任务的模型都可以通过计算两段输入 embedding 的余弦相似度打分。这类打分的典型使用方式就是传统双塔向量模型 向量检索库的粗排/精排。模型清单详见 Embedding 用法。需要强调的是与 cross-encoder 不同late-interaction 与 bi-encoder 的打分没有 Score Template 参与详情见本文第六节也不限制num_labels。三、离线推理Pooling 参数与LLM.score3.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_parameters中classify任务只接受[use_activation]同时verify()内部会把显式传入的参数与pooler_config做合并解析。此外要注意历史版本中曾被广泛使用的normalize参数已被移除统一由use_activation表达在线协议层遇到normalize会直接抛出VLLMValidationError见 vllm/entrypoints/pooling/base/protocol.py 的reject_removed_pooling_parameters。对于 re-ranker本质是二分类打分头而言use_activation决定输出的是激活后的 0~1 概率分数还是裸 logits——默认会按模型的 problem_type / label 数量选择 sigmoid二分类场景这是决定重排序结果可比性的关键开关。3.2LLM.score最小可用示例LLM.score直接输出句子对query-document pair的相似度分数。使用 cross-encoder 模型时必须显式指定runnerpoolingfrom vllm import LLM llm LLM(modelBAAI/bge-reranker-v2-m3, runnerpooling) (output,) llm.score( What is the capital of France?, The capital of Brazil is Brasilia., ) score output.outputs.score print(fScore: {score})上面的两段文本构成一个句子对返回单个分数。更完整、支持多候选文档的批量示例见 examples/basic/offline_inference/score.py其内部就是llm.score(query, documents)后逐条读取output.outputs.score并打印。从源码调用链看LLM.score会把请求转换成PoolingParams(taskclassify, use_activation...)提交给引擎即打分在任务层复用的正是 classification 推理路径——这与只有num_labels1的分类模型才能打分的约束在实现上完全自洽见 protocol.py 中的 to_pooling_params。对于需要特定 prompt 格式的 re-ranker如 Gemma / Qwen3 / mxbai 系离线调用需额外传入对应模板例如llm.score( query, documents, chat_templateget_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/scoreScore API 与LLM.score一一对应用于计算两段输入之间的相似度分数。请求体的全部参数定义在 vllm/entrypoints/pooling/scoring/protocol.pyScore 相关与 vllm/entrypoints/pooling/base/protocol.pypooling 通用参数汇总如下Pooling 通用参数pooling-common-paramspooling-common-extra-params参数类型 / 默认值说明modelstr \| None模型名通常必须指定userstr \| None终端用户名用于监控/审计truncate_prompt_tokensint \| None≥ -1截断到前 N 个 token拼接后的整体paddingmax_length \| do_not_pad \| None是否按最大长度 pad。像 SigLIP 这类定长训练且无 attention mask的模型必须用max_length否则 embedding 不可比较truncation_sideleft \| right \| None截断方向right保留前 N 个 tokenleft保留后 N 个 tokenrequest_idstr请求 ID不传则服务端随机生成并贯穿推理与响应priorityint默认 0请求优先级数值越小越早处理非 0 优先级要求服务端启用了优先级调度mm_processor_kwargsdict \| None透传给 HF processor 的额外参数cache_saltstr \| None前缀缓存加盐字符串用于多租户下防 prompt 猜测攻击分类/打分通用参数参数类型 / 默认值说明use_activationbool \| None是否对 pooler 输出应用激活None走 pooler 默认多为 Truemax_tokens_per_queryint默认 0每条 query 的最大 token 数超长截断0 表示不按 query 级别截断max_tokens_per_docint默认 0每条 document 的最大 token 数超长截断0 表示不按 document 级别截断instructionstr \| None通过 chat template 前置到每个待打分 pair 的任务指令等价于传chat_template_kwargs{instruction: ...}chat_template_kwargsdict \| None传给 chat/score template 渲染器的额外关键字参数Score 请求体参数score-request-params参数类型说明queriesScoreInput \| list[ScoreInput]查询文本或其列表documentsScoreInput \| list[ScoreInput]候选文档文本或其列表从协议定义看ScoreRequest是多种请求体形状的联合类型详见 protocol.py除了最常用的queries documents还兼容queries items、data_1 data_2、text_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传列表时会以query与documents中每一个元素分别构造成句子对总对数 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 分数接近 00.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 式逐对打分当queries与documents都是列表时第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.py 与 vision_rerank_api_online.py。4.2 Cohere Rerank API/rerank、/v1/rerank、/v2/rerankRerank 接口在协议层面兼容Jina AI 的 rerank 接口与Cohere 的 rerank 接口从而可以直接对接这两个生态中的开源工具链。可直接运行的客户端示例见 rerank_api_online.py 与 cohere_rerank_client.py。其参数 pooling 通用参数model、user、truncate_prompt_tokens等 classify/打分通用参数use_activation、max_tokens_per_query、max_tokens_per_doc、instruction、chat_template_kwargs 下面 rerank 专用参数参数类型 / 默认值说明queryScoreInput单个查询文本documentsScoreInput \| list[ScoreInput]待重排的候选文档top_nint默认 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 中查到RerankResult含index/document/relevance_score其中document还可携带多模态内容RerankDocument.text/RerankDocument.multi_modal这保证了图文 re-ranker 同样能走 Rerank 接口。五、更多可直接运行的示例除上文已出现的文件外仓库在 examples/pooling/score 目录下还维护了覆盖三种 score type 的完整示例集可作为后续二次开发的起点qwen3_reranker_offline.py/qwen3_reranker_online.pyQwen3-Reranker 的离/在线完整用法using_template_offline.py/using_template_online.py演示为不同 re-ranker 绑定对应 Score Templatererank_api_online.py/cohere_rerank_client.pyRerank API 的调用与 Cohere 兼容客户端示例colbert_rerank_online.py、colmodernvbert_rerank_online.py、colqwen3_rerank_online.py、colqwen3_5_rerank_online.pylate-interactionColBERT 系打分示例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_activation6.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 模型生效若你用一个 embeddingbi-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.jinja、qwen3_reranker.jinja、qwen3_vl_reranker.jinja、mxbai_rerank_v2.jinja、nemotron-vl-rerank.jinja 等模板文件分别对应前文各型号 re-ranker。6.3 激活函数开关use_activationuse_activation参数离线为PoolingParams.use_activation在线为请求体的use_activation用来启用/禁用 pooler 输出的激活对于 re-ranker 即 sigmoid/softmax 打分头。该参数同样只对 cross-encoder 模型有效取值为None跟随模型默认通常为启用或显式布尔值。设置use_activationFalse时打分 API 将返回未经激活的裸 logits适合需要自行后处理分数的高级用法。七、与任务/API 演进相关的注意事项最后整理两条与打分模型相关的兼容性边界避免在实际接入时踩坑score任务本身已被移除在 vLLM v0.21 及以后打分统一建立在classify任务之上num_labels 1的分类模型才开放打分 API。不要在PoolerConfig(task...)/--pooler-config.task中试图指定一个独立的score任务应使用classify。模型 runner 一般无需手动指定vllm serve/LLM(...)的--runner auto会自动识别 pooling 模型仅在自动识别失效时才需要显式runnerpooling。若模型不实现 pooling 接口可借助--convert type如classify、embed按架构名自动转换——这也是前文大量 re-ranker 示例能直接服务的前提转换细节见 Pooling 模型总览文档的 Model Conversion 小节。总而言之vLLM 的 Scoring 能力是一套复用分类/嵌入基础设施、向上层 RAG 提供统一打分语义的完整方案跨编码器负责逐对精排、双塔/后交互负责向量化粗排三者通过统一的LLM.score离线接口与/score、/rerank在线接口对外暴露。结合本文的模型加载 overrides、参数表和示例脚本即可在自己的检索增强应用中快速接入一条高性能的重排序链路。【免费下载链接】vllmA high-throughput and memory-efficient inference and serving engine for LLMs项目地址: https://gitcode.com/GitHub_Trending/vl/vllm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表