MTMD: Fix Qwen3-tts-0.6b - #28231
Merged
Merged
Conversation
The talker and the code predictor share the hidden size on the 0.6B checkpoints, so the reference builds no small_to_mtp_projection and the conversion emits no tensor for it. The graph already falls back to identity when the weight is missing, the loader now agrees.
The code predictor carries a massive activation: its layer 2 FFN intermediate peaks around 1.5e5, well past the 65504 ceiling of F16. mul_mat casts its input to the weight type, so an F16 ffn_down turns that peak into inf, the residual follows, and the next rms_norm yields NaN. Reference forward in float32 gives 145109 against 145396 measured in the graph.
CISC
approved these changes
Sep 2, 2026
12 tasks
ggerganov
approved these changes
Sep 2, 2026
Contributor
Author
|
I have another small PR to submit for the Vulkan crash: the gen graph hands GET_ROWS an index that is a view at a few bytes offset, which the Vulkan path rejects, and materializing those three index rows fixes it with bit for bit identical output on CPU and CUDA. |
Lawlietr
pushed a commit
to Lawlietr/llama.cpp
that referenced
this pull request
Sep 3, 2026
* mtmd: load the qwen3-tts code predictor proj_in as optional The talker and the code predictor share the hidden size on the 0.6B checkpoints, so the reference builds no small_to_mtp_projection and the conversion emits no tensor for it. The graph already falls back to identity when the weight is missing, the loader now agrees. * mtmd: keep the qwen3-tts code predictor ffn_down in F32 The code predictor carries a massive activation: its layer 2 FFN intermediate peaks around 1.5e5, well past the 65504 ceiling of F16. mul_mat casts its input to the weight type, so an F16 ffn_down turns that peak into inf, the residual follows, and the next rms_norm yields NaN. Reference forward in float32 gives 145109 against 145396 measured in the graph.
10 tasks
fewtarius
pushed a commit
to fewtarius/CachyLLama
that referenced
this pull request
Sep 5, 2026
* mtmd: load the qwen3-tts code predictor proj_in as optional The talker and the code predictor share the hidden size on the 0.6B checkpoints, so the reference builds no small_to_mtp_projection and the conversion emits no tensor for it. The graph already falls back to identity when the weight is missing, the loader now agrees. * mtmd: keep the qwen3-tts code predictor ffn_down in F32 The code predictor carries a massive activation: its layer 2 FFN intermediate peaks around 1.5e5, well past the 65504 ceiling of F16. mul_mat casts its input to the weight type, so an F16 ffn_down turns that peak into inf, the residual follows, and the next rms_norm yields NaN. Reference forward in float32 gives 145109 against 145396 measured in the graph.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Fixes Qwen3-TTS-12Hz-0.6B: the loader no longer requires the code predictor input projection, which that checkpoint does not have, and the predictor ffn_down stays in F32 since its FFN intermediate peaks above the F16 range.
The fix spans both sides, C++ and conversion script. The C++ half only needs a rebuild, but the F32 rule lives in the conversion script, so please regenerate the mmproj GGUF files.
Additional information
Qwen3-TTS-12Hz-0.6B failed in two different ways and this fixes both. The mmproj refused to load because the loader required the code predictor input projection, which the reference only builds when the talker and the predictor differ in hidden size, so the 0.6B checkpoint simply has no such tensor. With that out of the way the model then died on the first frame: its code predictor carries a massive activation, a spike about twice what F16 can represent, and since mul_mat casts its input to the weight type an F16 ffn_down turned that spike into infinity, then NaN, then an out of bounds gather. Keeping those five weights in F32 costs roughly 31 MB and makes the model run on CPU and CUDA again. The 1.7B is unaffected either way, it has more than six times the headroom under the F16 ceiling.
Existing mmproj GGUF files need to be regenerated: the fix lives in the conversion script, so a GGUF converted before this change still carries the F16 ffn_down and will still break on the 0.6B. The rule applies to every checkpoint in the family, so regenerate the 1.7B GGUF files as well and keep the published set on one consistent format.
Voice cloning stays speaker-embedding only for now: the helper exposes no reference transcript and builds only the speaker-slot prompt, and more fundamentally the conversion script packs just the decoder half of the speech tokenizer, so there is no codec encoder to turn a reference clip into the codes the in-context cloning mode feeds on.
Follow-up #26254
Testing
Short sample: "the quick brown fox jumped over the lazy dog".
qwen3tts-0.6B-clone-short.wav
qwen3tts-0.6B-tts-short.wav
qwen3tts-1.7B-clone-short.wav
qwen3tts-1.7B-tts-short.wav
Long sample: "Here is what went wrong with the small model. Its code predictor carries one enormous activation, a single spike about twice the largest value a half precision float can hold. When the weights are stored in that format, the multiplication turns the spike into infinity, the next normalization turns infinity into a not a number, and the whole thing collapses into an out of bounds memory read. The fix keeps five small weight tensors in full precision. It costs about thirty megabytes, and it lets the model run everywhere again."
qwen3tts-0.6B-clone-long.wav
qwen3tts-0.6B-tts-long.wav
qwen3tts-1.7B-clone-long.wav
qwen3tts-1.7B-tts-long.wav
The plain TTS clips use the model's own default voice, the cloned ones are conditioned on a 17 s reference recording of a real speaker.
Requirements