Repository navigation
Conversation
…T, DAV), music3-generate and --serve The AR LM with its depth decoder in a CUDA-graph frame step (warp-a-row GEMVs at the GB10 read ceiling, SwiGLU fused into gate/up, CFG top-k drawn on the device), int8 weight-only by default (a scale a row; depth decoder a scale a group of 128); the DiT on tuned cuBLASLt fp16 GEMMs with our flash attention; the DAV in fp32 tap SGEMMs. --serve speaks a JSON-lines protocol shared with our Mac MLX engine. Parity vs ComfyUI's native nodes, kernel contract gates 1-4 and gate 5 records, docs/recipes/minimax-music3-cuda.md with the receipts.
The AR's sampling, result, trace and progress types, the song's timings, the weight bytes a frame reads and the clock move to common.zig. The weight loaders take any store with alloc / upload / stage / unstage, and the CUDA store moves to store.zig, so weights.zig no longer touches the CUDA runtime. generate.zig names its backend from the family module and asks the engine for its weight bytes; parity.zig takes either engine. No change to what the CUDA engine computes: the same kernels run on the same buffers in the same order.
The AR LM with its depth decoder (int8 by default, bf16 with --weights bf16), the DiT and the DAV on TensorFold's own Metal runtime, from Zig, with kernels of their own in one metallib built ahead of time. - zig/kernels/metal/music3: the decode GEMVs (bf16, int8 a scale a row or a group of 128), attention, the CFG top-k draw, tensor-unit GEMMs (bf16 prompt rows; fp16 DiT with its rope and GLU in the epilogues; the DAV's fp32 from bf16 halves), the DiT's attention and glue, the DAV. - zig/src/families/music3/metal: the device, launches, AR, DiT, DAV and engine; music3_metal.zig is the family's Metal root, driven by the shared generate.zig and parity.zig. - zig/build/music3_metal.zig: the metallib, the family module and zig build music3-generate on macOS. - The kernel contract: 57 Metal records, gates 1-4 for m3_rmsnorm and the music3 sources for gate 5. - docs/recipes/minimax-music3-metal.md and its parity and lyric JSON.
Owner
|
Thank you, @drowzeys, for the Metal Music 3 port and repeated WAV measurements. Music 3 moves to 1.1.1, the next patch release. The reviewed integration uses the shared frame queue and prompt cache, independent session state and completion-aware cleanup; the prompt rewrite retains the credited model and design references. Please provide the ten frozen prompt-ID cases with the matching tokenizer. The combined build still needs audio fidelity, resumed/fresh and concurrent/solo WAV comparisons, cancellation/reopen checks, resources, memory and matched speed. No Metal Music 3 audio run is recorded; frozen prompt/tokenizer fixtures and fidelity, resume, concurrency and cancellation checks remain owed. Posted by Ash's AI Assistant Synthena |
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.
This puts MiniMax Music 3 on TensorFold's own Metal runtime. A caption and lyrics go in; a 44.1 kHz stereo song with vocals comes out, from Zig and Metal on Apple Silicon, with no MLX, Python or PyTorch at run time. It is the Metal half of #982 and shares that pull request's config, prompt, checkpoint loaders, request settings, WAV writer,
--serveprotocol and parity tools. All three stages run here: the 8B AR LM with its 4-layer depth decoder (int8 by default,--weights bf16for the checkpoint's own), the 2.4B flow-matching DiT and the DAV decoder.On one Mac Studio (M5 Ultra, 256 GB), 60 s songs:
--serveprocess, write the same WAV bytes.m3_rmsnormpasses gates 1–4.zig build testpasses every step on macOS.Precision is the reference's, as on CUDA:
music3.metallibis built with safe math and precise fp32 functions. One exception: the fused GLU's sigmoid usesfast::exp, sinceprecise::expin that epilogue made the ff_in GEMM 2.6 times slower (final latent 38.92 dB with it, 38.97 dB without).Next steps:
steel_gemm_fused_nax; int8 or fp8 products would be the next lever, a quality risk against the fp16 reference, not tried.TF_SIMD_FRAGS) compiles for them under gate 5; a second metallib for them was not built or run.What it adds
On top of #982, in two commits:
music3: share the backend-independent parts before a Metal backend. No change to what the CUDA engine computes.common.zigholds the AR's sampling, result, trace and progress types, the song's timings, the weight bytes a frame reads and the clock.weights.zig's loaders take any store with alloc / upload / stage / unstage; the CUDA store moves tostore.zig, soweights.zigno longer touches the CUDA runtime.generate.zignames its backend from the family module and asks the engine for its weight bytes;parity.zigtakes either engine. The same two files now drive both backends.music3: MiniMax Music 3 lyrics to song on Metal:zig/kernels/metal/music3/(one metallib, built ahead of time):ar.metalholds the embeddings, the RMS norm, the int8 quantizer and the decode GEMVs (bf16, int8 a scale a row, int8 a scale a group of 128; a simdgroup two weight rows, or a gate and up row whose SwiGLU it writes).attn.metalholds the body's q / k norm and rope, split-key decode attention (four keys a step under onesimd_sum) and its merge, and the depth decoder's attention.sample.metalholds music3: MiniMax Music 3 lyrics to song on one CUDA GPU, from Zig (new family; proposal) #982's CFG top-k draw (radix select, inverse CDF on the same Philox counters) and the frame's bookkeeping.gemm.metalholds the tensor-unit GEMMs throughtfp::gemm_block(bf16 prompt rows; fp16 for the DiT with the q / k rope and the GLU folded into their GEMMs' epilogues) and the DAV's fp32 GEMM from bf16 halves.dit.metalholds the DiT's condition, windows, LayerNorm, timestep MLP, guided velocity, Euler step and noise;dit_attn.metalits attention on the tensor units (heads of 64, fp16 probabilities for P V as on CUDA).dav.metalholds snake, the transposed convs' overlap-add, the stereo halves and tanh.zig/src/families/music3/metal/:gpu.zig(the queue, the pipelines, and buffers addressed asu64, so the shared loaders and tools work unchanged),kernels.zig,ar.zig,dit.zig,dav.zigandengine.zig.music3_metal.zigis the family's Metal root.zig/build/music3_metal.zig, plus 4 lines inbuild.zig: the metallib, the family module, andzig build music3-generateon macOS.registry.zig;zig/tests/contract/metal_music3.zig(gates 1–4 form3_rmsnorm, and the music3 sources for gate 5); a few lines in the runner; the sources inzig/kernels/metal/sources.zig.docs/recipes/minimax-music3-metal.mdand its JSON (parity_metal_int8.json,parity_metal_bf16.json,lyrics.json).Each AR frame is encoded straight into a serial compute encoder and committed as soon as it is encoded, so the next frame encodes while the GPU runs the last one. Position, step and count advance on the GPU, as on CUDA, and the host reads the drawn tokens every 16 frames for the stop code.
Receipts
Machine and settings for every run:
-std=metal4.1)zig build music3-generate -Doptimize=ReleaseFastminimax_music3_text_encoder_pruned_bf16,minimax_music3_dit_fp16,minimax_music3_dav)Other processes on the machine: an Ollama server and another app were resident during the timed runs. I did not measure whether they used the GPU.
Parity against ComfyUI (
tools/music3/parity.py)ComfyUI's native nodes on the same Mac (MPS) recorded the dumps #982 describes: hiphop bench prompt, 30 s, seed 7. The MLX engine is against the same dumps; #982's CUDA numbers are against ComfyUI on its own GB10.
The draws cannot match ComfyUI's (torch's multinomial against the Philox inverse-CDF draw) or CUDA's (the logits differ in the last bits), so a song is the same model's, not the same song.
Speed and memory: this port against the MLX engine on the same machine
Hiphop bench prompt, 60 s, seed 7. The MLX engine runs with
--quant int8(8 bits in groups of 64 everywhere). The runs alternated (Metal, MLX, Metal, MLX, ...), three each. Peak is the process's own peak footprint (/usr/bin/time -l).Lyric accuracy (
tools/music3/lyrics_check.py)#982's three 45 s songs in each format through
--serve, transcribed by faster-whisper large-v3-turbo on the CPU and scored by the Studio'smusic.heard.Determinism and request state
e81021f8….--serveprocess give the bytes of a fresh process.Kernel contract (M5 Ultra)
m3_rmsnorm, plain-gamma form, against the rows family's float64 RMS norm at the served shapes (2, 4 and 600 rows of 4096).max_total_threads_per_threadgroup), so none needs an M1/M2 compile record.Lean check and tests
python3 tools/zig/lean_check.py: 517 problems on music3: MiniMax Music 3 lyrics to song on one CUDA GPU, from Zig (new family; proposal) #982's head and 517 on this branch, so there are no new ones. Every new file is at or below 600 lines.zig build test -Dcpu=apple_m1, fresh cache, on #982zig build test -Dcpu=apple_m1, fresh cache, this branch