Skip to content

[New Model] Step-Audio2 - #464

Merged
linyueqian merged 5 commits into
vllm-project:mainfrom
wuli666:feature/step-audio2-integration
Jun 13, 2026
Merged

linyueqian merged 5 commits into
vllm-project:mainfrom
wuli666:feature/step-audio2-integration

Conversation

@wuli666

@wuli666 wuli666 commented Dec 24, 2025 •

Copy link
Copy Markdown
Contributor

Support complete Step-Audio2 integration with two-stage pipeline (Thinker → Token2Wav) for ASR, TTS, and S2ST tasks.

Architecture

                                                                                                                                                                                                                                                                                                   
  Stage 0: Thinker (Qwen2 LLM + Audio Encoder)
    → text + audio tokens (ID ≥ 151696)                                                                                                                                                                                                                                                                   
          │                                                                        
          │ async_chunk                                                                                                                                                                                                                                                                                   
          ▼                              
  Stage 1: Token2Wav (Flow Model + HiFT Vocoder)                                                                                                                                                                                                                                                          
    → 24kHz waveform (streaming overlap-add)                                       
  

step_audio2_thinker.py: Stage-0 model. Qwen2-based LLM with audio encoder for speech understanding and audio token generation. Supports multimodal audio input via StepAudio2Processor.

step_audio2_token2wav.py: Stage-1 model. Flow model (conformer encoder + DiT estimator) + HiFT vocoder for audio token to 24kHz waveform conversion. Supports both streaming (per-request _StreamState with chunked overlap-add) and non-streaming modes.

step_audio2.py (stage_input_processors): Async chunk processor thinker2token2wav_async_chunk that extracts audio tokens from the AR token stream and sends them in chunks (chunk_size=25 + lookahead=3) to Token2Wav.

serving_speech.py: Registered Step-Audio2 in /v1/audio/speech endpoint with dedicated _build_step_audio2_prompt() that injects <tts_start> without chat template interference.

Stage configs: step_audio_2_async_chunk.yaml (streaming, recommended), step_audio_2.yaml (sequential), step_audio_2_asr.yaml (ASR-only, single stage).

Related issues: #271

Installation: pip install step-audio2 (includes flashcosyvoice, cosyvoice2, s3tokenizer, hyperpyyaml, etc.)

Purpose

Resolves #271

Test Plan

Tested on 4x RTX 3090 with stepfun-ai/Step-Audio2-mini.

  • Online: TTS via /v1/audio/speech, ASR and S2ST via /v1/chat/completions
  • Offline: end2end.py with all three query types (audio_to_text, text_to_audio, audio_to_audio)
  • Benchmark: bench_tts_serve.py (10 prompts, concurrency=1)

Test Result

Online TTS (/v1/audio/speech): clean 24kHz audio output ✅
Online ASR (chat completions): correct transcription ✅
Online S2ST (chat completions): text + audio output ✅
Offline ASR/TTS/S2ST: all produce correct output ✅

Async chunk vs Sequential (4x RTX 3090, 10 prompts, concurrency=1):

Mode Mean TTFP Mean E2E Mean RTF
Sequential 4316ms 4316ms 0.938
Async Chunk 1437ms 4362ms 0.949

vLLM-Omni vs Official Step-Audio2 (H100 80GB):

Task Tokens vllm-omni Step-Audio2 Speedup
S2ST ~85 5.45s 7.36s 1.35x
S2ST ~160 6.67s 13.92s 2.09x
S2ST ~315 9.42s 31.50s 3.34x
TTS ~1024 16.65s ~87s ~5.2x

@wuli666 wuli666 mentioned this pull request Dec 24, 2025
1 task done
@hsliuustc0106

Copy link
Copy Markdown
Collaborator

@linyueqian PTAL

Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2.py Outdated
@david6666666 david6666666 mentioned this pull request Dec 25, 2025
28 of 61 tasks
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated

@linyueqian linyueqian left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add test ci

Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_token2wav.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_token2wav.py Outdated
@wuli666
wuli666 force-pushed the feature/step-audio2-integration branch 3 times, most recently from 18e9df2 to f072adc Compare December 29, 2025 14:44
@wuli666
wuli666 marked this pull request as ready for review December 29, 2025 16:03

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +304 to +306
generated_speech_tokens: torch.Tensor | list,
prompt_wav: str,
return_bytes: bool = True,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Token2Wav stage fails without missing prompt_wav argument

The Token2Wav wrapper mandates a prompt_wav argument with no default (step_audio2_token2wav.py lines 304-306), but the Stage 0→1 input processor only forwards audio token IDs and never adds a speaker path, and the stage config uses the generic GPUGenerationWorker. When Stage 1 runs it will call this forward with only the generated tokens, leading to a TypeError: forward() missing required argument 'prompt_wav' before any audio synthesis, so the two-stage pipeline cannot execute.

