@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 1e36c8687e
Fork 0

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