[Config Refactor] Migrate Ming and Ming-TTS deploy/pipline configs (#3154)

Signed-off-by: Yuanheng Zhao <jonathan.zhaoyh@gmail.com>
Signed-off-by: yuanheng <jonathan.zhaoyh@gmail.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
This commit is contained in:
Yuanheng ZhaoandHongsheng Liu authored and GitHub committed 2026-05-03 14:43:49 +12:00
1 parent 6a837849dd
commit d49356e4ca
25 files changed
+518 -398

No files matched your search

@@ -4,10 +4,10 @@
vLLM-Omni supports two deployment modes:
| Mode | Stage config | Output |
|------|-------------|--------|
| Thinker only (multimodal understanding) | `ming_flash_omni_thinker.yaml` (default `--omni`) | Text |
| Thinker + Talker (omni-speech) | `ming_flash_omni.yaml` | Text + Audio |
| Mode | Deploy config | Output |
|------|--------------|--------|
| Thinker + Talker (omni-speech, default) | `vllm_omni/deploy/ming_flash_omni.yaml` | Text + Audio |
| Thinker only (multimodal understanding) | `vllm_omni/deploy/ming_flash_omni_thinker_only.yaml` | Text |
For standalone TTS (talker only), see [`examples/offline_inference/ming_flash_omni_tts/`](../ming_flash_omni_tts/).
@@ -15,30 +15,30 @@ For standalone TTS (talker only), see [`examples/offline_inference/ming_flash_om
Please refer to the [stage configuration documentation](https://docs.vllm.ai/projects/vllm-omni/en/latest/configuration/stage_configs/) to configure memory allocation appropriately for your hardware setup.
The default `--omni` flag runs thinker only. For omni-speech, pass the two-stage config explicitly:
When no `--deploy-config` is passed, the model registry auto-loads the full thinker+talker `vllm_omni/deploy/ming_flash_omni.yaml` (See [Omni-Speech](#omni-speech-thinker--talker)).
For text-only output without spinning up the talker, pass:
```bash
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni.yaml
--deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml
```
## Run examples
The end-to-end script defaults to built-in assets; pass `--image-path`,
`--audio-path`, or `--video-path` to override.
The end-to-end script defaults to built-in assets; pass `--image-path`, `--audio-path`, or `--video-path` to override.
### Multi-Modality Understanding (Standalone Thinker)
Here we pass thinker-only deploy yaml:
```bash
# Text-only
python examples/offline_inference/ming_flash_omni/end2end.py --query-type text
# Image / audio / video / mixed understanding
python examples/offline_inference/ming_flash_omni/end2end.py --query-type use_image
python examples/offline_inference/ming_flash_omni/end2end.py --query-type use_audio
python examples/offline_inference/ming_flash_omni/end2end.py --query-type use_video --num-frames 16
python examples/offline_inference/ming_flash_omni/end2end.py --query-type use_mixed_modalities \
--image-path /path/to/image.jpg --audio-path /path/to/audio.wav
python examples/offline_inference/ming_flash_omni/end2end.py --deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml --query-type text
python examples/offline_inference/ming_flash_omni/end2end.py --deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml --query-type use_image
python examples/offline_inference/ming_flash_omni/end2end.py --deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml --query-type use_audio
python examples/offline_inference/ming_flash_omni/end2end.py --deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml --query-type use_video --num-frames 16
```
#### Reasoning (Thinking Mode)
### Reasoning (Thinking Mode)
Reasoning ("detailed thinking on") is applied by the script when
`--query-type reasoning` is set. The default prompt matches Ming's cookbook
@@ -46,19 +46,21 @@ and expects the reference figure from the upstream repo — see
`get_reasoning_query` in `end2end.py`.
```bash
python examples/offline_inference/ming_flash_omni/end2end.py -q reasoning --image-path ./3_0.png
python examples/offline_inference/ming_flash_omni/end2end.py \
--deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml \
--query-type reasoning \
--image-path ./3_0.png
```
### Omni-speech (thinker + talker)
### Omni-Speech (Thinker + Talker)
To enable spoken output, use the two-stage config and request `audio` (or `text,audio`) modalities.
The default deploy YAML already runs thinker+talker, so spoken output only requires requesting `audio` (or `text,audio`) modalities.
The thinker processes your multimodal input, generates text, then the talker synthesises the response as speech.
**Audio-only output** (speech response, no text):
```bash
python examples/offline_inference/ming_flash_omni/end2end.py \
--query-type text \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni.yaml \
--modalities audio \
--output-dir output_ming_omni_speech
```
@@ -67,14 +69,13 @@ python examples/offline_inference/ming_flash_omni/end2end.py \
```bash
python examples/offline_inference/ming_flash_omni/end2end.py \
--query-type use_audio \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni.yaml \
--modalities text,audio \
--output-dir output_ming_omni_speech
```
Generated `.wav` files are saved to `--output-dir` (default `output_ming`), one per request.
The stage config allocates thinker on GPUs 0–3 and talker on GPU 3 by default. Adjust `devices` in the YAML to match your hardware.
The default deploy YAML allocates thinker on GPUs 0–3 and talker on GPU 3 for a common device topology (4 rather than 5 devices that talker on its own device). Adjust `devices` in a copied YAML and pass it via `--deploy-config` to match your hardware or requirements.
### Modality control
@@ -84,8 +85,7 @@ The stage config allocates thinker on GPUs 0–3 and talker on GPU 3 by default.
| `audio` | Text (internal) | Runs | `<id>.wav` |
| `text,audio` | Text | Runs | `<id>.txt` + `<id>.wav` |
Pass `--stage-configs-path /path/to/your_config.yaml` to any of the commands
above to override the stage config.
Pass `--deploy-config /path/to/your_deploy.yaml` to any of the commands above to override the bundled deploy config.
## Online serving
@@ -20,6 +20,7 @@ from vllm.multimodal.media.audio import load_audio
from vllm.utils.argparse_utils import FlexibleArgumentParser
import vllm_omni
from vllm_omni.engine.arg_utils import nullify_stage_engine_defaults
from vllm_omni.entrypoints.omni import Omni
# Imports the processor also registers itself
@@ -302,14 +303,7 @@ def main(args):
else:
query_result = query_func(processor)
# Initialize Omni (with thinker-only stage config)
omni = Omni(
model=MODEL_NAME,
stage_configs_path=args.stage_configs_path,
log_stats=args.log_stats,
init_timeout=args.init_timeout,
stage_init_timeout=args.stage_init_timeout,
)
omni = Omni.from_cli_args(args, model=MODEL_NAME)
# Thinker sampling params
thinker_sampling_params = SamplingParams(
@@ -410,10 +404,10 @@ def parse_args():
help="Query type.",
)
parser.add_argument(
"--stage-configs-path",
"--deploy-config",
type=str,
default=None,
help="Path to a stage configs YAML file.",
help="Path to a deploy YAML; leave unset to auto-load full thinker+talker. Pass custom for text-only",
)
parser.add_argument(
"--log-stats",
@@ -499,6 +493,7 @@ def parse_args():
help="Output directory for results.",
)
nullify_stage_engine_defaults(parser)
return parser.parse_args()
@@ -3,7 +3,7 @@
This example runs **Ming-flash-omni-2.0 talker-only** offline inference with:
- `model`: `Jonathan1909/Ming-flash-omni-2.0`
- `stage config`: `vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml`
- `deploy config`: `vllm_omni/deploy/ming_flash_omni_tts.yaml`
It follows the Ming cookbook parameter style:
@@ -37,7 +37,7 @@ python examples/offline_inference/ming_flash_omni_tts/end2end.py --case basic
- `--text`: override default text in the selected case
- `--output`: custom output wav path
- `--model`: local model path or HF repo id
- `--stage-configs-path`: custom talker stage config path
- `--deploy-config`: custom talker deploy YAML path
- `--log-stats`: enable runtime stats logs
## Notes
@@ -9,6 +9,7 @@ from vllm.utils.argparse_utils import FlexibleArgumentParser
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
from vllm_omni.engine.arg_utils import nullify_stage_engine_defaults
from vllm_omni.entrypoints.omni import Omni
from vllm_omni.inputs.data import OmniTokensPrompt
from vllm_omni.model_executor.models.ming_flash_omni.prompt_utils import (
@@ -17,7 +18,6 @@ from vllm_omni.model_executor.models.ming_flash_omni.prompt_utils import (
)
MODEL_NAME = "Jonathan1909/Ming-flash-omni-2.0"
DEFAULT_STAGE_CONFIG = "vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml"
def get_messages(case: str, text_override: str | None) -> dict[str, Any]:
@@ -71,10 +71,10 @@ def parse_args():
parser = FlexibleArgumentParser(description="Ming-flash-omni standalone talker offline e2e example")
parser.add_argument("--model", type=str, default=MODEL_NAME, help="Model name or local path.")
parser.add_argument(
"--stage-configs-path",
"--deploy-config",
type=str,
default=DEFAULT_STAGE_CONFIG,
help="Path to stage configs yaml for standalone talker deployment.",
default="vllm_omni/deploy/ming_flash_omni_tts.yaml",
help="Path to a custom deploy YAML for the TTS deployment. ",
)
parser.add_argument(
"--case",
@@ -88,19 +88,15 @@ def parse_args():
parser.add_argument("--log-stats", action="store_true", default=False, help="Enable stats logging.")
parser.add_argument("--init-timeout", type=int, default=600, help="Engine init timeout in seconds.")
parser.add_argument("--stage-init-timeout", type=int, default=300, help="Single stage init timeout in seconds.")
nullify_stage_engine_defaults(parser)
return parser.parse_args()
def main():
args = parse_args()
omni = Omni(
model=args.model,
stage_configs_path=args.stage_configs_path,
log_stats=args.log_stats,
init_timeout=args.init_timeout,
stage_init_timeout=args.stage_init_timeout,
)
omni = Omni.from_cli_args(args, model=args.model)
messages = get_messages(args.case, args.text)
decode_args = {
@@ -8,8 +8,8 @@ Please refer to [README.md](../../../README.md)
| Mode | Launch command | Output |
|------|---------------|--------|
| Thinker only (multimodal understanding) | `vllm serve ... --omni` | Text |
| Thinker + Talker (omni-speech) | `vllm serve ... --omni --stage-configs-path ming_flash_omni.yaml` | Text + Audio |
| Thinker + Talker (omni-speech, default) | `vllm serve ... --omni` | Text + Audio |
| Thinker only (multimodal understanding) | `vllm serve ... --omni --deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml` | Text |
For standalone TTS (talker only), see [`examples/online_serving/ming_flash_omni_tts/`](../ming_flash_omni_tts/).
@@ -17,18 +17,20 @@ For standalone TTS (talker only), see [`examples/online_serving/ming_flash_omni_
### Launch the Server
**Thinker only (text output):**
**Thinker + Talker (omni-speech, text + audio output):**
```bash
vllm serve Jonathan1909/Ming-flash-omni-2.0 --omni --port 8091
```
**Thinker + Talker (omni-speech, text + audio output):**
The model registry auto-loads corresponding deploy yaml.
**Thinker-only (text output):**
```bash
vllm serve Jonathan1909/Ming-flash-omni-2.0 --omni --port 8091 \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni.yaml
--deploy-config vllm_omni/deploy/ming_flash_omni_thinker_only.yaml
```
Pass `--stage-configs-path /path/to/your_config.yaml` to use a custom stage
Pass `--deploy-config /path/to/your_deploy.yaml` to use a custom deploy
config.
### Send Multi-modal Request
@@ -18,17 +18,6 @@ if [[ ! "$QUERY_TYPE" =~ ^(text|use_audio|use_image|use_video|use_mixed_modaliti
exit 1
fi
thinker_sampling_params='{
"temperature": 0.4,
"top_p": 0.9,
"top_k": -1,
"max_tokens": 16384,
"seed": 42,
"detokenize": true,
"repetition_penalty": 1.05
}'
# Above is optional, it has a default setting in stage_configs of the corresponding model.
# Define URLs for assets
MARY_HAD_LAMB_AUDIO_URL="https://vllm-public-assets.s3.us-west-2.amazonaws.com/multimodal_asset/mary_had_lamb.ogg"
CHERRY_BLOSSOM_IMAGE_URL="https://vllm-public-assets.s3.us-west-2.amazonaws.com/vision_model_images/cherry_blossom.jpg"
@@ -114,9 +103,6 @@ echo ""
request_body=$(cat <<EOF
{
"model": "Jonathan1909/Ming-flash-omni-2.0",
"sampling_params_list": [
$thinker_sampling_params
],
"modalities": ["text"],
"messages": [
{
@@ -5,7 +5,7 @@ This directory contains online e2e examples for **Ming-flash-omni-2.0 standalone
Server uses:
- `model`: `Jonathan1909/Ming-flash-omni-2.0`
- `stage config`: `vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml`
- `deploy config`: `vllm_omni/deploy/ming_flash_omni_tts.yaml`
## Launch the Server
@@ -18,7 +18,7 @@ Equivalent manual command:
```bash
vllm serve Jonathan1909/Ming-flash-omni-2.0 \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml \
--deploy-config vllm_omni/deploy/ming_flash_omni_tts.yaml \
--host 0.0.0.0 \
--port 8091 \
--trust-remote-code \
@@ -12,13 +12,13 @@ set -e
MODEL="${MODEL:-Jonathan1909/Ming-flash-omni-2.0}"
HOST="${HOST:-0.0.0.0}"
PORT="${PORT:-8091}"
STAGE_CONFIG="${STAGE_CONFIG:-vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml}"
DEPLOY_CONFIG="${DEPLOY_CONFIG:-vllm_omni/deploy/ming_flash_omni_tts.yaml}"
echo "Starting Ming standalone TTS server with model: $MODEL"
echo "Stage config: $STAGE_CONFIG"
echo "Deploy config: $DEPLOY_CONFIG"
vllm serve "$MODEL" \
--stage-configs-path "$STAGE_CONFIG" \
--deploy-config "$DEPLOY_CONFIG" \
--host "$HOST" \
--port "$PORT" \
--trust-remote-code \
+3 -4
View File
@@ -46,7 +46,7 @@ Adjust `devices` in the YAML to match your hardware.
- OS: Linux
- Python: 3.10+
- CUDA Driver Version: 590.48.01
- CUDA 12.5
- CUDA 13.0
- vLLM version: 0.19.0
- vLLM-Omni version or commit: 0.19.0rc1
@@ -64,7 +64,6 @@ Thinker + talker (text and/or audio output):
vllm serve Jonathan1909/Ming-flash-omni-2.0 \
--omni \
--port 8091 \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni.yaml \
--log-stats
```
@@ -162,7 +161,7 @@ The bundled `ming_flash_omni_tts.yaml` runs the talker on a single GPU and expos
- OS: Linux
- Python: 3.10+
- CUDA Driver Version: 590.48.01
- CUDA 12.5
- CUDA 13.0
- vLLM version: 0.19.0
- vLLM-Omni version or commit: 0.19.0rc1
@@ -171,7 +170,7 @@ The bundled `ming_flash_omni_tts.yaml` runs the talker on a single GPU and expos
```bash
vllm serve Jonathan1909/Ming-flash-omni-2.0 \
--omni \
--stage-configs-path vllm_omni/model_executor/stage_configs/ming_flash_omni_tts.yaml \
--deploy-config vllm_omni/deploy/ming_flash_omni_tts.yaml \
--port 8091 \
--log-stats
```
@@ -6,8 +6,6 @@ import os
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
os.environ["VLLM_TEST_CLEAN_GPU_MEMORY"] = "0"
from pathlib import Path
import pytest
from tests.helpers.mark import hardware_test
@@ -16,7 +14,7 @@ from tests.helpers.media import (
generate_synthetic_image,
generate_synthetic_video,
)
from tests.helpers.stage_config import modify_stage_config
from tests.helpers.stage_config import get_deploy_config_path, modify_stage_config
models = ["Jonathan1909/Ming-flash-omni-2.0"]
@@ -35,48 +33,27 @@ def build_prompt(user_text: str) -> str:
)
_CI_DEPLOY_THINKER_ONLY = get_deploy_config_path("ci/ming_flash_omni_thinker_only.yaml")
_CI_DEPLOY = get_deploy_config_path("ci/ming_flash_omni.yaml")
def get_eager_config_thinker():
return modify_stage_config(_CI_DEPLOY_THINKER_ONLY, updates={"stages": {0: {"enforce_eager": True}}})
def get_eager_config():
path = modify_stage_config(
str(Path(__file__).parent.parent / "stage_configs" / "bailingmm_moe_v2_lite_thinker_only_ci.yaml"),
updates={
"stage_args": {
0: {
"engine_args.enforce_eager": "true",
},
},
},
)
return path
def get_eager_tts_config():
"""Thinker+talker CI config with enforce_eager on the thinker stage."""
path = modify_stage_config(
str(Path(__file__).parent.parent / "stage_configs" / "bailingmm_moe_v2_lite_ci.yaml"),
updates={
"stage_args": {
0: {
"engine_args.enforce_eager": "true",
},
},
},
)
return path
return modify_stage_config(_CI_DEPLOY, updates={"stages": {0: {"enforce_eager": True}}})
# Thinker-only config — used by text-output tests.
stage_configs = [get_eager_config()]
test_params = [(model, stage_config) for model in models for stage_config in stage_configs]
# Thinker+talker config — used by audio-output tests.
stage_configs_tts = [get_eager_tts_config()]
test_params_tts = [(model, stage_config) for model in models for stage_config in stage_configs_tts]
test_params_thinker = [(m, c) for m in models for c in [get_eager_config_thinker()]]
test_params = [(m, c) for m in models for c in [get_eager_config()]]
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params_thinker, indirect=True)
def test_text_to_text(omni_runner, omni_runner_handler) -> None:
"""
Test text-only input processing and text output generation.
@@ -92,7 +69,7 @@ def test_text_to_text(omni_runner, omni_runner_handler) -> None:
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params_thinker, indirect=True)
def test_image_to_text(omni_runner, omni_runner_handler) -> None:
"""
Test image understanding with text output.
@@ -109,7 +86,7 @@ def test_image_to_text(omni_runner, omni_runner_handler) -> None:
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params_thinker, indirect=True)
def test_audio_to_text(omni_runner, omni_runner_handler) -> None:
"""
Test audio understanding with text output.
@@ -128,7 +105,7 @@ def test_audio_to_text(omni_runner, omni_runner_handler) -> None:
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params_thinker, indirect=True)
def test_video_to_text(omni_runner, omni_runner_handler) -> None:
"""
Test video understanding with text output.
@@ -145,7 +122,7 @@ def test_video_to_text(omni_runner, omni_runner_handler) -> None:
@pytest.mark.core_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params_thinker, indirect=True)
def test_mixed_to_text(omni_runner, omni_runner_handler) -> None:
"""
Test mixed modality input (image + audio) with text output.
@@ -165,7 +142,7 @@ def test_mixed_to_text(omni_runner, omni_runner_handler) -> None:
@pytest.mark.advanced_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params_tts, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
def test_text_to_audio(omni_runner, omni_runner_handler) -> None:
"""
Test text input with audio output via the thinker+talker pipeline.
@@ -181,7 +158,7 @@ def test_text_to_audio(omni_runner, omni_runner_handler) -> None:
@pytest.mark.advanced_model
@pytest.mark.omni
@hardware_test(res={"cuda": "H100"}, num_cards=4)
@pytest.mark.parametrize("omni_runner", test_params_tts, indirect=True)
@pytest.mark.parametrize("omni_runner", test_params, indirect=True)
def test_image_to_audio(omni_runner, omni_runner_handler) -> None:
"""
Test image + text input with audio output via the thinker+talker pipeline.
@@ -6,7 +6,6 @@ Tests multimodal understanding via OpenAI-compatible API.
"""
import os
from pathlib import Path
import pytest
@@ -17,29 +16,17 @@ from tests.helpers.media import (
generate_synthetic_video,
)
from tests.helpers.runtime import OmniServerParams, dummy_messages_from_mix_data
from tests.helpers.stage_config import modify_stage_config
from tests.helpers.stage_config import get_deploy_config_path
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
os.environ["VLLM_TEST_CLEAN_GPU_MEMORY"] = "0"
models = ["Jonathan1909/Ming-flash-omni-2.0"]
# Use thinker-only topology to test text outputs
_CI_DEPLOY = get_deploy_config_path("ci/ming_flash_omni_thinker_only.yaml")
def get_eager_config():
path = modify_stage_config(
str(Path(__file__).parent.parent / "stage_configs" / "bailingmm_moe_v2_lite_ci.yaml"),
updates={
"stage_args": {
0: {
"engine_args.enforce_eager": "true",
},
},
},
)
return path
stage_configs = [get_eager_config()]
stage_configs = [_CI_DEPLOY]
# Create parameter combinations for model and stage config
test_params = [
@@ -1,75 +0,0 @@
# CI stage config for Ming-flash-omni-2.0 thinker+talker pipeline.
# Stage 0: Thinker (multimodal understanding -> text generation)
# Stage 1: Talker (text -> audio waveform via CFM + AudioVAE)
#
# The following config has been verified on 4x H100-80G GPUs
stage_args:
- stage_id: 0
stage_type: llm
runtime:
devices: "0,1,2,3"
max_batch_size: 1
engine_args:
model_stage: thinker
model_arch: MingFlashOmniForConditionalGeneration
worker_type: ar
scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler
gpu_memory_utilization: 0.74
enforce_eager: false
trust_remote_code: true
# Ming Thinker -> talker bridge reads detokenised text from
# source_output.outputs[0].text (not hidden states).
engine_output_type: text
distributed_executor_backend: "mp"
enable_prefix_caching: false
max_num_batched_tokens: 32768
max_model_len: 32768
tensor_parallel_size: 4
hf_config_name: llm_config
load_format: dummy
mm_processor_cache_gb: 0
compilation_config:
pass_config:
# Disable fused all-reduce to avoid a vllm/flashinfer version mismatch.
fuse_allreduce_rms: false
final_output: true
final_output_type: text
is_comprehension: true
default_sampling_params:
temperature: 0.0
top_p: 0.9
max_tokens: 100
repetition_penalty: 1.05
seed: 42
detokenize: true
ignore_eos: false
- stage_id: 1
stage_type: llm
runtime:
devices: "3"
max_batch_size: 1
engine_args:
model_stage: ming_tts
model_arch: MingFlashOmniTalkerForConditionalGeneration
worker_cls: vllm_omni.worker.gpu_generation_worker.GPUGenerationWorker
scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler
gpu_memory_utilization: 0.18
enforce_eager: true
trust_remote_code: true
engine_output_type: audio
enable_prefix_caching: false
max_num_batched_tokens: 1000000
tokenizer_subdir: talker/llm
# The HF repo ships BailingMM2Config (thinker-only) at root;
# OmniModelConfig treats that as "stage does not share outer mrope".
hf_config_name: talker_config
load_format: dummy
engine_input_source: [0]
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.ming_flash_omni.thinker2talker
final_output: true
final_output_type: audio
default_sampling_params:
temperature: 0.0
max_tokens: 1
seed: 42
@@ -1,35 +0,0 @@
# Thinker stage only
stage_args:
- stage_id: 0
stage_type: llm
runtime:
devices: "0,1,2,3"
max_batch_size: 1
engine_args:
model_stage: thinker
model_arch: MingFlashOmniForConditionalGeneration
worker_type: ar
scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler
gpu_memory_utilization: 0.9
enforce_eager: false
trust_remote_code: true
engine_output_type: latent
distributed_executor_backend: "mp"
enable_prefix_caching: false
max_num_batched_tokens: 32768
max_model_len: 32768
tensor_parallel_size: 4
hf_config_name: llm_config
load_format: dummy
mm_processor_cache_gb: 0
final_output: true
final_output_type: text
is_comprehension: true
default_sampling_params:
temperature: 0.4
top_p: 0.9
max_tokens: 100
repetition_penalty: 1.05
seed: 42
detokenize: true
ignore_eos: false
+46
View File
@@ -484,6 +484,52 @@ _CI_OVERLAYS: dict[str, dict[str, Any]] = {
},
},
},
"ming_flash_omni": {
"base_config": "ming_flash_omni.yaml",
"stages": [
{
"stage_id": 0,
"max_num_seqs": 1,
"gpu_memory_utilization": 0.74,
"max_model_len": 16384,
"max_num_batched_tokens": 16384,
"mm_processor_cache_gb": 0,
"skip_mm_profiling": True,
"enable_flashinfer_autotune": False,
"load_format": "dummy",
"default_sampling_params": {
"temperature": 0.0,
"max_tokens": 100,
},
},
{
"stage_id": 1,
"max_num_seqs": 1,
"gpu_memory_utilization": 0.18,
"load_format": "dummy",
},
],
},
"ming_flash_omni_thinker_only": {
"base_config": "ming_flash_omni_thinker_only.yaml",
"stages": [
{
"stage_id": 0,
"max_num_seqs": 1,
"gpu_memory_utilization": 0.9,
"max_model_len": 16384,
"max_num_batched_tokens": 16384,
"mm_processor_cache_gb": 0,
"skip_mm_profiling": True,
"enable_flashinfer_autotune": False,
"load_format": "dummy",
"default_sampling_params": {
"temperature": 0.4,
"max_tokens": 100,
},
},
],
},
# Single-stage thinker-only topology for the abort test.
"qwen2_5_omni_thinker_only": {
"async_chunk": False,
+156
View File
@@ -997,6 +997,162 @@ class TestQwen3TTSPipeline:
}
class TestMingFlashOmniPipeline:
def test_registered(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
p = _PIPELINE_REGISTRY.get("ming_flash_omni")
assert p is not None
assert p.model_arch == "MingFlashOmniForConditionalGeneration"
assert len(p.stages) == 2
assert p.validate() == []
def test_thinker_stage(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
s = _PIPELINE_REGISTRY["ming_flash_omni"].get_stage(0)
assert s.model_stage == "thinker"
assert s.execution_type == StageExecutionType.LLM_AR
assert s.owns_tokenizer is True
assert s.requires_multimodal_data is True
assert s.engine_output_type == "text"
assert s.hf_config_name == "llm_config"
assert s.sampling_constraints["detokenize"] is True
def test_talker_stage(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
s = _PIPELINE_REGISTRY["ming_flash_omni"].get_stage(1)
assert s.model_stage == "ming_tts"
assert s.execution_type == StageExecutionType.LLM_GENERATION
assert s.input_sources == (0,)
assert s.final_output_type == "audio"
assert s.engine_output_type == "audio"
assert s.hf_config_name == "talker_config"
# Per-stage model_arch override (Ming talker has its own self-contained LLM)
assert s.model_arch == "MingFlashOmniTalkerForConditionalGeneration"
assert s.tokenizer_subdir == "talker/llm"
assert s.custom_process_input_func is not None
def test_talker_stage_processor_wiring_resolves(self):
"""The custom_process_input_func string must point to a real callable.
Lazy string references only fail at first inference otherwise — this
catches typos in the pipeline declaration at import / registration time.
"""
import importlib
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
s = _PIPELINE_REGISTRY["ming_flash_omni"].get_stage(1)
module_path, _, attr = s.custom_process_input_func.rpartition(".")
module = importlib.import_module(module_path)
assert callable(getattr(module, attr))
def test_tts_pipeline_registered(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
p = _PIPELINE_REGISTRY.get("ming_flash_omni_tts")
assert p is not None
assert p.model_arch == "MingFlashOmniTalkerForConditionalGeneration"
assert len(p.stages) == 1
assert p.validate() == []
def test_tts_stage(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
s = _PIPELINE_REGISTRY["ming_flash_omni_tts"].get_stage(0)
assert s.model_stage == "ming_tts"
assert s.execution_type == StageExecutionType.LLM_GENERATION
assert s.input_sources == ()
assert s.owns_tokenizer is True
assert s.final_output_type == "audio"
assert s.engine_output_type == "audio"
assert s.hf_config_name == "talker_config"
assert s.tokenizer_subdir == "talker/llm"
def test_full_yaml_loads_and_merges(self):
"""deploy/ming_flash_omni.yaml parses and merges with the registered pipeline."""
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
from vllm_omni.config.stage_config import load_deploy_config, merge_pipeline_deploy
deploy_path = Path(__file__).parent.parent / "vllm_omni" / "deploy" / "ming_flash_omni.yaml"
if not deploy_path.exists():
pytest.skip("ming_flash_omni deploy yaml not found")
deploy = load_deploy_config(deploy_path)
assert len(deploy.stages) == 2
assert deploy.async_chunk is False
assert deploy.pipeline == "ming_flash_omni"
# We won't test stage 0/1 colocation contract here,
# as there could exist more variant of custom device setup
pipeline = _PIPELINE_REGISTRY["ming_flash_omni"]
stages = merge_pipeline_deploy(pipeline, deploy)
assert len(stages) == 2
assert stages[0].yaml_engine_args["model_arch"] == "MingFlashOmniForConditionalGeneration"
assert stages[1].yaml_engine_args["model_arch"] == "MingFlashOmniTalkerForConditionalGeneration"
def test_tts_yaml_loads_and_merges(self):
"""deploy/ming_flash_omni_tts.yaml parses and routes to the TTS-only pipeline."""
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
from vllm_omni.config.stage_config import load_deploy_config, merge_pipeline_deploy
deploy_path = Path(__file__).parent.parent / "vllm_omni" / "deploy" / "ming_flash_omni_tts.yaml"
if not deploy_path.exists():
pytest.skip("ming_flash_omni_tts deploy yaml not found")
deploy = load_deploy_config(deploy_path)
assert len(deploy.stages) == 1
assert deploy.pipeline == "ming_flash_omni_tts"
pipeline = _PIPELINE_REGISTRY["ming_flash_omni_tts"]
stages = merge_pipeline_deploy(pipeline, deploy)
assert len(stages) == 1
assert stages[0].yaml_engine_args["model_arch"] == "MingFlashOmniTalkerForConditionalGeneration"
def test_thinker_only_pipeline_registered(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
p = _PIPELINE_REGISTRY.get("ming_flash_omni_thinker_only")
assert p is not None
assert p.model_arch == "MingFlashOmniForConditionalGeneration"
assert len(p.stages) == 1
assert p.validate() == []
def test_thinker_only_stage(self):
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
s = _PIPELINE_REGISTRY["ming_flash_omni_thinker_only"].get_stage(0)
assert s.model_stage == "thinker"
assert s.execution_type == StageExecutionType.LLM_AR
assert s.input_sources == ()
assert s.owns_tokenizer is True
assert s.requires_multimodal_data is True
assert s.final_output_type == "text"
assert s.engine_output_type == "text"
assert s.hf_config_name == "llm_config"
assert s.sampling_constraints["detokenize"] is True
def test_thinker_only_yaml_loads_and_merges(self):
"""deploy/ming_flash_omni_thinker_only.yaml parses and routes to the thinker-only pipeline."""
import vllm_omni.model_executor.models.ming_flash_omni.pipeline # noqa: F401
from vllm_omni.config.stage_config import load_deploy_config, merge_pipeline_deploy
deploy_path = Path(__file__).parent.parent / "vllm_omni" / "deploy" / "ming_flash_omni_thinker_only.yaml"
if not deploy_path.exists():
pytest.skip("ming_flash_omni_thinker_only deploy yaml not found")
deploy = load_deploy_config(deploy_path)
assert len(deploy.stages) == 1
assert deploy.pipeline == "ming_flash_omni_thinker_only"
pipeline = _PIPELINE_REGISTRY["ming_flash_omni_thinker_only"]
stages = merge_pipeline_deploy(pipeline, deploy)
assert len(stages) == 1
assert stages[0].yaml_engine_args["model_arch"] == "MingFlashOmniForConditionalGeneration"
class TestBaseConfigInheritance:
"""Test deploy YAML base_config inheritance."""
+12
View File
@@ -85,6 +85,18 @@ _OMNI_PIPELINES: dict[str, tuple[str, str]] = {
"vllm_omni.model_executor.models.fish_speech.pipeline",
"FISH_SPEECH_PIPELINE",
),
"ming_flash_omni": (
"vllm_omni.model_executor.models.ming_flash_omni.pipeline",
"MING_FLASH_OMNI_PIPELINE",
),
"ming_flash_omni_tts": (
"vllm_omni.model_executor.models.ming_flash_omni.pipeline",
"MING_FLASH_OMNI_TTS_PIPELINE",
),
"ming_flash_omni_thinker_only": (
"vllm_omni.model_executor.models.ming_flash_omni.pipeline",
"MING_FLASH_OMNI_THINKER_ONLY_PIPELINE",
),
"moss_tts_nano": (
"vllm_omni.model_executor.models.moss_tts_nano.pipeline",
"MOSS_TTS_NANO_PIPELINE",
+56
View File
@@ -0,0 +1,56 @@
# Ming-flash-omni-2.0 deploy: thinker + talker.
#
# Stage 0: Thinker: multimodal understanding -> text generation.
# TP=4 (or PP=4) across GPUs 0-3.
# Stage 1: Talker: text -> audio waveform via CFM + AudioVAE.
# Generation worker, runs eager, colocates on the last GPU.
#
# Fields omitted from a stage fall back to StageDeployConfig dataclass
# defaults (see vllm_omni/config/stage_config.py).
# * Stage 0 (thinker) owns GPUs 0-3 with gpu_memory_utilization=0.74,
# as we tend to fit talker in one of the devices. (For now,
# gpu mem util on different devices are not supported to be set
# independently for a single stage.)
# * Stage 1 (talker) colocates on GPU 3 with gpu_memory_utilization=0.18.
# This custom settings is verified and required on devices with 80GB memory.
pipeline: ming_flash_omni
async_chunk: false
trust_remote_code: true
distributed_executor_backend: mp
enable_prefix_caching: false
stages:
- stage_id: 0
max_num_seqs: 1
gpu_memory_utilization: 0.74
enforce_eager: false
tensor_parallel_size: 4
max_num_batched_tokens: 32768
devices: "0,1,2,3"
# disable fused allreduce+rms for flashinfer version mismatch for now
compilation_config:
pass_config:
fuse_allreduce_rms: false
default_sampling_params:
temperature: 0.4
top_p: 0.9
max_tokens: 2048
repetition_penalty: 1.05
detokenize: true
ignore_eos: false
- stage_id: 1
max_num_seqs: 1
gpu_memory_utilization: 0.18
enforce_eager: true
max_num_batched_tokens: 1000000
devices: "3"
default_sampling_params:
temperature: 0.0
max_tokens: 1
# Ming-flash-omni-2.0 has only been verified on CUDA devices,
# left empty intentionally. Add per-platform overrides here
# when other backends (ROCm/XPU/NPU) are verified end-to-end.
platforms: {}
@@ -0,0 +1,36 @@
# Ming-flash-omni-2.0 thinker-only deploy: multimodal understanding -> text.
#
# Single-stage configuration that drops the talker; useful when only text
# output is required (chat / understanding / reasoning)
#
# Stage 0: Thinker — TP=4 across GPUs 0-3 with full memory budget since no
# talker shares the last device.
pipeline: ming_flash_omni_thinker_only
async_chunk: false
trust_remote_code: true
distributed_executor_backend: mp
enable_prefix_caching: false
stages:
- stage_id: 0
max_num_seqs: 1
gpu_memory_utilization: 0.9
enforce_eager: false
tensor_parallel_size: 4
max_num_batched_tokens: 32768
devices: "0,1,2,3"
# disable fused allreduce+rms for flashinfer version mismatch for now
compilation_config:
pass_config:
fuse_allreduce_rms: false
default_sampling_params:
temperature: 0.4
top_p: 0.9
max_tokens: 2048
repetition_penalty: 1.05
detokenize: true
ignore_eos: false
# Ming-flash-omni-2.0 has only been verified on CUDA devices
platforms: {}
+24
View File
@@ -0,0 +1,24 @@
# Ming-flash-omni-2.0 standalone TTS deploy: talker only.
#
# Single-stage configuration for direct text -> audio synthesis
# The talker runs as a generation worker on a single GPU
# and owns the tokenizer.
pipeline: ming_flash_omni_tts
async_chunk: false
trust_remote_code: true
enable_prefix_caching: false
stages:
- stage_id: 0
max_num_seqs: 1
gpu_memory_utilization: 0.8
enforce_eager: true
max_num_batched_tokens: 100000
devices: "0"
default_sampling_params:
temperature: 0.0
max_tokens: 1
# Ming-flash-omni-2.0 has only been verified on CUDA devices
platforms: {}
@@ -104,8 +104,8 @@ class MingFlashOmniForConditionalGeneration(
"model_arch='MingFlashOmniTalkerForConditionalGeneration' "
"directly — the talker has a self-contained LLM that "
"tokenises text itself and does not need the multimodal "
"preprocess path. See stage_configs/ming_flash_omni.yaml "
"stage 1 and stage_configs/ming_flash_omni_tts.yaml."
"preprocess path. See vllm_omni/deploy/ming_flash_omni.yaml "
"stage 1 and vllm_omni/deploy/ming_flash_omni_tts.yaml."
)
if self.model_stage == "thinker":
@@ -0,0 +1,106 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
"""Ming-flash-omni-2.0 pipeline topology (frozen).
Stage 0: Thinker — multimodal understanding + text generation.
Stage 1: Talker — text -> audio waveform via CFM + AudioVAE.
The thinker -> talker bridge passes the detokenized text rather than
hidden states through `ming_flash_omni.thinker2talker`; the talker has a
self-contained Qwen2 LLM that retokenizes the string itself.
"""
from vllm_omni.config.stage_config import (
PipelineConfig,
StageExecutionType,
StagePipelineConfig,
)
_PROC = "vllm_omni.model_executor.stage_input_processors.ming_flash_omni"
MING_FLASH_OMNI_PIPELINE = PipelineConfig(
model_type="ming_flash_omni",
model_arch="MingFlashOmniForConditionalGeneration",
# Upstream HF config applies model_type="bailingmm_moe_v2_lite"
# (the thinker sub-config name) rather than "ming_flash_omni".
# Declare the architectures here explicitly for routing
hf_architectures=(
"MingFlashOmniForConditionalGeneration",
"BailingMM2NativeForConditionalGeneration",
),
stages=(
StagePipelineConfig(
stage_id=0,
model_stage="thinker",
execution_type=StageExecutionType.LLM_AR,
input_sources=(),
final_output=True,
final_output_type="text",
owns_tokenizer=True,
requires_multimodal_data=True,
# Thinker reads the LLM sub-config of BailingMM2Config
hf_config_name="llm_config",
engine_output_type="text",
sampling_constraints={"detokenize": True},
),
StagePipelineConfig(
stage_id=1,
model_stage="ming_tts",
# Talker is a self-contained Qwen2 LLM + CFM + AudioVAE;
# it does not share the thinker backbone, so it gets its own arch.
model_arch="MingFlashOmniTalkerForConditionalGeneration",
execution_type=StageExecutionType.LLM_GENERATION,
input_sources=(0,),
final_output=True,
final_output_type="audio",
hf_config_name="talker_config",
engine_output_type="audio",
tokenizer_subdir="talker/llm",
custom_process_input_func=f"{_PROC}.thinker2talker",
),
),
)
# Standalone TTS variant: talker only.
MING_FLASH_OMNI_TTS_PIPELINE = PipelineConfig(
model_type="ming_flash_omni_tts",
model_arch="MingFlashOmniTalkerForConditionalGeneration",
stages=(
StagePipelineConfig(
stage_id=0,
model_stage="ming_tts",
execution_type=StageExecutionType.LLM_GENERATION,
input_sources=(),
final_output=True,
final_output_type="audio",
owns_tokenizer=True,
hf_config_name="talker_config",
engine_output_type="audio",
tokenizer_subdir="talker/llm",
),
),
)
# Thinker-only variant: multimodal understanding with text output
MING_FLASH_OMNI_THINKER_ONLY_PIPELINE = PipelineConfig(
model_type="ming_flash_omni_thinker_only",
model_arch="MingFlashOmniForConditionalGeneration",
stages=(
StagePipelineConfig(
stage_id=0,
model_stage="thinker",
execution_type=StageExecutionType.LLM_AR,
input_sources=(),
final_output=True,
final_output_type="text",
owns_tokenizer=True,
requires_multimodal_data=True,
hf_config_name="llm_config",
engine_output_type="text",
sampling_constraints={"detokenize": True},
),
),
)
@@ -963,7 +963,7 @@ class MingAudioGenerator:
)
if step > min_new_token and stop_prob > 0.5:
logger.info("Stopping at step %d with stop_prob=%.4f", step, stop_prob)
logger.debug("Stopping at step %d with stop_prob=%.4f", step, stop_prob)
break
return all_latents
@@ -1,46 +0,0 @@
# Stage config for Ming-flash-omni-2.0
# Stage 0: Thinker (Multimodal understanding + text generation)
# Stage 1a: Image Generator (Text embeddings -> PIL image)
# Stage 1b: Talker (Text embeddings -> audio waveform)
async_chunk: false
stage_args:
- stage_id: 0
stage_type: llm
runtime:
devices: "0,1,2,3"
max_batch_size: 1
engine_args:
model_stage: thinker
model_arch: MingFlashOmniForConditionalGeneration
# tokenizer_subdir: talker/llm
worker_type: ar
scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler
gpu_memory_utilization: 0.9
enforce_eager: false
trust_remote_code: true
engine_output_type: latent
distributed_executor_backend: "mp"
enable_prefix_caching: false
max_num_batched_tokens: 32768
tensor_parallel_size: 4 # Use 4 GPUs for MoE model
# pipeline_parallel_size: 4
hf_config_name: llm_config
compilation_config:
pass_config:
# there's a version mismatch regarding vllm and flashinfer
# disable fuse allreduce for now
fuse_allreduce_rms: false
final_output: true # Can output text directly
final_output_type: text
is_comprehension: true
default_sampling_params:
temperature: 0.4
top_p: 0.9
max_tokens: 2048
repetition_penalty: 1.05
seed: 42
detokenize: true
# Future Stage 1a: Image Generator (Optional - not yet implemented)
# Future Stage 1b: Talker/TTS (Optional - not yet implemented)
@@ -1,70 +0,0 @@
# Multi-stage config for Ming-flash-omni-2.0: Thinker + Talker
# Stage 0: Thinker (multimodal understanding → text generation)
# Stage 1: Talker (text → audio waveform via CFM + AudioVAE)
stage_args:
- stage_id: 0
stage_type: llm
runtime:
devices: "0,1,2,3"
max_batch_size: 1
engine_args:
model_stage: thinker
model_arch: MingFlashOmniForConditionalGeneration
worker_type: ar
scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler
gpu_memory_utilization: 0.74
enforce_eager: false
trust_remote_code: true
# Ming Thinker -> talker bridging reads the detokenized text via
# source_output.outputs[0].text rather than hidden states
engine_output_type: text
distributed_executor_backend: "mp"
enable_prefix_caching: false
max_num_batched_tokens: 32768
tensor_parallel_size: 4
hf_config_name: llm_config
compilation_config:
pass_config:
# there's a version mismatch regarding vllm and flashinfer
# disable fuse allreduce for now
fuse_allreduce_rms: false
final_output: true
final_output_type: text
is_comprehension: true
default_sampling_params:
temperature: 0.4
top_p: 0.9
max_tokens: 2048
repetition_penalty: 1.05
detokenize: true
ignore_eos: false
- stage_id: 1
stage_type: llm
runtime:
devices: "3"
max_batch_size: 1
engine_args:
# Use the standalone talker class
model_stage: ming_tts
model_arch: MingFlashOmniTalkerForConditionalGeneration
worker_cls: vllm_omni.worker.gpu_generation_worker.GPUGenerationWorker
scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler
gpu_memory_utilization: 0.18
enforce_eager: true
trust_remote_code: true
engine_output_type: audio
enable_prefix_caching: false
max_num_batched_tokens: 1000000
tokenizer_subdir: talker/llm
# The HF repo ships BailingMM2Config (thinker-only) at root,
# OmniModelConfig treats that as "stage does not share outer mrope"
hf_config_name: talker_config
engine_input_source: [0]
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.ming_flash_omni.thinker2talker
final_output: true
final_output_type: audio
default_sampling_params:
temperature: 0.0
max_tokens: 1
@@ -1,32 +0,0 @@
# Single-stage TTS config for Ming-flash-omni-2.0 Talker
# Stage 0: Talker only (text → audio waveform via CFM + AudioVAE)
# Use this config for standalone TTS deployment without thinker.
stage_args:
- stage_id: 0
stage_type: llm
is_comprehension: true
runtime:
devices: "0"
max_batch_size: 1
engine_args:
model_stage: ming_tts
model_arch: MingFlashOmniTalkerForConditionalGeneration
worker_cls: vllm_omni.worker.gpu_generation_worker.GPUGenerationWorker
scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler
gpu_memory_utilization: 0.8
enforce_eager: true
trust_remote_code: true
engine_output_type: audio
enable_prefix_caching: false
max_num_batched_tokens: 100000
tokenizer_subdir: talker/llm
# NOTE: `hf_config_name` for Ming talker acts as a placeholder
# The HF repo ships BailingMM2Config (thinker-only) at root,
# OmniModelConfig treats that as "stage does not share outer mrope"
hf_config_name: talker_config
final_output: true
final_output_type: audio
default_sampling_params:
temperature: 0.0
max_tokens: 1