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 4, 00:00 UTC
Handle optional bool-or-string CLI args in get_kwargs (#40951)
Signed-off-by: Christian Van <cvan20191@gmail.com> Co-authored-by: Christian Van <cvan20191@gmail.com>
Christian Van committed
May 9, 2026 at 22:47 UTC
0d382ecde8c6771fe07854eaad3af73c1353e031
2 files changed
+42
-11
tests/engine/test_arg_utils.py
+36
-1
@@ -9,7 +9,7 @@ from typing import Annotated, Literal
9
import pytest
10
from pydantic import Field
11
12
-from vllm.config import AttentionConfig, CompilationConfig, config
12
+from vllm.config import AttentionConfig, CompilationConfig, ModelConfig, config
13
from vllm.engine.arg_utils import (
14
EngineArgs,
15
_expand_json_human_readable_numbers,
@@ -116,6 +116,10 @@ class DummyConfig:
116
"""Regular bool with default True"""
117
optional_bool: bool | None = None
118
"""Optional bool with default None"""
119
+
120
+ optional_bool_or_str: bool | str | None = None
121
+ """Optional bool-or-str with default None"""
122
+
123
optional_literal: Literal["x", "y"] | None = None
124
"""Optional literal with default None"""
125
tuple_n: tuple[int, ...] = Field(default_factory=lambda: (1, 2, 3))
@@ -170,6 +174,11 @@ def test_get_kwargs():
174
# bools should not have their type set
175
assert kwargs["regular_bool"].get("type") is None
176
assert kwargs["optional_bool"].get("type") is None
177
+ # optional bool-or-str should accept an optional string value
178
+ assert kwargs["optional_bool_or_str"]["type"] is str
179
+ assert kwargs["optional_bool_or_str"]["nargs"] == "?"
180
+ assert kwargs["optional_bool_or_str"]["const"] is True
181
+ assert "action" not in kwargs["optional_bool_or_str"]
182
# optional literals should have None as a choice
183
assert kwargs["optional_literal"]["choices"] == ["x", "y", "None"]
184
# tuples should have the correct nargs
@@ -197,6 +206,32 @@ def test_get_kwargs():
206
assert kwargs["nested_config"]["type"]('{"field": 2}') == NestedConfig(2) # type: ignore[call-arg]
207
208
209
+def test_hf_token_get_kwargs():
210
+ kwargs = get_kwargs(ModelConfig)["hf_token"]
211
+
212
+ assert kwargs["type"] is str
213
+ assert kwargs["nargs"] == "?"
214
+ assert kwargs["const"] is True
215
+ assert "action" not in kwargs
216
+
217
+
218
+@pytest.mark.parametrize(
219
+ ("cli_args", "expected"),
220
+ [
221
+ ([], None),
222
+ (["--hf-token"], True),
223
+ (["--hf-token", "hf_secret"], "hf_secret"),
224
+ (["--hf-token", "None"], "None"),
225
+ ],
226
+)
227
+def test_hf_token_cli_arg(cli_args, expected):
228
+ parser = EngineArgs.add_cli_args(FlexibleArgumentParser())
229
+
230
+ args = parser.parse_args(cli_args)
231
+
232
+ assert args.hf_token == expected
233
+
234
+
235
@pytest.mark.parametrize(
236
("arg", "expected"),
237
[
vllm/engine/arg_utils.py
+6
-10
@@ -335,6 +335,11 @@ def _compute_kwargs(cls: ConfigType) -> dict[str, dict[str, Any]]:
335
kwargs[name]["type"] = parse_dataclass
336
kwargs[name]["help"] += _maybe_add_docs_url(dataclass_cls)
337
kwargs[name]["help"] += f"\n\n{json_tip}"
338
+ elif type_hints == {bool, str, type(None)}:
339
+ # Optional-valued flag: bare flag -> True, value -> str.
340
+ kwargs[name]["type"] = str
341
+ kwargs[name]["nargs"] = "?"
342
+ kwargs[name]["const"] = True
343
elif contains_type(type_hints, bool):
344
# Creates --no-<name> and --<name> flags
345
kwargs[name]["action"] = argparse.BooleanOptionalAction
@@ -801,16 +806,7 @@ class EngineArgs:
806
"--served-model-name", **model_kwargs["served_model_name"]
807
)
808
model_group.add_argument("--config-format", **model_kwargs["config_format"])
804
- # This one is a special case because it can bool
805
- # or str. TODO: Handle this in get_kwargs
806
- model_group.add_argument(
807
- "--hf-token",
808
- type=str,
809
- nargs="?",
810
- const=True,
811
- default=model_kwargs["hf_token"]["default"],
812
- help=model_kwargs["hf_token"]["help"],
813
- )
809
+ model_group.add_argument("--hf-token", **model_kwargs["hf_token"])
810
model_group.add_argument("--hf-overrides", **model_kwargs["hf_overrides"])
811
model_group.add_argument("--pooler-config", **model_kwargs["pooler_config"])
812
model_group.add_argument(