跳到内容

评分用法

评分模型旨在计算两个输入提示词之间的相似度分数。它支持三种模型类型(即 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

vllm serve BAAI/bge-reranker-v2-gemma --hf_overrides '{"architectures": ["GemmaForSequenceClassification"],"classifier_from_token": ["Yes"],"method": "no_post_processing"}'

注意

第二代 GTE 模型 (mGTE-TRM) 被命名为 NewForSequenceClassification。由于名称 NewForSequenceClassification 太通用,您应该设置 --hf-overrides '{"architectures": ["GteNewForSequenceClassification"]}' 以指定使用 GteNewForSequenceClassification 架构。

注意

使用以下命令加载官方原始的 mxbai-rerank-v2

vllm serve mixedbread-ai/mxbai-rerank-base-v2 --hf_overrides '{"architectures": ["Qwen2ForSequenceClassification"],"classifier_from_token": ["0", "1"], "method": "from_2_way_softmax"}'

注意

使用以下命令加载官方原始的 Qwen3 Reranker。更多信息可在以下位置找到: examples/pooling/score/qwen3_reranker_offline.py examples/pooling/score/qwen3_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 模型 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

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

后期交互模型

所有支持 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 自动将任何架构的模型转换为嵌入模型,但为了获得最佳结果,您应该使用专门为此训练的池化模型。

离线推理

池化参数

以下 池化参数 仅由交叉编码器模型支持,不适用于后期交互和双编码器模型。

    use_activation: bool | None = None

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.",
    )

示例

单次推理

您可以将字符串传递给 queriesdocuments,形成单个句子对。

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."
}'
响应
{
  "id": "score-request-id",
  "object": "list",
  "created": 693447,
  "model": "BAAI/bge-reranker-v2-m3",
  "data": [
    {
      "index": 0,
      "object": "score",
      "score": 1
    }
  ],
  "usage": {}
}
批量推理

您可以将一个字符串传递给 queries,将一个列表传递给 documents,从而形成多个句子对,其中每一对都是由 queriesdocuments 中的一个字符串构建的。对的总数为 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."
  ]
}'
响应
{
  "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": {}
}

您可以将列表传递给 queriesdocuments,形成多个句子对,其中每一对都是由 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."
  ]
}'
响应
{
  "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": {}
}
多模态输入

您可以通过在请求中传递包含多模态输入(图像等)列表的 content,将多模态输入传递给评分模型。请参考下面的示例进行说明。

部署模型

vllm serve jinaai/jina-reranker-m0

由于 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"])

完整示例

重排序 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 启用或禁用激活,这仅适用于交叉编码器模型。