A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 15, 02:15 UTC
[Deprecation] Remove `nullable_kvs` (#20969)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Harry Mellor committed
Jul 15, 2025 at 18:21 UTC
1e36c8687e2b195d942302cb441d23d80fff0cc8
3 files changed
+7
-93
tests/engine/test_arg_utils.py
+4
-52
@@ -2,7 +2,7 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
import json
5
-from argparse import ArgumentError, ArgumentTypeError
5
+from argparse import ArgumentError
6
from contextlib import nullcontext
7
from dataclasses import dataclass, field
8
from typing import Annotated, Literal, Optional
@@ -12,8 +12,8 @@ import pytest
12
from vllm.config import CompilationConfig, config
13
from vllm.engine.arg_utils import (EngineArgs, contains_type, get_kwargs,
14
get_type, get_type_hints, is_not_builtin,
15
- is_type, literal_to_kwargs, nullable_kvs,
16
- optional_type, parse_type)
15
+ is_type, literal_to_kwargs, optional_type,
16
+ parse_type)
17
from vllm.utils import FlexibleArgumentParser
18
19
@@ -25,18 +25,10 @@ from vllm.utils import FlexibleArgumentParser
25
"foo": 1,
26
"bar": 2
27
}),
28
- (json.loads, "foo=1,bar=2", {
29
- "foo": 1,
30
- "bar": 2
31
- }),
28
])
29
def test_parse_type(type, value, expected):
30
parse_type_func = parse_type(type)
35
- context = nullcontext()
36
- if value == "foo=1,bar=2":
37
- context = pytest.warns(DeprecationWarning)
38
- with context:
39
- assert parse_type_func(value) == expected
31
+ assert parse_type_func(value) == expected
32
33
34
def test_optional_type():
@@ -203,34 +195,6 @@ def test_get_kwargs():
195
assert kwargs["from_cli_config2"]["type"]('{"field": 2}').field == 4
196
197
206
-@pytest.mark.parametrize(("arg", "expected"), [
207
- (None, dict()),
208
- ("image=16", {
209
- "image": 16
210
- }),
211
- ("image=16,video=2", {
212
- "image": 16,
213
- "video": 2
214
- }),
215
- ("Image=16, Video=2", {
216
- "image": 16,
217
- "video": 2
218
- }),
219
-])
220
-def test_limit_mm_per_prompt_parser(arg, expected):
221
- """This functionality is deprecated and will be removed in the future.
222
- This argument should be passed as JSON string instead.
223
-
224
- TODO: Remove with nullable_kvs."""
225
- parser = EngineArgs.add_cli_args(FlexibleArgumentParser())
226
- if arg is None:
227
- args = parser.parse_args([])
228
- else:
229
- args = parser.parse_args(["--limit-mm-per-prompt", arg])
230
-
231
- assert args.limit_mm_per_prompt == expected
232
-
233
-
198
@pytest.mark.parametrize(
199
("arg", "expected"),
200
[
@@ -326,18 +290,6 @@ def test_prefix_cache_default():
290
assert not engine_args.enable_prefix_caching
291
292
329
-@pytest.mark.parametrize(
330
- ("arg"),
331
- [
332
- "image", # Missing =
333
- "image=4,image=5", # Conflicting values
334
- "image=video=4" # Too many = in tokenized arg
335
- ])
336
-def test_bad_nullable_kvs(arg):
337
- with pytest.raises(ArgumentTypeError):
338
- nullable_kvs(arg)
339
-
340
-
293
# yapf: disable
294
@pytest.mark.parametrize(("arg", "expected", "option"), [
295
(None, None, "mm-processor-kwargs"),
tests/entrypoints/openai/test_openai_schema.py
+2
-1
@@ -1,5 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
+import json
4
from typing import Final
5
6
import pytest
@@ -29,7 +30,7 @@ def server():
30
"--enforce-eager",
31
"--trust-remote-code",
32
"--limit-mm-per-prompt",
32
- f"image={MAXIMUM_IMAGES}",
33
+ json.dumps({"image": MAXIMUM_IMAGES}),
34
]
35
36
with RemoteOpenAIServer(MODEL_NAME, args) as remote_server:
vllm/engine/arg_utils.py
+1
-40
@@ -18,7 +18,7 @@ from typing import (TYPE_CHECKING, Annotated, Any, Callable, Dict, List,
18
import regex as re
19
import torch
20
from pydantic import TypeAdapter, ValidationError
21
-from typing_extensions import TypeIs, deprecated
21
+from typing_extensions import TypeIs
22
23
import vllm.envs as envs
24
from vllm.config import (BlockSize, CacheConfig, CacheDType, CompilationConfig,
@@ -65,9 +65,6 @@ def parse_type(return_type: Callable[[str], T]) -> Callable[[str], T]:
65
66
def _parse_type(val: str) -> T:
67
try:
68
- if return_type is json.loads and not re.match(
69
- r"(?s)^\s*{.*}\s*$", val):
70
- return cast(T, nullable_kvs(val))
68
return return_type(val)
69
except ValueError as e:
70
raise argparse.ArgumentTypeError(
@@ -93,42 +90,6 @@ def union_dict_and_str(val: str) -> Optional[Union[str, dict[str, str]]]:
90
return optional_type(json.loads)(val)
91
92
96
-@deprecated(
97
- "Passing a JSON argument as a string containing comma separated key=value "
98
- "pairs is deprecated. This will be removed in v0.10.0. Please use a JSON "
99
- "string instead.")
100
-def nullable_kvs(val: str) -> dict[str, int]:
101
- """Parses a string containing comma separate key [str] to value [int]
102
- pairs into a dictionary.
103
-
104
- Args:
105
- val: String value to be parsed.
106
-
107
- Returns:
108
- Dictionary with parsed values.
109
- """
110
- out_dict: dict[str, int] = {}
111
- for item in val.split(","):
112
- kv_parts = [part.lower().strip() for part in item.split("=")]
113
- if len(kv_parts) != 2:
114
- raise argparse.ArgumentTypeError(
115
- "Each item should be in the form KEY=VALUE")
116
- key, value = kv_parts
117
-
118
- try:
119
- parsed_value = int(value)
120
- except ValueError as exc:
121
- msg = f"Failed to parse value of item {key}={value}"
122
- raise argparse.ArgumentTypeError(msg) from exc
123
-
124
- if key in out_dict and out_dict[key] != parsed_value:
125
- raise argparse.ArgumentTypeError(
126
- f"Conflicting values specified for key: {key}")
127
- out_dict[key] = parsed_value
128
-
129
- return out_dict
130
-
131
-
93
def is_type(type_hint: TypeHint, type: TypeHintT) -> TypeIs[TypeHintT]:
94
"""Check if the type hint is a specific type."""
95
return type_hint is type or get_origin(type_hint) is type