Useful? React with 👍 / 👎.

@hsliuustc0106 hsliuustc0106 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wuli666

wuli666 commented Jan 4, 2026

Copy link
Copy Markdown
Contributor Author

please follow this guideline: https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/model/adding_omni_model/

ok, I'll submit a version as soon as possible.

@hsliuustc0106

Copy link
Copy Markdown
Collaborator

I think this PR is almost ready for test and then merged, let's push it faster.

@hsliuustc0106

Copy link
Copy Markdown
Collaborator

@Bounty-hunter @wuhang2014 PTAL

Comment thread examples/offline_inference/step_audio2/README.md Outdated
Comment thread examples/offline_inference/step_audio2/README.md Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_processor.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_token2wav.py Outdated
Comment thread vllm_omni/model_executor/stage_configs/step_audio_2.yaml Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated
@wuli666
wuli666 force-pushed the feature/step-audio2-integration branch 2 times, most recently from 4f94598 to a8d982b Compare January 7, 2026 08:48
@hsliuustc0106

Copy link
Copy Markdown
Collaborator
  • fix DCO&docs&pre-commits
  • add hardware usage guidance in your yaml
  • test whether both offline and online support
  • rm unnecessary comments
  • test the e2e speedup compared with original implementation from stepfun

Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_token2wav.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_token2wav.py Outdated
Comment thread vllm_omni/model_executor/models/step_audio2/step_audio2_thinker.py Outdated
Comment thread examples/offline_inference/step_audio2/README.md Outdated
Comment thread examples/offline_inference/step_audio2/end2end.py Outdated
@david6666666 david6666666 mentioned this pull request Jan 16, 2026
37 of 63 tasks
@wuli666
wuli666 force-pushed the feature/step-audio2-integration branch 3 times, most recently from c2cdcb4 to 01aa912 Compare January 19, 2026 14:39
- test_step_audio2.py: import OmniRunner from tests.helpers.runtime and
  create_new_process_for_each_test from tests.helpers.process (the old
  conftest.py/utils.py were removed in the test-helpers refactor)
- step_audio2_token2wav.py: hoist model_name_or_path out of the
  token2wav_path branch so _resolve_prompt_wav works when token2wav_path is
  configured (fixes UnboundLocalError)
- stage_input_processors/step_audio2.py: migrate thinker2token2wav to the
  current calling convention (source_outputs, prompt, requires_multimodal_data),
  matching every other stage input processor; the stale
  (stage_list, engine_input_source, ...) signature caused KeyError: 0 at the
  Thinker->Token2Wav handoff
- align the sync-path token2wav test assertion to the single-element-list
  contract used by the other async-chunk tests
- inputs/preprocess.py: drop unused backwards-compat aliases
  (EmbedsInputs/SingletonInputs/MultiModalInputs) nothing referenced, restoring
  the file to upstream
- mark required librosa imports with # noqa: TID251 (same as the minicpmo
  example) and apply ruff import ordering so pre-commit passes

Signed-off-by: wuli666 <djjpro975@gmail.com>
@wuli666
wuli666 force-pushed the feature/step-audio2-integration branch from 44ef141 to fbc5c55 Compare June 11, 2026 06:55
@linyueqian linyueqian added ready label to trigger buildkite CI merge-test label to trigger buildkite merge test CI labels Jun 11, 2026
@linyueqian

Copy link
Copy Markdown
Collaborator

please fix ci and paste your successful ci run result here. i will remove ready label for now

@linyueqian linyueqian removed ready label to trigger buildkite CI merge-test label to trigger buildkite merge test CI labels Jun 11, 2026
The "TTS . Step-Audio2 E2E Test" step collected 0 tests (exit 5): the two
weight-loading E2E tests were core_model while the step runs -m advanced_model.
Mark them advanced_model so the step collects them, and fix three issues that
otherwise made the tests unrunnable or false-green:

