[Bugfix][Rust Frontend] Fix startup with config-only model (#58643)

Signed-off-by: louie-tsai <louie.tsai@intel.com>

Louie Tsai committed Sep 29, 2026 at 03:11 UTC 208bb38c80984e29c03282d295d50325f5895338
2 files changed +56
tests/entrypoints/launchers/api_server/test_api_server_process_manager.py
+46
@@ -489,3 +489,49 @@ def test_rust_frontend_launch_log_redacts_credentials(monkeypatch, caplog):
489 assert hf_token not in message
490 assert api_key not in message
491 assert '"hf_token": "***"' in message
492 +
493 +
494 +def test_rust_frontend_uses_config_model_as_model_tag(monkeypatch, caplog, tmp_path):
495 + """Config-only model selection must be forwarded to the Rust frontend."""
496 + import subprocess as subprocess_mod
497 +
498 + from vllm.entrypoints.launchers.cli_args import make_arg_parser
499 + from vllm.utils.argparse_utils import FlexibleArgumentParser
500 + from vllm.v1.utils import RustFrontendProcessManager
501 +
502 + config_path = tmp_path / "config.yml"
503 + config_path.write_text("model: org/model\n")
504 + args = make_arg_parser(FlexibleArgumentParser()).parse_args(
505 + ["--config", str(config_path)]
506 + )
507 + assert args.model == "org/model"
508 + assert args.model_tag is None
509 +
510 + class _FakeProc:
511 + pid = 4321
512 + returncode = 0
513 +
514 + def poll(self):
515 + return 0
516 +
517 + def wait(self, timeout=None):
518 + return 0
519 +
520 + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
521 + try:
522 + monkeypatch.setattr(subprocess_mod, "Popen", lambda *a, **kw: _FakeProc())
523 + with caplog.at_level("INFO", logger="vllm.v1.utils"):
524 + RustFrontendProcessManager(
525 + binary_path="/nonexistent/vllm-rs",
526 + sock=sock,
527 + args=args,
528 + input_address="ipc:///tmp/in",
529 + output_address="ipc:///tmp/out",
530 + engine_start_index=0,
531 + engine_count=1,
532 + data_parallel_size=1,
533 + )
534 + finally:
535 + sock.close()
536 +
537 + assert '"model_tag": "org/model"' in caplog.text
vllm/v1/utils.py
+10
@@ -391,6 +391,16 @@ class RustFrontendProcessManager:
391 "data_parallel_hybrid_lb",
392 },
393 )
394 +
395 + # `model_tag` is the positional `vllm serve` model argument. When the
396 + # model is supplied only through `--config`, argparse populates `model`
397 + # while leaving `model_tag` unset. The Rust frontend requires
398 + # `model_tag` in its JSON bootstrap payload, so use the resolved model
399 + # as a fallback.
400 + model_tag = getattr(args, "model_tag", None) or getattr(args, "model", None)
401 + if model_tag is not None:
402 + args_dict["model_tag"] = model_tag
403 +
404 # The Rust `frontend` subcommand parses --args-json via serde_json,
405 # which bypasses clap and therefore ignores any `#[arg(env = ...)]`
406 # declarations on SharedRuntimeArgs fields. Forward the env-driven