0

Why YUE2 // GROOVE keeps YuE2's reference configuration — and what "16 GB" really means

@bearboneposted Thu, 17 Sep 2026 10:12:16 GMT·Official·1 reply

Two questions come up under every YuE2 launcher: "why does this need so much VRAM?" and "why not run a quantized model?"

Here is what we measured, and the reasoning behind Groove's choices.

Nothing below is aimed at any other project. Several teams are doing real engineering to fit YuE2 onto small GPUs, and they are solving a different problem.

Part 1 — what a full-length song actually needs

Upstream's stated requirement is an NVIDIA GPU with BF16 support and 24 GB VRAM, generating without quantization. Upstream's own model card also publishes measured peaks: about 11.0–11.2 GiB for a normal full-CoT run on an RTX 4090, and 14.08 GiB in a maximum-context test. In other words, the 24 GB recommendation leaves substantial headroom relative to those published measurements.

We ran one full-length song — 4 min 45 s, about 10,200 generated tokens (score + semantic), roughly 11,100 tokens of context at its longest point, CFG 1.5, a deliberately heavy case — on an NVIDIA L4 with Groove's memory budget set to different hard allocation caps:

Memory budget Allocation cap Result Peak VRAM¹
24 GB 20 GiB ✅ complete 10.5 GiB
16 GB 14 GiB ✅ complete — score.abc, semantic.npy, audio.flac byte-identical to the 24 GB run 10.8 GiB
12 GB 10 GiB ❌ OOM at ~60 s, reproduced twice 10.25 GiB at failure
12 GB, FP8 (upstream experimental mode) 10 GiB ✅ complete, 4.2× slower than the BF16 budget-16 run 9.9 GiB

¹ Peak VRAM was sampled with nvidia-smi at 5-second intervals, so these are lower bounds; the 10.25 GiB figure comes from the CUDA allocator's own out-of-memory report.

The budget only constrains allocation; in this test, the matching hashes confirm that lowering the cap did not change the generated outputs. The observed peak for this test song was about 10.5–10.8 GiB; the model weights alone are 7.3 GB in BF16.

What that does and does not show: a 14 GiB allocation cap is validated for this workload, which strongly suggests a 16 GB-class card is sufficient. We have not yet run this test on a physical 16 GB GPU, however, and this is controlled data from one song.

This is also not a claim that 16 GB covers YuE2's maximum-context workload. Upstream reports a 14.08 GiB peak for that case, leaving essentially no headroom under a 16 GB-class memory budget and potentially exceeding the effective cap of a physical card. Our claim is narrower: 16 GB-class hardware looks realistic for the full-length workload we measured, not for every possible YuE2 workload.

Longer or denser songs use more context, and CFG increases AR-stage memory substantially. At the 12 GB setting, the BF16 run had about 10.25 GiB already in use against the 10 GiB cap when it failed.

That margin is small enough that a lossless memory optimization — using a tighter, workload-appropriate semantic_sampling.max_tokens ceiling instead of pre-allocating the semantic KV cache for the default 9,000-token generation budget — may get this workload through. We are testing it and will report.

Until then, 12 GB means FP8, at roughly 4× the generation time on our L4.

On Apple Silicon, the same song takes ~10.5 GB of GPU allocation on our 64 GB test Macs. We have validated 32 GB unified-memory Macs; we have not validated 16 GB Macs.

Part 2 — why Groove does not ship a quantized model

What Groove runs

On CUDA, Groove runs the official YuE2 weights and upstream's model and inference code unchanged: BF16 AR/NAR and the official FP32 VAE, which upstream enforces in code.

The default listening path uses YuE2-Vae, upstream's recommended decoder. YuE2-Vae-legacy is available separately for reproducing the recorded WildSongBench decoder protocol.

On Apple Silicon, Groove runs the same weights and model code on a backend upstream does not officially validate. We use PyTorch 2.14 instead of upstream's pinned 2.10 because of a known MPS attention defect in the older version. That deviation is measured and documented rather than hidden.

Upstream ships no quantized weights. It does ship an opt-in, explicitly experimental FP8 mode for the AR transformer, documented as carrying "no quantized quality or speed claim". Groove exposes that mode unchanged and labels it the same way.

What low-VRAM ports change

Different projects make different combinations of trade-offs.

