From 60a933b9ab522a02d83002fde0342c27a54217ef Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Mon, 21 Sep 2026 11:56:06 -0700 Subject: [PATCH] [Model] Default Qwen3-TTS to experimental Model Runner V2 (#7930) Signed-off-by: Sy03 <1370724210@qq.com> --- docs/configuration/stage_configs.md | 16 +++++++++----- recipes/Qwen/Qwen3-TTS.md | 6 ++++-- tests/config/test_omni_config.py | 32 +++++++++++++++++----------- vllm_omni/deploy/qwen3_tts.yaml | 20 +++++++++++++++-- vllm_omni/deploy/qwen3_tts_mrv2.yaml | 4 +++- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/docs/configuration/stage_configs.md b/docs/configuration/stage_configs.md index 2540b19d9..9836bcff9 100644 --- a/docs/configuration/stage_configs.md +++ b/docs/configuration/stage_configs.md @@ -293,19 +293,25 @@ vllm serve Qwen/Qwen2.5-Omni-7B --omni --port 8091 --deploy-config /path/to/depl ## Qwen3-TTS with Model Runner V2 -Qwen3-TTS can opt into the native CUDA Model Runner V2 pipeline on vLLM -0.29.0. Select one of these deployment profiles: +Qwen3-TTS runs the native CUDA Model Runner V2 pipeline by default on vLLM +0.29.0. MRV2 is an experimental feature for this model: the bundled default +profile selects it on CUDA only, and its scheduler and delivery paths are +still being qualified. Set `model_runner: v1` in a copy of the deploy config +to opt out; the `platforms:` sections of `qwen3_tts.yaml` keep V1 on NPU, XPU, +ROCm and MUSA. Select one of these deployment profiles: | Profile | Runner | Code2Wav graph batches | Intended use | | --- | --- | --- | --- | -| `qwen3_tts.yaml` | V1 | Existing defaults | Existing deployment / regression control | -| `qwen3_tts_mrv2.yaml` | V2 | B1 | Native runner validation | +| `qwen3_tts.yaml` | V2 (default) | Existing defaults | Shipped default; experimental | +| `qwen3_tts_mrv2.yaml` | V2 | B1 | Explicit MRV2 profile (same runner selection as the default) | | `qwen3_tts_high_concurrency_mrv2.yaml` | V2 | B1, B2 | Opt-in throughput tuning | | `qwen3_tts_high_concurrency_mrv2_b4.yaml` | V2 | B1, B2, B3, B4 | Experimental throughput / buffered playback | +| `qwen3_tts_high_concurrency.yaml` | V1 | Existing defaults | V1 high-concurrency control | ```bash +# MRV2 is the default; pass a copy with `model_runner: v1` to force V1. vllm serve Qwen/Qwen3-TTS-12Hz-1.7B-Base --omni \ - --deploy-config vllm_omni/deploy/qwen3_tts_mrv2.yaml + --deploy-config /path/to/qwen3_tts_v1.yaml ``` The V2 profiles bound Talker prefill to 512 tokens per step and select the diff --git a/recipes/Qwen/Qwen3-TTS.md b/recipes/Qwen/Qwen3-TTS.md index d0dbe57df..d6a1a850c 100644 --- a/recipes/Qwen/Qwen3-TTS.md +++ b/recipes/Qwen/Qwen3-TTS.md @@ -71,8 +71,10 @@ Alternatively, use the convenience script: ``` The bundled deploy config (`vllm_omni/deploy/qwen3_tts.yaml`) enables async -chunking for low first-audio latency. For advanced deployment tuning, pass a -custom deploy config: +chunking for low first-audio latency, and selects the experimental Model +Runner V2 on CUDA. Copy it and set `model_runner: v1` to run V1; NPU, XPU, +ROCm and MUSA keep V1 through the `platforms:` sections. For advanced +deployment tuning, pass a custom deploy config: ```bash vllm serve Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice \ diff --git a/tests/config/test_omni_config.py b/tests/config/test_omni_config.py index 331717ba6..d589fde2b 100644 --- a/tests/config/test_omni_config.py +++ b/tests/config/test_omni_config.py @@ -816,19 +816,25 @@ def test_mrv2_fails_fast_on_platforms_without_native_workers(platform: str): _apply_platform_overrides(DeployConfig(model_runner="v2"), platform=platform) -@pytest.mark.parametrize( - ("default_name", "mrv2_name"), - [ - ("qwen3_tts.yaml", "qwen3_tts_mrv2.yaml"), - ( - "qwen3_tts_high_concurrency.yaml", - "qwen3_tts_high_concurrency_mrv2.yaml", - ), - ], -) -def test_qwen3_mrv2_profiles_are_explicit_opt_in(default_name: str, mrv2_name: str): - assert load_deploy_config(_DEPLOY_DIR / default_name).model_runner == "v1" - assert load_deploy_config(_DEPLOY_DIR / mrv2_name).model_runner == "v2" +def test_qwen3_tts_high_concurrency_mrv2_profile_is_explicit_opt_in(): + assert load_deploy_config(_DEPLOY_DIR / "qwen3_tts_high_concurrency.yaml").model_runner == "v1" + assert load_deploy_config(_DEPLOY_DIR / "qwen3_tts_high_concurrency_mrv2.yaml").model_runner == "v2" + + +def test_qwen3_tts_default_profile_is_experimental_mrv2_with_v1_platform_fallback(): + deploy_path = _DEPLOY_DIR / "qwen3_tts.yaml" + assert load_deploy_config(deploy_path).model_runner == "v2" + + pipeline = _resolve_pipeline_or_skip("qwen3_tts") + stages = merge_pipeline_deploy(pipeline, load_deploy_config(deploy_path)) + assert all(stage.yaml_engine_args["use_v2_model_runner"] is True for stage in stages) + + assert _apply_platform_overrides(load_deploy_config(deploy_path), platform="cuda").model_runner == "v2" + for platform in ("npu", "xpu", "rocm", "musa"): + assert _apply_platform_overrides(load_deploy_config(deploy_path), platform=platform).model_runner == "v1" + + # The explicit MRV2 profile resolves to the same runner selection. + assert load_deploy_config(_DEPLOY_DIR / "qwen3_tts_mrv2.yaml").model_runner == "v2" def test_qwen3_tts_mrv2_retunes_do_not_change_default_mrv1_profile(): diff --git a/vllm_omni/deploy/qwen3_tts.yaml b/vllm_omni/deploy/qwen3_tts.yaml index 8f5ab584d..f3ebe80f6 100644 --- a/vllm_omni/deploy/qwen3_tts.yaml +++ b/vllm_omni/deploy/qwen3_tts.yaml @@ -1,16 +1,23 @@ # Qwen3-TTS deploy: talker → code2wav via shared-memory chunk streaming. # Verified on 1x H100. # +# Runner selection: +# Model Runner V2 (MRV2) is EXPERIMENTAL and is the default runner on CUDA +# for this model. Set `model_runner: v1` to opt out. The `platforms:` +# sections at the end of this file keep V1 on NPU, XPU, ROCm and MUSA. +# See docs/configuration/stage_configs.md ("Qwen3-TTS with Model Runner V2"). +# # Fields omitted from a stage fall back to StageDeployConfig defaults (see # vllm_omni/config/stage_config.py). Notable choices for this model: # * Stage 0 (talker) sets max_num_batched_tokens=512 for async-chunk # latency tuning (not correctness) — small per-step batches keep -# first-chunk latency low. +# first-chunk latency low, and the MRV2 profiles rely on that bound. # * Stage 1 (code2wav) sets max_num_batched_tokens=65536 for correctness: # codec prefill length (Q * num_frames) exceeds the 32k default. # * Stage 0 does not set enforce_eager — talker runs cudagraph by default. # Stage 1 defaults to false so Code2Wav can use its inner cudagraph; # set true to disable that path in eager mode. +model_runner: v2 async_chunk: true connectors: @@ -71,7 +78,9 @@ stages: # See docs/design/feature/prefix_caching.md for the stage matrix. enable_prefix_caching: false async_scheduling: true - max_num_batched_tokens: 32768 + # Bound per-step prefill work (validated MRV2 basic profile). Small + # per-step batches keep first-chunk latency low. + max_num_batched_tokens: 512 max_model_len: 4096 devices: "0" output_connectors: @@ -124,6 +133,8 @@ stages: platforms: rocm: + # MRV2 is not qualified on ROCm; keep the legacy V1 runner. + model_runner: v1 stages: - stage_id: 1 # MIOpen Conv1d cannot be invoked while vLLM captures the outer @@ -131,6 +142,7 @@ platforms: # Stage 1 eager on ROCm so decoder convolutions execute normally. enforce_eager: true npu: + model_runner: v1 stages: - stage_id: 0 enforce_eager: false @@ -139,3 +151,7 @@ platforms: - stage_id: 1 compilation_config: cudagraph_mode: PIECEWISE + xpu: + model_runner: v1 + musa: + model_runner: v1 diff --git a/vllm_omni/deploy/qwen3_tts_mrv2.yaml b/vllm_omni/deploy/qwen3_tts_mrv2.yaml index 228076c8e..180d55b5c 100644 --- a/vllm_omni/deploy/qwen3_tts_mrv2.yaml +++ b/vllm_omni/deploy/qwen3_tts_mrv2.yaml @@ -1,4 +1,6 @@ -# Opt-in CUDA Model Runner V2 profile. The base profile retains V1. +# Explicit CUDA Model Runner V2 profile. `qwen3_tts.yaml` now selects V2 by +# default (experimental); this file is kept for scripts that name the MRV2 +# profile explicitly and for the platform fallbacks below. base_config: qwen3_tts.yaml model_runner: v2