[Bugfix][Frontend] Do not modify caller params in LLM.score() (#59959)

Signed-off-by: 叮当猫 <2756823972@qq.com>
Signed-off-by: apex-mochen <2756823972@qq.com>
Co-authored-by: DeepSeek Harness <noreply@deepseek.com>
Co-authored-by: Taneem Ibrahim <taneem.ibrahim@gmail.com>
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
dingdangmao
2026-10-08 09:03:08 +08:00
committed by GitHub
co-authored by DeepSeek Harness Taneem Ibrahim Codex
parent 9e3e37cb3c
commit 2dd887426e
2 changed files with 39 additions and 0 deletions
@@ -7,6 +7,8 @@ import pytest
from vllm import PoolingParams
from vllm.entrypoints.pooling.base.io_processor import PoolingIOProcessor
from vllm.entrypoints.pooling.offline import PoolingOfflineMixin
from vllm.entrypoints.pooling.scoring.io_processor import CrossEncoderIOProcessor
from vllm.entrypoints.pooling.typing import OfflineEncodeInputsContext
from vllm.exceptions import VLLMValidationError
from vllm.renderers import TokenizeParams
@@ -221,3 +223,38 @@ def test_qwen3_reranker_no_warning_when_template_provided(monkeypatch):
)
mock_logger.warning.assert_not_called()
def _make_score_llm(monkeypatch) -> PoolingOfflineMixin:
"""A scoring LLM with no model behind it.
Input validation runs for real; only the rendering, engine and
post-processing boundaries are stubbed out. The pooling task is filled in
before any of them, so the mutation is observable without inference.
"""
proc = CrossEncoderIOProcessor.__new__(CrossEncoderIOProcessor)
proc.is_multimodal_model = False
proc.architecture = "CrossEncoder"
monkeypatch.setattr(proc, "get_request_factory_offline", lambda ctx: (None, 0))
monkeypatch.setattr(proc, "post_process_offline", lambda ctx: [])
llm = PoolingOfflineMixin.__new__(PoolingOfflineMixin)
llm.runner_type = "pooling"
llm.pooling_task = "classify" # SCORE_TYPE_MAP -> "cross-encoder"
llm.model_config = SimpleNamespace(hf_config=SimpleNamespace(num_labels=1))
llm.pooling_io_processors = {"cross-encoder": proc}
monkeypatch.setattr(llm, "_run_tiling_engine", lambda *args, **kwargs: [])
return llm
def test_score_leaves_caller_pooling_params_untouched(monkeypatch):
llm = _make_score_llm(monkeypatch)
params = PoolingParams()
llm.score("query", "doc", pooling_params=params)
assert params.task is None, (
"LLM.score() wrote the model's own pooling task into the caller's "
"PoolingParams; reusing that object with another pooling model now "
"fails with 'You cannot overwrite ...' before any inference runs."
)
+2
View File
@@ -362,6 +362,8 @@ class PoolingOfflineMixin(OfflineInferenceMixin):
assert isinstance(pooling_params, PoolingParams)
pooling_task = io_processor.pooling_task
# Clone to avoid modifying the caller's pooling parameters.
pooling_params = pooling_params.clone()
if pooling_params.task is None:
pooling_params.task = pooling_task
elif pooling_params.task != pooling_task: