Skip to content

MiniMax Music3 preview: fix BF16 conv corruption, repair converter, wire web UI - #243

Merged
0xShug0 merged 3 commits into
0xShug0:preview/minimax-music-3from
JoeMattie:preview-improvements
Aug 15, 2026
Merged

MiniMax Music3 preview: fix BF16 conv corruption, repair converter, wire web UI#243
0xShug0 merged 3 commits into
0xShug0:preview/minimax-music-3from
JoeMattie:preview-improvements

Conversation

@JoeMattie

Copy link
Copy Markdown

Follow-up to #241 per the discussion there: improvements and missing pieces applied on top of preview/minimax-music-3. Three focused commits.

1. Fix silent output corruption with BF16 conv kernels

Symptom: generating with the BF16 component variants (flow_transformer_gguf=transformer_bf16.gguf when the file stores BF16 conv kernels, or any package produced by the branch's converter with --type bf16) produces fully saturated output (a constant full-scale waveform) instead of music.

Root cause: the CUDA conv path does not support BF16 kernel types. The naive lowering hard-asserts (ggml-cuda/im2col.cu:86: GGML_ASSERT(dst->type == GGML_TYPE_F16 || dst->type == GGML_TYPE_F32)), and the fast path the flow transformer's 1x1 convs take silently produces garbage, which saturates the whole latent stream. The published transformer_q4_k.gguf / transformer_bf16.gguf on HF happen to carry F32 convs, which is why the default path works; the branch's converter as shipped regenerates them as BF16 and reproduces the corruption. A user passing minimax_music3.weight_type=bf16 converts the published F32 convs to BF16 at load and hits it too.

Fix, belt and suspenders:

  • Runtime: conv_safe_storage_type() guards the plain conv weight loads (flow preprocess/postprocess, condition encoder proj, vocoder dec_in_proj), falling back to F32 whenever the effective storage would be BF16. The weight-norm vocoder convs fold at load and are unaffected.
  • Converter: --keep-type rules pin those conv kernels to F32 on disk for every target type.

Verified: full-BF16 package (BF16 convs on disk) now renders healthy audio (32 s blues test, natural segment dynamics) at the same speed as before the guard. Isolation evidence: with the corruption present, swapping only the flow transformer to F16 restored correct audio while swapping only the depth decoder did not.

Measured on this branch while investigating (RTX 3090, CUDA 13.3, 32 s at 30 steps): BF16 flow at 44.5 s flow+vocode beats all-F16 at 49.0 s, so BF16 storage stays the right default here and no precision change is proposed - only the conv guard.

2. Repair the converter's spec handling and emit config sidecars

scripts/minimax_music3/convert_gguf.py as shipped fails in two ways:

  • write_variant_spec crashes with KeyError: 'tensors' because the spec's gguf source has no tensors map (the runtime opens component GGUFs by filename). The generated variant spec also fails audiocpp_gguf's source matching, aborting every conversion. Conversion now runs with --allow-missing-model-spec until the spec sources are aligned with the runtime's file layout.
  • The runtime requires config/<component>.json sidecars but the converter never emitted them, so a freshly converted package fails to load. The converter now copies them from the source snapshot.

3. Wire the family into the native web UI

  • webui/configs/models_catalog.json: a Music-generation entry with the language_model_q4_k.gguf entry file and the minimax_music3_q4_k install id.
  • webui/configs/model_params.json: advanced controls for num_inference_steps, guidance_scale, ar_guidance_scale, and top_k.
  • webui/native/src/lib/catalog.ts: an entry-file rule mapping the multi-component package to its language_model_*.gguf (same pattern as minimax_h3's dit.gguf).
  • The session additionally accepts the canonical duration_seconds request option (the UI's duration field) as an alias for duration_sec.
  • webui/native/dist/ rebuilt from the merged sources.

Notes for the open issues from #230's discussion

  • Quality metrics: rather than comparing full songs end to end, the harness in Add MiniMax-Music3 community model #241 compares deterministic component seams against the diffusers reference (exact tokenizer ids, greedy depth rollouts, LM/DiT logit correlation, vocoder SNR), which stays meaningful across precision changes because sampling randomness never enters the comparison. Happy to port that harness onto this branch as a follow-up.
  • Quant combos: data points from Add MiniMax-Music3 community model #241 that transfer directly: the depth decoder is quality-sensitive (Q8_0 flips top codebooks at near-ties; F16 is safe), token embeddings tolerate Q8_0, and slicing the LM output head to the 16385 sampleable rows saves about 1.5 GB with zero quality cost.
  • Longform: with the corruption fixed, this branch's BF16 flow path is already near its practical floor at 200-frame windows; the remaining longform ideas from Add MiniMax-Music3 community model #241 are bucketed KV views for very long songs and pipelining flow windows onto a second GPU while the AR stage streams.

🤖 Generated with Claude Code

JoeMattie and others added 3 commits August 14, 2026 19:34
BF16 conv kernels are unsupported by the CUDA conv path: the naive
im2col lowering asserts on the kernel type and the fast path the flow
transformer's 1x1 convolutions take silently corrupts, saturating the
generated audio into full-scale noise. This reproduces with any package
whose conv kernels are stored BF16 and with weight_type=bf16 over the
published F32-conv packages.

conv_safe_storage_type() falls back to F32 for the plain conv weight
loads (flow preprocess/postprocess, condition encoder proj, vocoder
dec_in_proj) whenever the effective storage would be BF16. The
weight-norm vocoder convolutions fold at load and are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The converter as shipped failed before writing any output: the variant
spec builder crashed on the spec's tensor-less gguf source, and the
generated spec did not pass audiocpp_gguf source matching, so every
component conversion aborted. Conversion now runs with
--allow-missing-model-spec until the spec sources are aligned with the
runtime's filename-based component loading.

Freshly converted packages also failed to load because the runtime's
required config/<component>.json sidecars were never emitted; they are
now copied from the source snapshot. Conv kernels are pinned to F32 on
disk through --keep-type rules for every target type, matching the
runtime guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds the catalog entry, advanced parameter controls, and the
entry-file rule mapping the multi-component package to its
language_model GGUF. The session accepts the canonical
duration_seconds request option as an alias for duration_sec, which is
what the UI's duration field sends.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@0xShug0
0xShug0 merged commit 12719a0 into 0xShug0:preview/minimax-music-3 Aug 15, 2026
@0xShug0

0xShug0 commented Aug 15, 2026

Copy link
Copy Markdown
Owner

@JoeMattie! Good catch on these issues and thank you for the insights on quant and longform optimization. Feel free to port your tests or do optimizations. I’m currently testing q4_0. It’s about 15% faster than q4_k, roughly matching q8_0, while using less VRAM (peak ~11 GB). I think we can definitely push it further by fusing weights and selectively quantizing specific layers.

Update: Pushed my changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants