[Refactor] Migrate Step-Audio2 online test to deploy config (#5309)
Signed-off-by: zwhzzz0821 <2831474076@qq.com>
This commit is contained in:
1 parent
8fc9df4331
commit
633ebbd8a4
4 files changed
+74
-113
No files matched your search
@@ -1,81 +0,0 @@
|
||||
# Stage config for Step-Audio2 CI tests
|
||||
# Stage 0: Thinker (audio understanding → text + audio tokens)
|
||||
# Stage 1: Token2Wav (audio tokens → waveform)
|
||||
|
||||
# The following config has been verified on 2x 24GB GPU (L4/RTX3090/RTX4090).
|
||||
stage_args:
|
||||
- stage_id: 0
|
||||
runtime:
|
||||
process: true
|
||||
devices: "0"
|
||||
max_batch_size: 1
|
||||
engine_args:
|
||||
model_stage: thinker
|
||||
model_arch: StepAudio2ThinkerForConditionalGeneration
|
||||
tensor_parallel_size: 1
|
||||
hf_overrides:
|
||||
architectures: ["StepAudio2ThinkerForConditionalGeneration"]
|
||||
|
||||
worker_cls: vllm_omni.worker.gpu_ar_worker.GPUARWorker
|
||||
scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler
|
||||
max_model_len: 1024
|
||||
max_num_batched_tokens: 1024
|
||||
max_num_seqs: 1
|
||||
gpu_memory_utilization: 0.7
|
||||
skip_mm_profiling: true
|
||||
enforce_eager: true
|
||||
trust_remote_code: true
|
||||
enable_prefix_caching: false
|
||||
engine_output_type: text # Output text + audio tokens
|
||||
is_comprehension: true
|
||||
final_output: true
|
||||
final_output_type: text
|
||||
default_sampling_params:
|
||||
temperature: 0.7
|
||||
top_p: 0.9
|
||||
top_k: -1
|
||||
max_tokens: 256
|
||||
seed: 42
|
||||
detokenize: true
|
||||
repetition_penalty: 1.05
|
||||
|
||||
- stage_id: 1
|
||||
runtime:
|
||||
process: true
|
||||
devices: "0"
|
||||
max_batch_size: 1
|
||||
engine_args:
|
||||
|
||||
model_stage: token2wav
|
||||
model_arch: StepAudio2Token2WavModel
|
||||
worker_cls: vllm_omni.worker.gpu_generation_worker.GPUGenerationWorker
|
||||
scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler
|
||||
hf_overrides:
|
||||
architectures: ["StepAudio2Token2WavModel"]
|
||||
gpu_memory_utilization: 0.2
|
||||
enforce_eager: true
|
||||
trust_remote_code: true
|
||||
enable_prefix_caching: false
|
||||
max_num_batched_tokens: 1024
|
||||
engine_output_type: audio # Output waveform
|
||||
engine_input_source: [0]
|
||||
custom_process_input_func: vllm_omni.model_executor.stage_input_processors.step_audio2.thinker2token2wav
|
||||
final_output: true
|
||||
final_output_type: audio
|
||||
default_sampling_params:
|
||||
temperature: 0.0
|
||||
top_p: 1.0
|
||||
top_k: -1
|
||||
max_tokens: 1
|
||||
seed: 42
|
||||
detokenize: false
|
||||
|
||||
runtime:
|
||||
enabled: true
|
||||
defaults:
|
||||
window_size: -1
|
||||
max_inflight: 1
|
||||
edges:
|
||||
- from: 0
|
||||
to: 1
|
||||
window_size: -1
|
||||
@@ -3,34 +3,32 @@
|
||||
"""
|
||||
E2E expansion tests for Step-Audio2 online serving (weekly CI).
|
||||
|
||||
Tests speech-to-speech translation via /v1/chat/completions.
|
||||
Tests audio-to-text generation via /v1/chat/completions.
|
||||
Request shape follows examples/online_serving/step_audio2/openai_chat_completion_client.py.
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.helpers.mark import hardware_test
|
||||
from tests.helpers.media import generate_synthetic_audio
|
||||
from tests.helpers.runtime import OmniServerParams
|
||||
from tests.helpers.stage_config import get_deploy_config_path
|
||||
|
||||
os.environ.setdefault("VLLM_WORKER_MULTIPROC_METHOD", "spawn")
|
||||
|
||||
MODEL = "stepfun-ai/Step-Audio-2-mini"
|
||||
STAGE_CONFIG = str(Path(__file__).parent / "stage_configs" / "step_audio2_ci.yaml")
|
||||
DEPLOY_CONFIG = get_deploy_config_path("step_audio2_ci.yaml")
|
||||
SAMPLE_RATE = 16000
|
||||
SEED = 42
|
||||
# pyttsx3 synthetic input phrase; Step-Audio2 text output includes codec tokens
|
||||
# (<audio_NNNN>) so we validate audio only, not text↔audio similarity.
|
||||
SYNTH_PHRASE = "how are you"
|
||||
|
||||
TEST_PARAMS = [
|
||||
pytest.param(
|
||||
OmniServerParams(
|
||||
model=MODEL,
|
||||
stage_config_path=STAGE_CONFIG,
|
||||
server_args=["--deploy-config", DEPLOY_CONFIG, "--trust-remote-code"],
|
||||
env_dict={"VLLM_IMAGE_FETCH_TIMEOUT": "60"},
|
||||
),
|
||||
id="step_audio2",
|
||||
@@ -64,19 +62,11 @@ def _default_sampling_params_list() -> list[dict]:
|
||||
"detokenize": True,
|
||||
"repetition_penalty": 1.05,
|
||||
},
|
||||
{
|
||||
"temperature": 0.0,
|
||||
"top_p": 1.0,
|
||||
"top_k": -1,
|
||||
"max_tokens": 1,
|
||||
"seed": SEED,
|
||||
"detokenize": False,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _build_s2st_request_config(omni_server, audio_base64: str) -> dict:
|
||||
"""Build audio-to-audio (S2ST) chat completion request config."""
|
||||
def _build_audio_to_text_request_config(omni_server, audio_base64: str) -> dict:
|
||||
"""Build an audio-to-text chat completion request config."""
|
||||
audio_url = f"data:audio/wav;base64,{audio_base64}"
|
||||
return {
|
||||
"model": omni_server.model,
|
||||
@@ -86,7 +76,7 @@ def _build_s2st_request_config(omni_server, audio_base64: str) -> dict:
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "You are an audio processing assistant. Listen and repeat the audio content.",
|
||||
"text": "You are a speech recognition assistant. Transcribe the audio accurately.",
|
||||
}
|
||||
],
|
||||
},
|
||||
@@ -94,26 +84,19 @@ def _build_s2st_request_config(omni_server, audio_base64: str) -> dict:
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "audio_url", "audio_url": {"url": audio_url}},
|
||||
{"type": "text", "text": "Please listen to this audio and repeat its content."},
|
||||
{"type": "text", "text": "Please transcribe the audio content."},
|
||||
],
|
||||
},
|
||||
{"role": "assistant", "content": "<tts_start>"},
|
||||
],
|
||||
# Thinker text includes undetokenized audio codec placeholders; assert audio only.
|
||||
"modalities": ["audio"],
|
||||
"audio_ref_text": SYNTH_PHRASE,
|
||||
"modalities": ["text"],
|
||||
"sampling_params_list": _default_sampling_params_list(),
|
||||
"extra_body": {
|
||||
"continue_final_message": True,
|
||||
"add_generation_prompt": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@hardware_test(res={"cuda": "H100"}, num_cards=1)
|
||||
def test_single_s2st_request(omni_server, openai_client) -> None:
|
||||
"""Test single speech-to-speech request via chat completions API."""
|
||||
request_config = _build_s2st_request_config(
|
||||
def test_single_audio_to_text_request(omni_server, openai_client) -> None:
|
||||
"""Test a single audio-to-text request via the chat completions API."""
|
||||
request_config = _build_audio_to_text_request_config(
|
||||
omni_server,
|
||||
_synthetic_audio_base64(duration_sec=2),
|
||||
)
|
||||
@@ -122,9 +105,9 @@ def test_single_s2st_request(omni_server, openai_client) -> None:
|
||||
|
||||
@hardware_test(res={"cuda": "H100"}, num_cards=1)
|
||||
@pytest.mark.parametrize("request_num", [2, 4])
|
||||
def test_concurrent_s2st_requests(omni_server, openai_client, request_num: int) -> None:
|
||||
"""Test concurrent speech-to-speech requests."""
|
||||
request_config = _build_s2st_request_config(
|
||||
def test_concurrent_audio_to_text_requests(omni_server, openai_client, request_num: int) -> None:
|
||||
"""Test concurrent audio-to-text requests."""
|
||||
request_config = _build_audio_to_text_request_config(
|
||||
omni_server,
|
||||
_synthetic_audio_base64(duration_sec=2),
|
||||
)
|
||||
|
||||
@@ -1174,6 +1174,7 @@ stages:
|
||||
("step_audio_2.yaml", "step_audio_2", 2, "audio", None),
|
||||
("step_audio_2_asr.yaml", "step_audio_2_asr", 1, "text", "step_audio_2_asr"),
|
||||
("step_audio_2_async_chunk.yaml", "step_audio_2", 2, "audio", None),
|
||||
("step_audio2_ci.yaml", "step_audio_2_asr", 1, "text", "step_audio_2_asr"),
|
||||
("hunyuan_video_15.yaml", "hunyuan_video_15", 1, "video", None),
|
||||
("wan2_2_ti2v.yaml", "wan2_2_ti2v", 1, "video", None),
|
||||
],
|
||||
@@ -1241,6 +1242,33 @@ stages:
|
||||
assert deploy.stages[0].tensor_parallel_size == 2
|
||||
assert deploy.stages[1].devices == "1"
|
||||
|
||||
def test_step_audio2_online_ci_deploy_is_single_thinker(self):
|
||||
deploy = load_deploy_config(Path(get_deploy_config_path("step_audio2_ci.yaml")))
|
||||
|
||||
assert deploy.pipeline == "step_audio_2_asr"
|
||||
assert deploy.async_chunk is False
|
||||
assert deploy.trust_remote_code is True
|
||||
assert deploy.enable_prefix_caching is False
|
||||
assert len(deploy.stages) == 1
|
||||
|
||||
stage = deploy.stages[0]
|
||||
assert stage.devices == "0"
|
||||
assert stage.tensor_parallel_size == 1
|
||||
assert stage.max_model_len == 1024
|
||||
assert stage.max_num_batched_tokens == 1024
|
||||
assert stage.max_num_seqs == 1
|
||||
assert stage.gpu_memory_utilization == 0.7
|
||||
assert stage.skip_mm_profiling is True
|
||||
assert stage.enforce_eager is True
|
||||
assert stage.async_scheduling is False
|
||||
assert stage.engine_extras["hf_overrides"]["architectures"] == ["StepAudio2ThinkerForConditionalGeneration"]
|
||||
|
||||
stages = merge_pipeline_deploy(OMNI_PIPELINES[deploy.pipeline], deploy)
|
||||
assert len(stages) == 1
|
||||
assert stages[0].final_output is True
|
||||
assert stages[0].final_output_type == "text"
|
||||
assert stages[0].yaml_engine_args["engine_output_type"] == "text"
|
||||
|
||||
def test_step_audio2_dispatches_sync_and_async_chunk_processors(self):
|
||||
pipeline = resolve_pipeline_config("step_audio_2")
|
||||
assert isinstance(pipeline, PipelineConfig)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Step-Audio2 online CI deploy: thinker only (audio/text -> text).
|
||||
#
|
||||
# The two-stage topology can deadlock when an audio-to-text request skips the
|
||||
# Token2Wav stage, so this config explicitly selects the ASR pipeline.
|
||||
# Keeps the legacy 1x 24GB CI sizing; validated here on 1x H100-80GB.
|
||||
pipeline: step_audio_2_asr
|
||||
async_chunk: false
|
||||
trust_remote_code: true
|
||||
enable_prefix_caching: false
|
||||
|
||||
stages:
|
||||
- stage_id: 0
|
||||
devices: "0"
|
||||
tensor_parallel_size: 1
|
||||
max_model_len: 1024
|
||||
max_num_batched_tokens: 1024
|
||||
max_num_seqs: 1
|
||||
gpu_memory_utilization: 0.7
|
||||
skip_mm_profiling: true
|
||||
enforce_eager: true
|
||||
async_scheduling: false
|
||||
hf_overrides:
|
||||
architectures: ["StepAudio2ThinkerForConditionalGeneration"]
|
||||
default_sampling_params:
|
||||
temperature: 0.7
|
||||
top_p: 0.9
|
||||
top_k: -1
|
||||
max_tokens: 256
|
||||
seed: 42
|
||||
detokenize: true
|
||||
repetition_penalty: 1.05
|
||||
Reference in new issue
Block a user