MiniMax Music 3 on the 780M: local text-to-song generation via ComfyUI
Background
MiniMax released MiniMax Music 3 as an open-weights model on 2026-08-13, a hierarchical autoregressive music generator. An 8B global LLM handles long-range structure, paired with a 0.6B local LLM for frame-level acoustic detail, and synthesis itself runs through Flow Matching plus a Flow-VAE. It turns a text caption plus lyrics into a full song, up to roughly 300 seconds, at 32kHz 16-bit stereo. ComfyUI added native support the same week, core nodes with no custom node package required, starting at v0.33.0. This box was still on 0.32.0.
Install
ComfyUI update: git pull on the existing ComfyUI-TheRock checkout. The requirements.txt diff was small, three pinned package bumps (comfyui-frontend-package, comfyui-workflow-templates, comfy-kitchen) and an unpinned torch line. Installed only the pinned bumps explicitly:
pip install "comfyui-frontend-package==1.49.6" \
"comfyui-workflow-templates==0.11.43" \
"comfyui-embedded-docs==0.5.10" "comfy-kitchen==0.2.31"
Deliberately not pip install -r requirements.txt, since a bare torch line in that file will happily let pip resolve a stock CPU/CUDA wheel over an existing ROCm build if it runs against the wrong interpreter. Confirmed torch.version.hip was untouched (2.12.0+rocm7.15.0a20260728) after the targeted install.
Models, from Comfy-Org/MiniMax-Music-3 on Hugging Face, into the usual ComfyUI model folders:
| File | Size | Folder |
|---|---|---|
minimax_music3_dit_int8_convrot.safetensors | 2.50 GB | diffusion_models/ |
minimax_music3_text_encoder_pruned_int8_convrot.safetensors | 9.20 GB | text_encoders/ |
minimax_music3_dav.safetensors | 0.22 GB | vae/ |
INT8 (convrot quantization) was the choice over FP16 (a 4.9GB diffusion model) or the 16-18GB text encoder variants, since the 780M has roughly 14.8GB of total shared VRAM and no headroom for the bigger files. The eager compute backend, the one this ROCm build uses since the accelerated hip kitchen backend isn’t compiled for this install, lists convrot int8 quantize/dequantize ops as supported, so the low-VRAM path works here.
The node graph isn’t in the node list
The “MiniMax Music 3” block visible in ComfyUI’s UI is a frontend-only collapsed subgraph, not an executable node type, so building a /prompt API call by hand means finding the real graph underneath it. It’s bundled in the comfyui-workflow-templates-json package (templates/audio_minimax_music_3.json, under definitions.subgraphs):
UNETLoader → MiniMaxMusic3TextEncode → ConditioningZeroOut (negative)
↓ (also outputs a FLOAT "seconds")
CLIPLoader (type="minimax") ↗ EmptyMiniMaxMusic3LatentAudio
VAELoader ────────────────────────────────────↓
KSampler → VAEDecodeAudioTiled → SaveAudioAdvanced
Two things worth knowing before wiring this by hand:
- There’s no real negative prompt. The “negative” input is
ConditioningZeroOutfed from the same positive conditioning, a zeroed embedding rather than a text field. Steering away from unwanted elements, like excluding percussion, has to go directly in the positive caption as explicit exclusion language. SaveAudioAdvanced’s format is a dynamic combo. Submitting{"format": "mp3", "quality": "V0"}fails validation withRequired input is missing: quality (input_name: "format.quality"). The actual key has to be the literal string"format.quality"in the flat JSON, not a nested object.
Where the generation time goes
MiniMaxMusic3TextEncode isn’t a simple encode step. It runs the AR model’s full autoregressive sampling internally, visible as an AR sampling: N/M progress bar, before KSampler’s diffusion pass even starts. Total AR steps scale linearly with max_duration, consistently about 25 steps per target second, at a sustained 1.4-1.7 it/s on this GPU:
| max_duration | AR steps | AR phase | KSampler (30 steps) | Total |
|---|---|---|---|---|
| 20s | 501 | ~5 min | ~5s/step, ~2.5 min | ~8.5 min |
| 60s | 1501 | ~16 min | ~14s/step, ~7 min | ~24 min |
| 90s | 2251 | ~23 min | ~24s/step, ~12 min | ~35-40 min |
| 120s | 3001 | ~30 min | ~25-35s/step, ~15 min | ~45-55 min |
num_inference_steps for KSampler stays fixed at 30 regardless of duration. The audio latent just gets longer, so per-step cost rises instead. VAEDecodeAudioTiled (tile_size=1536, overlap=64) kept decode VRAM manageable at longer durations, over the plain VAEDecodeAudio node; the docs note it’s the recommended path for low-VRAM GPUs.
One real GPU-context lesson
A KSampler step on a 120s generation failed mid-run with:
CUDA error: HIPBLAS_STATUS_INTERNAL_ERROR when calling
`rocBLASStatusToHIPStatus(rocblas_gemm_ex(...))`
Resubmitting the identical prompt finished in 0.08 seconds, then hit a second, different error, invalid configuration argument, on the same node. ComfyUI’s in-memory node-output cache works: the roughly 23-minute AR phase was skipped entirely, reused straight from cache. And once ROCm/HIP throws an internal error like this, the device context is poisoned for the rest of the process, so every subsequent GPU operation fails almost instantly no matter what it is. Only a full ComfyUI process restart cleared it, which necessarily drops that same in-memory cache. Resubmitting from a clean process succeeded on the next attempt. No pattern turned up for what triggers it beyond heavier generations, later in a long session. It’s logged here as a real, so-far unexplained flake rather than a reproducible bug.
Reference audio and melody conditioning: not available here
MiniMax’s hosted API supports audio-reference “cover” generation: pass in a song, get back a reworked version with ASR-extracted lyrics. Checking both the registered ComfyUI nodes and the model source (comfy/ldm/minimax_music/, comfy_extras/nodes_minimax_music.py) turned up nothing that exposes an audio input on this end. That capability lives only in MiniMax’s paid hosted API, not in the open-weights checkpoint or ComfyUI’s current node set, which leaves text caption plus lyrics as the only local option.
Result
Generation works cleanly on the 780M through the INT8 diffusion model, the INT8 pruned text encoder, and VAEDecodeAudioTiled, with --reserve-vram 6 --cpu-vae unchanged from the existing launch config. Structured captions (Global Metadata, Vocal Details, and Arrangement sections) steer style and instrument choice reliably across iterations, right down to articulation, such as explicitly excluding staccato or spiccato strings. Generation time is the real trade-off. A 120s song runs closer to 45-55 minutes of wall-clock time on this hardware than anything resembling a quick turnaround, and that cost is front-loaded into the AR phase, before any audio exists to judge.