[Misc] Use VLLMValidationError in offline inference input validation (#53432)

Signed-off-by: Jensen Chen <a1043904820@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

Jensen Chen committed Aug 23, 2026 at 08:43 UTC 39eba6ac368133ab4e69a0589fcd53c481dddc44
4 files changed +67 -7
tests/entrypoints/llm/test_generate.py
+4 -3
@@ -6,6 +6,7 @@ import weakref
6 import pytest
7
8 from vllm import LLM, SamplingParams
9 +from vllm.exceptions import VLLMValidationError
10
11 MODEL_NAME = "distilbert/distilgpt2"
12
@@ -52,7 +53,7 @@ def test_multiple_sampling_params(llm: LLM):
53 assert len(PROMPTS) == len(outputs)
54
55 # Exception raised, if the size of params does not match the size of prompts
55 - with pytest.raises(ValueError):
56 + with pytest.raises(VLLMValidationError):
57 outputs = llm.generate(PROMPTS, sampling_params=sampling_params[:3])
58
59 # Single SamplingParams should be applied to every prompt
@@ -75,13 +76,13 @@ def test_multiple_priority(llm: LLM):
76 assert len(PROMPTS) == len(outputs)
77
78 # Exception raised, if the length of priority does not match the length of prompts
78 - with pytest.raises(ValueError):
79 + with pytest.raises(VLLMValidationError):
80 outputs = llm.generate(
81 PROMPTS, sampling_params=None, priority=[0] * (len(PROMPTS) - 1)
82 )
83
84 # Exception raised, if the priority list is empty
84 - with pytest.raises(ValueError):
85 + with pytest.raises(VLLMValidationError):
86 outputs = llm.generate(PROMPTS, sampling_params=None, priority=[])
87
88
tests/entrypoints/test_offline_utils.py new
+57
@@ -0,0 +1,57 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +
4 +import pytest
5 +
6 +from vllm import SamplingParams
7 +from vllm.entrypoints.offline_utils import OfflineInferenceMixin
8 +from vllm.exceptions import VLLMValidationError
9 +from vllm.lora.request import LoRARequest
10 +
11 +
12 +@pytest.fixture
13 +def mixin() -> OfflineInferenceMixin:
14 + return object.__new__(OfflineInferenceMixin)
15 +
16 +
17 +def test_rejects_mismatched_params(mixin: OfflineInferenceMixin):
18 + with pytest.raises(VLLMValidationError) as exc_info:
19 + mixin._params_to_seq([SamplingParams()], num_requests=2)
20 +
21 + assert str(exc_info.value) == (
22 + "The lengths of prompts (2) and params (1) must be the same."
23 + )
24 + assert exc_info.value.parameter is None
25 + assert exc_info.value.value is None
26 +
27 +
28 +def test_rejects_mismatched_lora_requests(mixin: OfflineInferenceMixin):
29 + with pytest.raises(VLLMValidationError) as exc_info:
30 + mixin._lora_request_to_seq([None], num_requests=2)
31 +
32 + assert str(exc_info.value) == (
33 + "The lengths of prompts (2) and lora_request (1) must be the same."
34 + )
35 + assert exc_info.value.parameter is None
36 + assert exc_info.value.value is None
37 +
38 +
39 +def test_rejects_mismatched_priority(mixin: OfflineInferenceMixin):
40 + with pytest.raises(VLLMValidationError) as exc_info:
41 + mixin._priority_to_seq([0], num_requests=2)
42 +
43 + assert str(exc_info.value) == (
44 + "The lengths of prompts (2) and priority (1) must be the same."
45 + )
46 + assert exc_info.value.parameter is None
47 + assert exc_info.value.value is None
48 +
49 +
50 +def test_matching_lengths_pass_through(mixin: OfflineInferenceMixin):
51 + lora = LoRARequest("l", 1, "/tmp/l")
52 +
53 + assert mixin._params_to_seq([SamplingParams()], num_requests=1) == [
54 + SamplingParams()
55 + ]
56 + assert mixin._lora_request_to_seq([lora], num_requests=1) == [lora]
57 + assert mixin._priority_to_seq([3], num_requests=1) == [3]
tests/lora/test_qwen3_with_multi_loras.py
+2 -1
@@ -12,6 +12,7 @@ import pytest
12
13 from tests.utils import multi_gpu_test
14 from vllm import LLM, SamplingParams
15 +from vllm.exceptions import VLLMValidationError
16 from vllm.lora.request import LoRARequest
17
18 MODEL_PATH = "Qwen/Qwen3-0.6B"
@@ -192,7 +193,7 @@ def test_multiple_lora_requests():
193 assert len(PROMPTS) == len(outputs)
194
195 # Exception raised, if the size of params does not match the size of prompts
195 - with pytest.raises(ValueError):
196 + with pytest.raises(VLLMValidationError):
197 outputs = llm.generate(PROMPTS, lora_request=lora_request[:1])
198
199 # Single LoRARequest should be applied to every prompt
vllm/entrypoints/offline_utils.py
+4 -3
@@ -19,6 +19,7 @@ from vllm.entrypoints.chat_utils import (
19 ChatCompletionMessageParam,
20 ChatTemplateContentFormatOption,
21 )
22 +from vllm.exceptions import VLLMValidationError
23 from vllm.inputs import EngineInput
24 from vllm.logger import init_logger
25 from vllm.lora.request import LoRARequest
@@ -246,7 +247,7 @@ class OfflineInferenceMixin:
247 ) -> Sequence[_P]:
248 if isinstance(params, Sequence):
249 if len(params) != num_requests:
249 - raise ValueError(
250 + raise VLLMValidationError(
251 f"The lengths of prompts ({num_requests}) "
252 f"and params ({len(params)}) must be the same."
253 )
@@ -262,7 +263,7 @@ class OfflineInferenceMixin:
263 ) -> Sequence[LoRARequest | None]:
264 if isinstance(lora_request, Sequence):
265 if len(lora_request) != num_requests:
265 - raise ValueError(
266 + raise VLLMValidationError(
267 f"The lengths of prompts ({num_requests}) "
268 f"and lora_request ({len(lora_request)}) must be the same."
269 )
@@ -278,7 +279,7 @@ class OfflineInferenceMixin:
279 ) -> Sequence[int]:
280 if priority is not None:
281 if len(priority) != num_requests:
281 - raise ValueError(
282 + raise VLLMValidationError(
283 f"The lengths of prompts ({num_requests}) "
284 f"and priority ({len(priority)}) must be the same."
285 )