评分用法¶
评分模型旨在计算两个输入提示词之间的相似度分数。它支持三种模型类型(即 score_type):cross-encoder(交叉编码器)、late-interaction(后期交互)和 bi-encoder(双编码器)。
注意
vLLM 仅处理 RAG 流水线中的模型推理部分(如嵌入生成和重排序)。对于更高级的 RAG 编排,您应该利用 LangChain 等集成框架。
摘要¶
- 模型用法:评分
- 池化任务
| 评分类型 | 池化任务 | 评分函数 |
|---|---|---|
交叉编码器 | classify(见说明) | 线性分类器 |
后期交互 | token_embed | 后期交互 (MaxSim) |
双编码器 | embed | 余弦相似度 |
注意
只有当分类模型输出的 num_labels 等于 1 时,它才能用作评分模型并启用其评分 API。
支持的模型¶
交叉编码器模型¶
交叉编码器(也称为重排序器)模型是分类模型的一个子集,它接受两个提示词作为输入,并输出 num_labels 为 1 的结果。
纯文本模型¶
| 架构 | 模型 | 示例 HF 模型 | 评分模板(见说明) | LoRA | PP |
|---|---|---|---|---|---|
BertForSequenceClassification | 基于 BERT | cross-encoder/ms-marco-MiniLM-L-6-v2 等。 | 不适用 | ||
GemmaForSequenceClassification | 基于 Gemma | BAAI/bge-reranker-v2-gemma(见说明)等。 | bge-reranker-v2-gemma.jinja | ✅︎ | ✅︎ |
GteNewForSequenceClassification | mGTE-TRM(见说明) | Alibaba-NLP/gte-multilingual-reranker-base 等。 | 不适用 | ||
LlamaBidirectionalForSequenceClassificationC | 基于 Llama,带双向注意力 | nvidia/llama-nemotron-rerank-1b-v2 等。 | nemotron-rerank.jinja | ✅︎ | ✅︎ |
Qwen2ForSequenceClassificationC | 基于 Qwen2 | mixedbread-ai/mxbai-rerank-base-v2(见说明)等。 | mxbai_rerank_v2.jinja | ✅︎ | ✅︎ |
Qwen3ForSequenceClassificationC | 基于 Qwen3 | tomaarsen/Qwen3-Reranker-0.6B-seq-cls, Qwen/Qwen3-Reranker-0.6B(见说明)等。 | qwen3_reranker.jinja | ✅︎ | ✅︎ |
RobertaForSequenceClassification | 基于 RoBERTa | cross-encoder/quora-roberta-base 等。 | 不适用 | ||
XLMRobertaForSequenceClassification | 基于 XLM-RoBERTa | BAAI/bge-reranker-v2-m3 等。 | 不适用 | ||
*ModelC, *ForCausalLMC 等 | 生成式模型 | 不适用 | 不适用 | * | * |
C 通过 --convert classify 自动转换为分类模型。(详情)
* 功能支持与原始模型相同。
注意
某些模型需要特定的提示词格式才能正常工作。
您可以在 examples/pooling/score/template/ 中找到示例 HuggingFace 模型的对应评分模板。
示例: examples/pooling/score/using_template_offline.py examples/pooling/score/using_template_online.py
注意
使用以下命令加载官方原始的 BAAI/bge-reranker-v2-gemma。
注意
第二代 GTE 模型 (mGTE-TRM) 被命名为 NewForSequenceClassification。由于名称 NewForSequenceClassification 太通用,您应该设置 --hf-overrides '{"architectures": ["GteNewForSequenceClassification"]}' 以指定使用 GteNewForSequenceClassification 架构。
注意
使用以下命令加载官方原始的 mxbai-rerank-v2。
注意
使用以下命令加载官方原始的 Qwen3 Reranker。更多信息可在以下位置找到: examples/pooling/score/qwen3_reranker_offline.py examples/pooling/score/qwen3_reranker_online.py。
多模态模型¶
注意
有关多模态模型输入的更多信息,请参阅此页面。
| 架构 | 模型 | 输入 | 示例 HF 模型 | LoRA | PP |
|---|---|---|---|---|---|
JinaVLForSequenceClassification | 基于 JinaVL | 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(见说明)等。 | ✅︎ | ✅︎ |
C 通过 --convert classify 自动转换为分类模型。(详情)
* 功能支持与原始模型相同。
注意
与 Qwen3-Reranker 类似,您需要使用以下 --hf_overrides 来加载官方原始的 Qwen3-VL-Reranker。
后期交互模型¶
所有支持 token 嵌入任务的模型也支持使用评分 API,通过计算两个输入提示词的后期交互来计算相似度得分。有关 token 嵌入模型的更多信息,请参阅此页面。
纯文本模型¶
| 架构 | 模型 | 示例 HF 模型 | LoRA | PP |
|---|---|---|---|---|
ColBERTLfm2Model | LFM2 | LiquidAI/LFM2-ColBERT-350M | ||
ColBERTModernBertModel | ModernBERT | lightonai/GTE-ModernColBERT-v1 | ||
ColBERTJinaRobertaModel | Jina XLM-RoBERTa | jinaai/jina-colbert-v2 | ||
HF_ColBERT | BERT | answerdotai/answerai-colbert-small-v1, colbert-ir/colbertv2.0 | ||
*ModelC, *ForCausalLMC 等 | 生成式模型 | 不适用 | * | * |
多模态模型¶
注意
有关多模态模型输入的更多信息,请参阅此页面。
| 架构 | 模型 | 输入 | 示例 HF 模型 | LoRA | PP |
|---|---|---|---|---|---|
ColModernVBertForRetrieval | ColModernVBERT | T / I | ModernVBERT/colmodernvbert-merged | ||
ColPaliForRetrieval | ColPali | T / I | vidore/colpali-v1.3-hf | ||
ColQwen3 | Qwen3-VL | T / I | TomoroAI/tomoro-colqwen3-embed-4b, TomoroAI/tomoro-colqwen3-embed-8b | ||
ColQwen3_5 | ColQwen3.5 | T + I + V | athrael-soju/colqwen3.5-4.5B-v3 | ||
OpsColQwen3Model | Qwen3-VL | T / I | OpenSearch-AI/Ops-Colqwen3-4B, OpenSearch-AI/Ops-Colqwen3-8B | ||
Qwen3VLNemotronEmbedModel | Qwen3-VL | T / I | nvidia/nemotron-colembed-vl-4b-v2, nvidia/nemotron-colembed-vl-8b-v2 | ✅︎ | ✅︎ |
*ForConditionalGenerationC, *ForCausalLMC 等 | 生成式模型 | * | 不适用 | * | * |
C 通过 --convert embed 自动转换为嵌入模型。(详细信息)
* 功能支持与原始模型相同。
如果您的模型不在上述列表中,我们将尝试使用 as_embedding_model 自动转换该模型。
双编码器¶
所有支持嵌入任务的模型也支持使用评分 API,通过计算两个输入提示词嵌入的余弦相似度来计算相似度得分。有关嵌入模型的更多信息,请参阅此页面。
纯文本模型¶
| 架构 | 模型 | 示例 HF 模型 | LoRA | PP |
|---|---|---|---|---|
BertModel | 基于 BERT | BAAI/bge-base-en-v1.5, Snowflake/snowflake-arctic-embed-xs 等。 | ||
BertSpladeSparseEmbeddingModel | SPLADE | naver/splade-v3 | ||
ErnieModel | 基于 BERT 的中文 ERNIE | shibing624/text2vec-base-chinese-sentence | ||
Gemma2ModelC | 基于 Gemma 2 | BAAI/bge-multilingual-gemma2 等。 | ✅︎ | ✅︎ |
Gemma3TextModelC | 基于 Gemma 3 | google/embeddinggemma-300m 等。 | ✅︎ | ✅︎ |
GritLM | GritLM | parasail-ai/GritLM-7B-vllm. | ✅︎ | ✅︎ |
GteModel | Arctic-Embed-2.0-M | Snowflake/snowflake-arctic-embed-m-v2.0. | ||
GteNewModel | mGTE-TRM(见说明) | Alibaba-NLP/gte-multilingual-base 等。 | ||
LlamaBidirectionalModelC | 基于 Llama,带双向注意力 | nvidia/llama-nemotron-embed-1b-v2 等。 | ✅︎ | ✅︎ |
LlamaModelC, LlamaForCausalLMC, MistralModelC 等。 | 基于 Llama | intfloat/e5-mistral-7b-instruct 等。 | ✅︎ | ✅︎ |
ModernBertModel | 基于 ModernBERT | Alibaba-NLP/gte-modernbert-base 等。 | ||
NomicBertModel | Nomic BERT | nomic-ai/nomic-embed-text-v1, nomic-ai/nomic-embed-text-v2-moe, Snowflake/snowflake-arctic-embed-m-long 等。 | ||
Qwen2ModelC, Qwen2ForCausalLMC | 基于 Qwen2 | ssmits/Qwen2-7B-Instruct-embed-base(见说明), Alibaba-NLP/gte-Qwen2-7B-instruct(见说明)等。 | ✅︎ | ✅︎ |
Qwen3ModelC, Qwen3ForCausalLMC | 基于 Qwen3 | Qwen/Qwen3-Embedding-0.6B 等。 | ✅︎ | ✅︎ |
RobertaModel, RobertaForMaskedLM | 基于 RoBERTa | sentence-transformers/all-roberta-large-v1 等。 | ||
VoyageQwen3BidirectionalEmbedModelC | 基于 Voyage Qwen3 的双向注意力模型 | voyageai/voyage-4-nano 等。 | ✅︎ | ✅︎ |
XLMRobertaModel | 基于 XLMRobertaModel | BAAI/bge-m3(见说明), intfloat/multilingual-e5-base, jinaai/jina-embeddings-v3(见说明)等。 | ||
*ModelC, *ForCausalLMC 等 | 生成式模型 | 不适用 | * | * |
注意
第二代 GTE 模型 (mGTE-TRM) 被命名为 NewModel。由于名称 NewModel 太通用,您应该设置 --hf-overrides '{"architectures": ["GteNewModel"]}' 以指定使用 GteNewModel 架构。
注意
ssmits/Qwen2-7B-Instruct-embed-base 具有错误定义的 Sentence Transformers 配置。您需要通过传递 --pooler-config '{"pooling_type": "MEAN"}' 手动设置平均池化。
注意
对于 Alibaba-NLP/gte-Qwen2-*,您需要启用 --trust-remote-code 以加载正确的分词器。请参阅 HuggingFace Transformers 上的相关议题。
注意
BAAI/bge-m3 模型带有用于稀疏和 ColBERT 嵌入的额外权重,有关更多信息,请参阅此页面。
注意
jinaai/jina-embeddings-v3 通过 LoRA 支持多种任务,而 vLLM 目前仅通过合并 LoRA 权重支持文本匹配任务。
多模态模型¶
注意
有关多模态模型输入的更多信息,请参阅此页面。
| 架构 | 模型 | 输入 | 示例 HF 模型 | LoRA | PP |
|---|---|---|---|---|---|
CLIPModel | CLIP | T / I | openai/clip-vit-base-patch32, openai/clip-vit-large-patch14 等。 | ||
LlamaNemotronVLModel | Llama Nemotron Embedding + SigLIP | T + I | nvidia/llama-nemotron-embed-vl-1b-v2 | ||
LlavaNextForConditionalGenerationC | 基于 LLaVA-NeXT | T / I | royokong/e5-v | ✅︎ | |
Phi3VForCausalLMC | 基于 Phi-3-Vision | T + I | TIGER-Lab/VLM2Vec-Full | ✅︎ | |
Qwen3VLForConditionalGenerationC | Qwen3-VL | T + I + V | Qwen/Qwen3-VL-Embedding-2B 等。 | ✅︎ | ✅︎ |
SiglipModel | SigLIP, SigLIP2 | T / I | google/siglip-base-patch16-224, google/siglip2-base-patch16-224 | ||
*ForConditionalGenerationC, *ForCausalLMC 等 | 生成式模型 | * | 不适用 | * | * |
C 通过 --convert embed 自动转换为嵌入模型。(详细信息)
* 功能支持与原始模型相同。
如果您的模型不在上述列表中,我们将尝试使用 as_embedding_model 自动转换该模型。默认情况下,整个提示词的嵌入是从对应于最后一个 token 的归一化隐藏状态中提取的。
注意
虽然 vLLM 支持通过 --convert embed 自动将任何架构的模型转换为嵌入模型,但为了获得最佳结果,您应该使用专门为此训练的池化模型。
离线推理¶
池化参数¶
以下 池化参数 仅由交叉编码器模型支持,不适用于后期交互和双编码器模型。
LLM.score¶
score 方法输出句子对之间的相似度得分。
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
在线服务¶
评分 API¶
我们的评分 API (/score) 与 LLM.score 类似,用于计算两个输入提示词之间的相似度得分。
参数¶
支持以下评分 API 参数
model: str | None = None
user: str | None = None
truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
truncation_side: Literal["left", "right"] | None = Field(
default=None,
description=(
"Which side to truncate from when truncate_prompt_tokens is active. "
"'right' keeps the first N tokens. "
"'left' keeps the last N tokens."
),
)
request_id: str = Field(
default_factory=random_uuid,
description=(
"The request_id related to this request. If the caller does "
"not set it, a random_uuid will be generated. This id is used "
"through out the inference process and return in response."
),
)
priority: int = Field(
default=0,
ge=-(2**63),
le=2**63 - 1,
description=(
"The priority of the request (lower means earlier handling; "
"default: 0). Any priority other than 0 will raise an error "
"if the served model does not use priority scheduling."
),
)
mm_processor_kwargs: dict[str, Any] | None = Field(
default=None,
description="Additional kwargs to pass to the HF processor.",
)
cache_salt: str | None = Field(
default=None,
description=(
"If specified, the prefix cache will be salted with the provided "
"string to prevent an attacker to guess prompts in multi-user "
"environments. The salt should be random, protected from "
"access by 3rd parties, and long enough to be "
"unpredictable (e.g., 43 characters base64-encoded, corresponding "
"to 256 bit)."
),
)
use_activation: bool | None = Field(
default=None,
description="Whether to use activation for the pooler outputs. "
"`None` uses the pooler's default, which is `True` in most cases.",
)
示例¶
单次推理¶
您可以将字符串传递给 queries 和 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 France?",
"documents": "The capital of France is Paris."
}'
响应
批量推理¶
您可以将一个字符串传递给 queries,将一个列表传递给 documents,从而形成多个句子对,其中每一对都是由 queries 和 documents 中的一个字符串构建的。对的总数为 len(documents)。
请求
响应
您可以将列表传递给 queries 和 documents,形成多个句子对,其中每一对都是由 queries 中的一个字符串和 documents 中对应的字符串构建的(类似于 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."
]
}'
响应
多模态输入¶
您可以通过在请求中传递包含多模态输入(图像等)列表的 content,将多模态输入传递给评分模型。请参考下面的示例进行说明。
部署模型
由于 OpenAI 客户端未定义请求模式,我们使用底层的 requests 库向服务器发布请求
代码
import requests
response = requests.post(
"https://: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"])
完整示例
- examples/pooling/score/vision_score_api_online.py
- examples/pooling/score/vision_rerank_api_online.py
重排序 API¶
/rerank, /v1/rerank 和 /v2/rerank API 兼容 Jina AI 的 rerank API 接口 和 Cohere 的 rerank API 接口,以确保与流行的开源工具兼容。
代码示例: examples/pooling/score/rerank_api_online.py
参数¶
支持以下重排序 API 参数
model: str | None = None
user: str | None = None
truncate_prompt_tokens: Annotated[int, Field(ge=-1)] | None = None
truncation_side: Literal["left", "right"] | None = Field(
default=None,
description=(
"Which side to truncate from when truncate_prompt_tokens is active. "
"'right' keeps the first N tokens. "
"'left' keeps the last N tokens."
),
)
request_id: str = Field(
default_factory=random_uuid,
description=(
"The request_id related to this request. If the caller does "
"not set it, a random_uuid will be generated. This id is used "
"through out the inference process and return in response."
),
)
priority: int = Field(
default=0,
ge=-(2**63),
le=2**63 - 1,
description=(
"The priority of the request (lower means earlier handling; "
"default: 0). Any priority other than 0 will raise an error "
"if the served model does not use priority scheduling."
),
)
mm_processor_kwargs: dict[str, Any] | None = Field(
default=None,
description="Additional kwargs to pass to the HF processor.",
)
cache_salt: str | None = Field(
default=None,
description=(
"If specified, the prefix cache will be salted with the provided "
"string to prevent an attacker to guess prompts in multi-user "
"environments. The salt should be random, protected from "
"access by 3rd parties, and long enough to be "
"unpredictable (e.g., 43 characters base64-encoded, corresponding "
"to 256 bit)."
),
)
use_activation: bool | None = Field(
default=None,
description="Whether to use activation for the pooler outputs. "
"`None` uses the pooler's default, which is `True` in most cases.",
)
示例¶
请注意,top_n 请求参数是可选的,默认为 documents 字段的长度。结果文档将按相关性排序,index 属性可用于确定原始顺序。
请求
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"
]
}'
响应
{
"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
}
]
}
更多示例¶
更多示例可在此处找到: examples/pooling/score
支持的功能¶
由于交叉编码器模型是接受两个提示词作为输入且输出 num_labels 等于 1 的分类模型的一个子集,因此交叉编码器特征应与(序列)分类保持一致。有关更多信息,请参阅此页面。
评分模板¶
评分模板仅支持 cross-encoder(交叉编码器)模型。如果您正在使用 embedding(嵌入)模型进行评分,vLLM 不会应用评分模板。
某些评分模型需要特定的提示词格式才能正常工作。您可以使用 --chat-template 参数指定自定义评分模板(请参阅 聊天模板)。
与聊天模板一样,评分模板接收一个 messages 列表。对于评分,每条消息都有一个 role 属性——要么是 "query"(查询),要么是 "document"(文档)。对于常见的逐点交叉编码器,您可以预期正好有两条消息:一条查询和一条文档。要访问查询和文档内容,请使用 Jinja 的 selectattr 过滤器
- 查询:
{{ (messages | selectattr("role", "eq", "query") | first).content }} - 文档:
{{ (messages | selectattr("role", "eq", "document") | first).content }}
这种方法比基于索引的访问(messages[0], messages[1])更健壮,因为它通过语义角色选择消息。如果将来在 messages 中添加了其他类型的消息,它也避免了对消息顺序的假设。
示例模板文件: examples/pooling/score/template/nemotron-rerank.jinja
启用/禁用激活¶
您可以通过 use_activation 启用或禁用激活,这仅适用于交叉编码器模型。