- step_audio2_ci.yaml: use a single Thinker stage. The audio->text / text-only
  tests never emit audio tokens, so Token2Wav (stage 1) is skipped and the
  orchestrator waits on the skipped stage forever (deadlock). Also drop the
  Qwen2ForCausalLM hf_overrides so audio input goes through the real Thinker
  audio encoder instead of vLLM`s renderer.
- Drop @create_new_process_for_each_test: the fork default crashes CUDA, and
  the spawn path exits 0 without running the test (false green) because the
  file has no __main__/RUNNING_IN_SUBPROCESS protocol. Run the runner directly
  like the other E2E tests (Qwen3-TTS, Voxtral).
- OmniRequestOutput.request_output is a single RequestOutput, not a list:
  use request_output.outputs[0] instead of request_output[0].outputs[0].

Verified on 2x GPU with the exact CI command:
  pytest -s -v tests/e2e/offline_inference/test_step_audio2.py \
    -m "advanced_model" --run-level "advanced_model"
=> 2 passed.

Signed-off-by: wuli666 <djjpro975@gmail.com>
@wuli666

wuli666 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@linyueqian CI fixed.

Successful run on 2× GPU (full file, all 10 tests):

$ pytest -v tests/e2e/offline_inference/test_step_audio2.py --run-level advanced_model

collected 10 items

test_step_audio2.py::test_processor_loads_correctly             PASSED [ 10%]
test_step_audio2.py::test_audio_preprocessing                   PASSED [ 20%]
test_step_audio2.py::test_feature_length_calculation            PASSED [ 30%]
test_step_audio2.py::test_token_config_constants                PASSED [ 40%]
test_step_audio2.py::test_mm_field_config_structure             PASSED [ 50%]
test_step_audio2.py::test_audio_encoder_output_shape            PASSED [ 60%]
test_step_audio2.py::test_token_separation                      PASSED [ 70%]
test_step_audio2.py::test_has_audio_output                      PASSED [ 80%]
test_step_audio2.py::test_audio_to_text_and_audio[test_config0] PASSED [ 90%]
test_step_audio2.py::test_text_only_input[test_config0]         PASSED [100%]

================= 10 passed, 18 warnings in 111.14s (0:01:51) ==================

The two weight-loading E2E tests also pass under the exact CI command (-m 'advanced_model' --run-level 'advanced_model') → 2 passed in 197.88s.

Check Result
Full file (all 10 tests) ✅ 10 passed
E2E, exact CI cmd on 2× GPU (-m advanced_model) ✅ 2 passed (197.88s)

@linyueqian linyueqian added ready label to trigger buildkite CI merge-test label to trigger buildkite merge test CI labels Jun 12, 2026
The `tests/diffusion tests/model_executor -m core_model and cpu` step exited 2
(1 error during collection): test_step_audio2_token2wav_async_chunk.py imports
StepAudio2Token2WavForConditionalGeneration at module level, which pulls the
optional step-audio2 extras (flashcosyvoice / s3tokenizer / hyperpyyaml). The
CPU core_model image does not install them, so the import raised
ModuleNotFoundError during collection and failed the whole sweep.

- Guard the module-level import: skip (not error) when the optional extras are
  absent; a genuine import error (e.g. vLLM API drift) still surfaces.
- Mark both Step-Audio2 model_executor unit tests [core_model, cpu] (matching
  ming_flash_omni / mimo_audio) so they are collected and run on the CPU sweep
  instead of being silently deselected.

Verified (CPU): extras present -> 8 passed; simulating the CI image (extras
absent) -> token2wav skips, async_chunk 4 passed, 0 collection errors.

Signed-off-by: wuli666 <djjpro975@gmail.com>
@wuli666

wuli666 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@linyueqian PTAL

@linyueqian linyueqian changed the title [WIP] [Model] Step-Audio2 [New Model] Step-Audio2 Jun 12, 2026
@linyueqian linyueqian added ready label to trigger buildkite CI merge-test label to trigger buildkite merge test CI and removed ready label to trigger buildkite CI merge-test label to trigger buildkite merge test CI labels Jun 12, 2026
@linyueqian
linyueqian enabled auto-merge (squash) June 12, 2026 23:05
@linyueqian
linyueqian merged commit 9bc8705 into vllm-project:main Jun 13, 2026
7 of 8 checks passed
linyueqian added a commit to linyueqian/vllm-omni that referenced this pull request Jun 13, 2026
Resolve serving_speech.py conflict from Step-Audio2 (vllm-project#464): instead of the
inline 'if self._tts_model_type == "step_audio2"' branch added on main, migrate
Step-Audio2 onto the adapter framework (new StepAudio2Adapter delegating to the
existing _validate_tts_request dispatcher + _build_step_audio2_prompt). Keeps the
uniform adapter dispatch; registry now has 14 model-types.

Also brings in vllm-project#4373 (Qwen3-TTS codes.ref leak), vllm-project#4397 (Ming-omni Mapping),

Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
vllm-project#3763 (Wan2.2 SP) from main.
Nughm3 pushed a commit to Nughm3/vllm-omni that referenced this pull request Jun 18, 2026
Signed-off-by: linyueqian <linyueqian@outlook.com>
Signed-off-by: wuli666 <djjpro975@gmail.com>
Co-authored-by: linyueqian <linyueqian@outlook.com>
Co-authored-by: wuli666 <djjpro975@gmail.com>
khairulkabir1661 pushed a commit to khairulkabir1661/vllm-omni that referenced this pull request Sep 25, 2026
Signed-off-by: linyueqian <linyueqian@outlook.com>
Signed-off-by: wuli666 <djjpro975@gmail.com>
Co-authored-by: linyueqian <linyueqian@outlook.com>
Co-authored-by: wuli666 <djjpro975@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-test label to trigger buildkite merge test CI ready label to trigger buildkite CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[New Model]:Step Audio 2

9 participants