[Model] Add GLM-TTS text-to-speech model support (#3141)

Signed-off-by: BeatSeat <wendavid552@gmail.com>
Signed-off-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
This commit is contained in:
BeatSeatandYueqian Lin authored and GitHub committed 2026-05-24 05:42:26 +08:00
1 parent 748470c1fb
commit 28ce618f0e
38 files changed
+7568 -7

No files matched your search

@@ -2335,6 +2335,84 @@ class TestCosyVoice3Serving:
cosyvoice3_server._build_cosyvoice3_prompt.assert_awaited_once()
# ---- GLM-TTS Serving Tests ----
@pytest.fixture
def glm_tts_server(mocker: MockerFixture):
mocker.patch.object(OmniOpenAIServingSpeech, "_load_supported_speakers", return_value=set())
mocker.patch.object(OmniOpenAIServingSpeech, "_load_codec_frame_rate", return_value=None)
mock_engine_client = mocker.MagicMock()
mock_engine_client.errored = False
mock_engine_client.model_config = mocker.MagicMock(
model="zai-org/GLM-TTS",
hf_config=SimpleNamespace(min_token_text_ratio=2, max_token_text_ratio=20),
)
mock_engine_client.default_sampling_params_list = [
SimpleNamespace(max_tokens=2048, min_tokens=None, extra_args=None)
]
mock_engine_client.tts_batch_max_items = 32
mock_engine_client.generate = mocker.MagicMock(return_value="generator")
mock_engine_client.stage_configs = [
SimpleNamespace(
engine_args=SimpleNamespace(model_stage="glm_tts"),
tts_args={},
)
]
mock_models = mocker.MagicMock()
mock_models.is_base_model.return_value = True
return OmniOpenAIServingSpeech(
engine_client=mock_engine_client,
models=mock_models,
request_logger=mocker.MagicMock(),
)
class TestGLMTTSServing:
def test_validate_glm_tts_requires_ref_audio(self, glm_tts_server):
request = OpenAICreateSpeechRequest(input="Hello", ref_text="Reference transcript")
error = glm_tts_server._validate_glm_tts_request(request)
assert error is not None
assert "ref_audio" in error
def test_validate_glm_tts_requires_ref_text(self, glm_tts_server):
request = OpenAICreateSpeechRequest(input="Hello", ref_audio="data:audio/wav;base64,abc")
error = glm_tts_server._validate_glm_tts_request(request)
assert error is not None
assert "ref_text" in error
def test_estimate_glm_tts_target_text_len_uses_tokenizer_tokens(
self,
glm_tts_server,
mocker: MockerFixture,
):
class FakeTokenizer:
def encode(self, text):
assert text == "normalized target"
return [10, 20, 30]
mocker.patch(
"vllm_omni.model_executor.models.glm_tts.glm_tts.resolve_glm_tts_tokenizer_path",
return_value="resolved-tokenizer",
)
load_tokenizer = mocker.patch(
"vllm_omni.model_executor.models.glm_tts.glm_tts.load_glm_tts_tokenizer",
return_value=FakeTokenizer(),
)
mocker.patch(
"vllm_omni.model_executor.models.glm_tts.text_frontend.GLMTTSTextFrontend.text_normalize",
return_value="normalized target",
)
text_token_len = glm_tts_server._estimate_glm_tts_text_token_len("abcdef")
assert text_token_len == 3
load_tokenizer.assert_called_once()
class TestTTSAsyncOffloading:
"""Tests for event-loop-safe offloading of blocking TTS operations."""