@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / ca1969186d
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 9, 11:15 UTC

[UX] Enable nested configs in config yaml files (#33193)

Michael Goin committed Jan 28, 2026 at 16:54 UTC ca1969186dde5fc0f76d22f2124dc0e6e0c9b792
2 files changed +70 -7
tests/utils_/test_argparse_utils.py
+44
@@ -379,6 +379,50 @@ def test_load_config_file(tmp_path):
379 os.remove(str(config_file_path))
380
381
382 +def test_load_config_file_nested(tmp_path):
383 + """Test that nested dicts in YAML config are converted to JSON strings."""
384 + config_data = {
385 + "port": 8000,
386 + "compilation-config": {
387 + "pass_config": {"fuse_allreduce_rms": True},
388 + },
389 + }
390 + config_file_path = tmp_path / "nested_config.yaml"
391 + with open(config_file_path, "w") as f:
392 + yaml.dump(config_data, f)
393 +
394 + parser = FlexibleArgumentParser()
395 + processed_args = parser.load_config_file(str(config_file_path))
396 +
397 + assert processed_args[processed_args.index("--port") + 1] == "8000"
398 + cc_value = json.loads(
399 + processed_args[processed_args.index("--compilation-config") + 1]
400 + )
401 + assert cc_value == {"pass_config": {"fuse_allreduce_rms": True}}
402 +
403 +
404 +def test_nested_config_end_to_end(tmp_path):
405 + """Test end-to-end parsing of nested configs in YAML files."""
406 + config_data = {
407 + "compilation-config": {
408 + "mode": 3,
409 + "pass_config": {"fuse_allreduce_rms": True},
410 + },
411 + }
412 + config_file_path = tmp_path / "nested_config.yaml"
413 + with open(config_file_path, "w") as f:
414 + yaml.dump(config_data, f)
415 +
416 + parser = FlexibleArgumentParser()
417 + parser.add_argument("-cc", "--compilation-config", type=json.loads)
418 + args = parser.parse_args(["--config", str(config_file_path)])
419 +
420 + assert args.compilation_config == {
421 + "mode": 3,
422 + "pass_config": {"fuse_allreduce_rms": True},
423 + }
424 +
425 +
426 def test_compilation_mode_string_values(parser):
427 """Test that -cc.mode accepts both integer and string mode values."""
428 args = parser.parse_args(["-cc.mode", "0"])
vllm/utils/argparse_utils.py
+26 -7
@@ -444,16 +444,30 @@ class FlexibleArgumentParser(ArgumentParser):
444
445 def load_config_file(self, file_path: str) -> list[str]:
446 """Loads a yaml file and returns the key value pairs as a
447 - flattened list with argparse like pattern
447 + flattened list with argparse like pattern.
448 +
449 + Supports both flat configs and nested YAML structures.
450 +
451 + Flat config example:
452 ```yaml
453 port: 12323
454 tensor-parallel-size: 4
455 ```
456 returns:
453 - processed_args: list[str] = [
454 - '--port': '12323',
455 - '--tensor-parallel-size': '4'
456 - ]
457 + ['--port', '12323', '--tensor-parallel-size', '4']
458 +
459 + Nested config example:
460 + ```yaml
461 + compilation-config:
462 + pass_config:
463 + fuse_allreduce_rms: true
464 + speculative-config:
465 + model: "nvidia/gpt-oss-120b-Eagle3-v2"
466 + num_speculative_tokens: 3
467 + ```
468 + returns:
469 + ['--compilation-config', '{"pass_config": {"fuse_allreduce_rms": true}}',
470 + '--speculative-config', '{"model": "nvidia/gpt-oss-120b-Eagle3-v2", ...}']
471 """
472 extension: str = file_path.split(".")[-1]
473 if extension not in ("yaml", "yml"):
@@ -461,10 +475,10 @@ class FlexibleArgumentParser(ArgumentParser):
475 f"Config file must be of a yaml/yml type. {extension} supplied"
476 )
477
464 - # only expecting a flat dictionary of atomic types
478 + # Supports both flat configs and nested dicts
479 processed_args: list[str] = []
480
467 - config: dict[str, int | str] = {}
481 + config: dict[str, Any] = {}
482 try:
483 with open(file_path) as config_file:
484 config = yaml.safe_load(config_file)
@@ -484,6 +498,11 @@ class FlexibleArgumentParser(ArgumentParser):
498 processed_args.append("--" + key)
499 for item in value:
500 processed_args.append(str(item))
501 + elif isinstance(value, dict):
502 + # Convert nested dicts to JSON strings so they can be parsed
503 + # by the existing JSON argument parsing machinery.
504 + processed_args.append("--" + key)
505 + processed_args.append(json.dumps(value))
506 else:
507 processed_args.append("--" + key)
508 processed_args.append(str(value))