In the implementations we inspected as of 17 September 2026 — including WanGP's YuE2 integration, the ahmadw MLX port and its Pinokio wrapper, and the audio.cpp GGUF builds — these include combinations of:

  • weight quantization of the AR and/or acoustic transformers;
  • alternative inference kernels and RNG paths;
  • reduced decoder precision in some builds, such as BF16 or FP16 VAE execution;
  • reduced ODE step counts in some presets, such as 8 instead of 32.

These choices differ by project and should not be treated as one common configuration.

Some projects publish useful quantitative parity or error measurements — logits, NAR outputs, decoder parity, or related numerical checks. What we have not found is a controlled blind-listening or WildSongBench comparison that isolates those lower-precision configurations against the official BF16 reference.

So we isolated the stages we could.

For decoder comparisons, we decoded the exact same latent. For acoustic-stage comparisons, we used the exact same semantic tokens and initial noise. One variable changed at a time, and we measured sample-level SNR against the reference render.

Higher SNR means closer to the reference waveform:

Change SNR vs reference²
Different PyTorch build, same CUDA GPU 119 dB
Same CUDA latent → FP32 VAE on M4 Pro vs CUDA 109.8 dB
Decoder run in BF16, weights + activations 35 dB
Same CUDA semantic tokens + same noise → NAR + VAE on M4 Pro vs CUDA, 32 steps 28.6 dB
ODE 32 → 48 steps on CUDA 28.0 dB
ODE 32 → 16 steps 21 dB
ODE 32 → 8 steps 17 dB

² Rows 1, 2, 4 and 5 are measured against the CUDA reference render. Rows 3, 6 and 7 were measured on the M4 Pro against that machine's own FP32 / 32-step render of the same tokens; against the CUDA render they differ by no more than 0.2 dB.

How to read this

The 32→48 row is a calibration point. Changing the model's own solver-step setting moves the render by about 28 dB.

That does not make 28 dB a perceptual threshold. SNR measures numerical distance from the reference render; it does not say whether the difference sounds better or worse.

By this metric, reducing the solver to 16 or 8 steps is a substantially larger departure than the 32→48 change. Running the decoder in BF16 is also measurable, but remains closer to the reference than 32→48.

That distinction between numerical distance and perceptual quality is not theoretical. In our one non-blind cross-platform re-render comparison at 28.6 dB, the author actually preferred the M4 Pro render. One pair proves nothing about systematic quality, but it is a useful reminder that numerical distance does not imply a quality direction: farther from the reference does not automatically mean worse.

Changing the seed is also a different category of variation. A different seed can change the composition itself, whereas the rows above isolate numerical or rendering changes while holding the musical content fixed.

We have not run our own controlled INT8 A/B, so INT8 transformers are not in this table.

Why that leads to Groove's default

Our position follows from the measurements, not from a claim that quantization sounds worse.

Quantization creates a different numerical configuration. Equivalence to the published reference is something that has to be demonstrated, not assumed.

And in Groove's case, the unquantized reference already completes our full-length test under a 14 GiB allocation cap. That removes much of the practical reason to silently replace the published configuration with a lower-precision one.

So Groove keeps the reference path by default, uses lossless memory-management tools such as the allocation budget above, and exposes upstream's FP8 mode as a clearly labelled experimental option.

Every run records model-weight hashes, the upstream runtime hash, and the effective configuration so the numerical environment is fully traceable.

An identical rerun on our M4 Pro reproduced the entire generation pipeline bit for bit through audio.flac. On CUDA, changing only the memory cap from 20 GiB to 14 GiB left the generated score.abc, semantic.npy, and audio.flac byte-identical.

If Groove ever ships an additional lower-precision mode, it will come with measurements like the ones above rather than being introduced as a silent replacement.

If you want to stay on the authors' unquantized reference inference path, that is what Groove is designed for.

Our 4:45 test song completed unchanged under a 14 GiB allocation cap, so a 16 GB-class GPU is much more realistic than the upstream 24 GB guideline might suggest — for workloads in this range.

That does not mean 16 GB covers the model's maximum context. It means the practical floor for full-length workloads in this range can be substantially lower than the upstream hardware recommendation.

If your priority is fitting YuE2 into an 8 GB card, quantized ports solve a different — and entirely legitimate — problem.

Just treat that as a different numerical configuration, and evaluate it as one.

Replies (1)
Up to 10 files, 25MB each. Images are optimized; GIFs -> MP4; videos 720p (max 120s).
Why YUE2 // GROOVE keeps YuE2's reference configuration — and what "16 GB" really means · Pinokio