From a7e6c412abf7cd26099265ab14e22c3d02b4ace5 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Sat, 12 Sep 2026 21:29:10 +0800 Subject: [PATCH] [Edge] A deploy YAML must mean the same thing whichever flag loaded it `vllm_omni/deploy/edge/qwen3_tts.yaml` carries `orchestrator: parallel_stage_init: true`, but `_apply_profile_orchestrator_defaults` ran only on the `deploy_profile` path. Pointing `--deploy-config` at the same file loaded its stages and silently dropped the block, so the edge deployment started sequentially: --deploy-profile edge 30.76 s --deploy-config .../edge/qwen3_tts.yaml 63.76 s (same file) with nothing in the log to say why. The block now applies however the config was reached. Explicit arguments still win, and the allow-list stays narrow -- a test checks an unrecognised key cannot be injected through it. Co-Authored-By: Claude Opus 5 (1M context) --- tests/config/test_deploy_profiles.py | 52 ++++++++++++++++++++++++++++ vllm_omni/entrypoints/utils.py | 9 +++++ 2 files changed, 61 insertions(+) diff --git a/tests/config/test_deploy_profiles.py b/tests/config/test_deploy_profiles.py index 086052d3f..f1b0dfe40 100644 --- a/tests/config/test_deploy_profiles.py +++ b/tests/config/test_deploy_profiles.py @@ -98,3 +98,55 @@ def test_edge_profile_carries_parallel_stage_init(): assert args["parallel_stage_init"] is True # unknown block keys are ignored assert "init_timeout" not in args + + +@pytest.mark.core_model +@pytest.mark.cpu +def test_orchestrator_block_applies_however_the_config_was_loaded(tmp_path): + """A deploy YAML must mean the same thing whichever flag loaded it. + + Applying the `orchestrator:` block only on the profile path made + `--deploy-config deploy/edge/qwen3_tts.yaml` load the stages but drop + `parallel_stage_init: true`, so an edge deployment started sequentially + (63.8 s against 30.5 s on Qwen3-TTS) with nothing in the log to say why. + """ + from vllm_omni.entrypoints import utils as entry_utils + + path = tmp_path / "profile.yaml" + path.write_text( + "pipeline: qwen3_tts\n" + "orchestrator:\n" + " parallel_stage_init: true\n" + " stage_init_timeout: 900\n", + encoding="utf-8", + ) + out = entry_utils.apply_deploy_profile("m", {"deploy_config": str(path)}) + assert out["parallel_stage_init"] is True + assert out["stage_init_timeout"] == 900 + + +@pytest.mark.core_model +@pytest.mark.cpu +def test_explicit_arguments_still_beat_the_orchestrator_block(tmp_path): + from vllm_omni.entrypoints import utils as entry_utils + + path = tmp_path / "profile.yaml" + path.write_text("orchestrator:\n stage_init_timeout: 900\n", encoding="utf-8") + out = entry_utils.apply_deploy_profile( + "m", {"deploy_config": str(path), "stage_init_timeout": 120}) + assert out["stage_init_timeout"] == 120 + + +@pytest.mark.core_model +@pytest.mark.cpu +def test_unknown_orchestrator_keys_are_ignored(tmp_path): + """The block is a narrow allow-list, not a way to inject arbitrary args.""" + from vllm_omni.entrypoints import utils as entry_utils + + path = tmp_path / "profile.yaml" + path.write_text( + "orchestrator:\n parallel_stage_init: true\n rm_rf_slash: true\n", + encoding="utf-8") + out = entry_utils.apply_deploy_profile("m", {"deploy_config": str(path)}) + assert out["parallel_stage_init"] is True + assert "rm_rf_slash" not in out diff --git a/vllm_omni/entrypoints/utils.py b/vllm_omni/entrypoints/utils.py index d2cbbbb1c..4ece99d2c 100644 --- a/vllm_omni/entrypoints/utils.py +++ b/vllm_omni/entrypoints/utils.py @@ -325,6 +325,15 @@ def apply_deploy_profile(model: str, args_dict: dict[str, Any]) -> dict[str, Any """Translate ``deploy_profile`` into ``deploy_config`` in-place (used by CLI and engine).""" profile = args_dict.pop("deploy_profile", None) if not profile: + # A deploy YAML carries the same `orchestrator:` block whichever flag + # loaded it. Applying it only on the profile path made the file mean + # different things depending on how it was passed, silently: pointing + # --deploy-config at deploy/edge/qwen3_tts.yaml loaded its stages but + # dropped `parallel_stage_init: true`, so an edge deployment started + # sequentially -- 63.8 s instead of 30.5 s on Qwen3-TTS -- with nothing + # in the log to say why. + if args_dict.get("deploy_config"): + _apply_profile_orchestrator_defaults(args_dict["deploy_config"], args_dict) return args_dict if args_dict.get("deploy_config"): raise ValueError("`deploy_profile` and `deploy_config` are mutually exclusive; pass only one.")