From 217df17ac30ba2a8c374088772f81926cc5beee3 Mon Sep 17 00:00:00 2001 From: Pascal Date: Fri, 7 Aug 2026 13:32:52 +0200 Subject: [PATCH] mtmd: stop feeding the text stream again during Qwen3-TTS generation (#26706) The reference implementation has two mutually exclusive prompt layouts. In non streaming mode the prefill carries the whole utterance text plus tts_eos summed with codec_pad, and the trailing text hidden collapses to a single tts_pad row. In streaming mode the prefill carries only the first text token and the trailing rows stream the rest of the text followed by tts_eos. The pipeline built the non streaming prefill but the streaming overlay, so the talker saw the utterance a second time during generation and read it twice before emitting codec_eos. The overlay is now the single tts_pad row that matches the prefill. --- tools/mtmd/mtmd-helper-gen.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tools/mtmd/mtmd-helper-gen.cpp b/tools/mtmd/mtmd-helper-gen.cpp index b52dc8e5a3..85671d1a33 100644 --- a/tools/mtmd/mtmd-helper-gen.cpp +++ b/tools/mtmd/mtmd-helper-gen.cpp @@ -112,7 +112,6 @@ public: c2w_state.clear(); audio_pcm.clear(); overlay.clear(); - overlay_idx = 0; h_state_buf.clear(); out_buf.clear(); prompt_embd_buf.clear(); @@ -205,11 +204,9 @@ public: top_p = inp->top_p > 0 ? inp->top_p : 1.0f; out_type = inp->out_type; - // the text stream keeps flowing during generation: after frame k, the input adds - // trailing text row k on top of the codes embedding, then tts_eos, then tts_pad - for (int i = 3; i < n_ids - 5; i++) overlay.push_back(row(ids[(size_t) i])); - overlay.push_back(row(tts_eos)); - overlay.push_back(row(tts_pad)); + // the prompt above holds the whole text stream up to tts_eos, so every generated + // frame adds tts_pad on top of the codes embedding + overlay = row(tts_pad); return 0; } @@ -265,9 +262,7 @@ public: } std::vector fb(out.embd, out.embd + n_embd); - const auto & ov = overlay[std::min(overlay_idx, overlay.size() - 1)]; - for (int i = 0; i < n_embd; i++) fb[(size_t) i] += ov[(size_t) i]; - overlay_idx++; + for (int i = 0; i < n_embd; i++) fb[(size_t) i] += overlay[(size_t) i]; const int n_pos_per_embd = mrope ? 4 : 1; decode_embd_batch batch_embd(fb.data(), 1, n_pos_per_embd, n_embd); @@ -437,8 +432,7 @@ private: std::vector codes_buf; std::vector c2w_state; std::vector audio_pcm; - std::vector> overlay; - size_t overlay_idx = 0; + std::vector overlay; std::vector h_state_buf; mtmd_helper_gen_audio_outtype out_type = MTMD_HELPER_GEN_AUDIO_OUTTYPE_WAV; std::vector out_buf;