[Bugfix][Qwen3-TTS] Ignore voice labels for inline Base cloning (#6974)
Signed-off-by: sc-hua <sc_hua@qq.com>
This commit is contained in:
1 parent
7d6e2ade6c
commit
d2aa07159c
3 files changed
+39
-2
No files matched your search
@@ -152,3 +152,23 @@ def test_xvector_then_icl_same_ref_audio_keeps_engine_alive(omni_server, online_
|
||||
online_client.send_audio_speech_request({**base_request, "x_vector_only_mode": True})
|
||||
online_client.send_audio_speech_request({**base_request, "x_vector_only_mode": False, "ref_text": REF_TEXT})
|
||||
online_client.send_audio_speech_request({**base_request, "x_vector_only_mode": True})
|
||||
|
||||
|
||||
@hardware_test(res={"cuda": "L4"}, num_cards=1)
|
||||
@pytest.mark.parametrize("omni_server", tts_async_chunk_server_params, indirect=True)
|
||||
def test_inline_ref_audio_cache_ignores_openai_voice_label(omni_server, online_client) -> None:
|
||||
"""An OpenAI voice label must not identify an inline Base voice clone."""
|
||||
base_request = {
|
||||
"model": omni_server.model,
|
||||
"input": get_prompt(),
|
||||
"stream": False,
|
||||
"timeout": DEFAULT_AUDIO_SPEECH_TIMEOUT_S,
|
||||
"response_format": "wav",
|
||||
"task_type": "Base",
|
||||
"ref_audio": REF_AUDIO_URL,
|
||||
"ref_text": REF_TEXT,
|
||||
"min_audio_bytes": 1,
|
||||
}
|
||||
|
||||
online_client.send_audio_speech_request({**base_request, "voice": "voice-a"})
|
||||
online_client.send_audio_speech_request({**base_request, "voice": "voice-b"})
|
||||
@@ -5507,8 +5507,9 @@ class TestTTSAsyncOffloading:
|
||||
assert prompt["additional_information"]["non_streaming_mode"] == [True]
|
||||
assert "full_utterance_decode" not in prompt["additional_information"]
|
||||
|
||||
def test_qwen3_repeated_ref_audio_hot_path_sends_cache_key_without_waveform(self, qwen3_tts_server):
|
||||
"""After a ref artifact is marked ready, repeated requests avoid ref_audio payload IPC."""
|
||||
def test_qwen3_inline_ref_audio_hot_path_does_not_use_named_speaker_cache(self, qwen3_tts_server, mocker):
|
||||
"""An OpenAI-compatible voice does not identify an inline voice clone."""
|
||||
ignored_voice_log = mocker.patch("vllm_omni.entrypoints.openai.tts_adapters.qwen3_tts.logger.info")
|
||||
wav_list = [0.0] * 48000
|
||||
artifact_key = "a" * 40
|
||||
ref_audio = "data:audio/wav;base64,same"
|
||||
@@ -5531,6 +5532,7 @@ class TestTTSAsyncOffloading:
|
||||
|
||||
request = OpenAICreateSpeechRequest(
|
||||
input="hello",
|
||||
voice="voice-a",
|
||||
task_type="Base",
|
||||
ref_audio=ref_audio,
|
||||
ref_text="reference",
|
||||
@@ -5540,7 +5542,14 @@ class TestTTSAsyncOffloading:
|
||||
)
|
||||
|
||||
assert request_id == "req-hot"
|
||||
assert request.voice == "voice-a"
|
||||
ignored_voice_log.assert_called_once_with(
|
||||
"Ignoring voice=%r for Qwen3-TTS Base request because inline ref_audio takes precedence",
|
||||
"voice-a",
|
||||
)
|
||||
assert "ref_audio" not in tts_params
|
||||
assert "speaker" not in tts_params
|
||||
assert "voice_created_at" not in tts_params
|
||||
assert tts_params["_qwen3_tts_ref_audio_cache_key"] == [artifact_key]
|
||||
assert tts_params["ref_code_length"] == [50]
|
||||
prompt = qwen3_tts_server.engine_client.generate.call_args.kwargs["prompt"]
|
||||
|
||||
@@ -431,6 +431,14 @@ class Qwen3TTSAdapter(ARTTSAdapter):
|
||||
Qwen3-TTS ref-audio artifact tracked after ``generate()``.
|
||||
"""
|
||||
server = self.ctx.server
|
||||
# Inline Base cloning derives its voice from ref_audio, not the
|
||||
# OpenAI-compatible voice label.
|
||||
if has_inline_ref_audio and request.task_type == "Base" and request.voice is not None:
|
||||
logger.info(
|
||||
"Ignoring voice=%r for Qwen3-TTS Base request because inline ref_audio takes precedence",
|
||||
request.voice,
|
||||
)
|
||||
request = request.model_copy(update={"voice": None})
|
||||
qwen3_ref_audio_warmup_artifact_key: str | None = None
|
||||
tts_params = self._build_tts_params(request)
|
||||
# Resolve ref_audio (explicit or auto-set for uploaded voices)
|
||||
|
||||
Reference in new issue
Block a user