The Patchbay_

Generate Songs with YuE2

YuE2 writes an editable melody-and-chord score, then renders it as a full 48 kHz song with vocals — the only open music model where you can read and change the composition before it becomes audio.

Last updated 2026-09-12

YuE is the open lyrics-to-song model from M·A·P and HKUST. It is also the most-changed project in open music generation: the original YuE has been superseded by YuE2, which works in a fundamentally different way and posts benchmark numbers competitive with Suno.

Almost everything written about YuE online describes version 1. This page covers YuE2 — what actually installs today.

If you have read about YuE elsewhere, read this first. YuE2 is not an incremental update. Version 1 generated audio tokens directly from lyrics. YuE2 first writes an editable musical score, then renders it. That changes the workflow, the hardware requirements, the output quality, and — importantly — the licence. The original code is preserved on the YuE-v1 branch, but the project has moved on.

What makes YuE2 different: the score is visible

Nearly every music model is a black box — prompt in, audio out, and if it's 80% right your only option is to re-roll and hope. YuE2 splits generation into two stages you can get between.

One AR–NAR Mixture-of-Transformers backbone predicts a symbolic plan — melody and chords, written as ABC notation — and semantic tokens autoregressively. Flow matching then generates acoustic latents from that plan, and a VAE decodes them to 48 kHz stereo audio.

The consequence is the whole point of the model: you can read, play and edit the composition before it becomes audio. Don't like the chord in bar 12? Change that chord and re-render, with the melody, tempo, meter and lyrics held exactly. The project calls this white-box music generation, and no other open music model offers it.

It also explains why YuE2 handles covers well. Transcribe an existing recording to a score, hand the score back with a different style prompt, and you get the same tune performed differently.

Hardware and platform: read this before installing

RequirementDetail
OSLinux. The documented, supported platform — there is no macOS or Windows path
Python3.12
GPUNVIDIA with BF16 support, 24 GB VRAM
QuantisationNone. YuE2 produces 48 kHz stereo without it, and the 24 GB figure assumes that
ConcurrencyOne request at a time
Output48 kHz stereo FLAC

That 24 GB on Linux is the steepest requirement of any model covered on this site. There is no small variant, no CPU fallback and no Apple Silicon support. A 4090, a 3090, or rented cloud time.

If that rules you out, ACE-Step does full songs with vocals on 8 GB, runs on macOS and Windows, and is Apache-2.0 including its weights. It does not sound as good. It will actually run on your machine.

Install

git clone https://github.com/multimodal-art-projection/YuE.git
cd YuE
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install .

python examples/generate.py --output outputs/first-song

Model files download from Hugging Face on first use. Open outputs/first-song/audio.flac — and note the output directory also keeps the score, the semantic tokens, the acoustic latents, the settings and the model identities. That record-keeping is deliberate, and it's what makes comparisons between runs meaningful.

Your first song

A request is a small JSON object. This is the project's own example:

{
  "id": "city_lights",
  "style": "English, warm piano pop, expressive female voice, acoustic piano, rounded bass and light drums, lyrical memorable melody, unhurried phrasing, 88 BPM",
  "lyrics": "[Verse]\nNeon fades along the lane\nFootsteps keep the time of rain\nFold the night and leave it here\nMorning has a sky to clear\n\n[Chorus]\nLet the day come into view\nEvery road begins with you\nHold a little room for light\nWe will sing beyond the night",
  "cot": "full",
  "seed": 831001
}

The two text fields do different jobs. style carries genre, instruments, vocal character, language and tempo. lyrics carries the words, with [Verse] and [Chorus] section tags. Note the style field leads with the language — that's how you steer it.

import json
from pathlib import Path
from yue2 import YuE2Pipeline

request = json.loads(Path('examples/song.json').read_text(encoding='utf-8'))

with YuE2Pipeline.from_pretrained('m-a-p/YuE2-3B', device='cuda') as pipe:
    song = pipe(**request)
    song.save_artifacts('outputs/my-song')
    print(song.truncated)

Or from the command line:

yue2 generate --request examples/song.json --output outputs/song-cli

One call produces one candidate. The headline benchmark figure uses best-of-8 selection, which is a separate evaluation step — so if you compare a single local generation against the published numbers, you are not comparing like with like.

Planning modes

SettingBehaviour
cot="full"Plan melody and chords. The default for new songs
cot="melody"Plan melody only, accompaniment free. Recommended for covers
cot="off"Generate straight from lyrics and style, no symbolic plan
abc=...Supply your own score. Requires full or melody

The distinction between full and melody is about how much freedom the arrangement gets. A full score fixes the harmony; a melody-only score lets the model reharmonise to suit the style you asked for. That is exactly why melody-only is the recommendation for covers — you want the tune, not the original chords.

cfg_scale controls text guidance. The defaults are ready to use, and the project's own guidance is that changing sampling or guidance settings may change quality — not necessarily improve it.

The staged API: stop between plan and audio

This is the part worth learning. Rather than one call, run the stages yourself and inspect the composition in between:

import json
from pathlib import Path
import soundfile as sf
from yue2 import YuE2Pipeline, SymbolicPlan

request = json.loads(Path('examples/song.json').read_text(encoding='utf-8'))

with YuE2Pipeline.from_pretrained('m-a-p/YuE2-3B', device='cuda') as pipe:
    plan = pipe.plan(**request)       # 1. the composition
    plan.save('outputs/plan')         #    inspect outputs/plan/score.abc here

    restored = SymbolicPlan.load('outputs/plan')
    semantic = pipe.generate_semantic(restored)   # 2. semantic tokens
    latents  = pipe.synthesize(semantic)          # 3. acoustic latents
    audio    = pipe.decode(latents)               # 4. waveform

sf.write('outputs/plan/audio.flac', audio, 48000)

SymbolicPlan.load restores exact token IDs and verifies the saved files, so re-rendering an unchanged plan is genuinely reproducible.

Don't edit a saved plan in place. To change the composition, copy the ABC out, edit the copy, and submit it as a new abc input. The saved plan carries token IDs and integrity records that won't survive hand-editing.

Editing the composition

The workflow that makes YuE2 worth the 24 GB. Generate a plan, edit the score, re-render:

python skills/yue2-music/scripts/run_yue2.py plan \
  --request examples/song.json --output outputs/plan

cp outputs/plan/score.abc edited.abc

Now edit edited.abc — change chord symbols, adjust a melody note, alter the section order — and render it:

python examples/generate.py --request examples/song.json \
  --abc-file edited.abc --cot full --output outputs/edited

The repository ships abc_tools.py for checking that an edit changed only what you intended:

python skills/yue2-music/scripts/abc_tools.py inspect edited.abc
python skills/yue2-music/scripts/abc_tools.py compare outputs/plan/score.abc edited.abc

A match: true result means notes, timing, meter and tempo are unchanged — the comparison deliberately allows harmony to differ. That's a real regression test for a musical edit, which is an unusual thing to be able to say about a generative model.

One limit worth being clear about: editing re-renders the whole song. It does not preserve the original waveform outside the edited region. If you loved the vocal take, editing the harmony will not keep it.

Covers: transcribe, restyle, re-render

Covers use transcription of a different kind — SheetSage2, the project's own audio-to-score model. It needs its own environment, because its dependencies conflict with YuE2's:

python3.11 -m venv .venv-sheetsage2
.venv-sheetsage2/bin/python -m pip install huggingface-hub==0.36.0
.venv-sheetsage2/bin/huggingface-cli download m-a-p/SheetSage2 \
  --local-dir models/SheetSage2
.venv-sheetsage2/bin/python -m pip install \
  torch==2.8.0 torchaudio==2.8.0 \
  --index-url https://download.pytorch.org/whl/cu126
.venv-sheetsage2/bin/python -m pip install -r models/SheetSage2/requirements.txt

Transcribe the source, keeping melody only so the accompaniment can move:

.venv-sheetsage2/bin/python models/SheetSage2/infer.py source.wav \
  --output cover-score --melody-only

Then hand the score back to YuE2 with new lyrics and a target style:

.venv/bin/python examples/generate.py --request cover-request.json \
  --abc-file cover-score/score.abc --cot melody --output outputs/cover

Run the two sequentially so they can share one GPU. And review the transcription before generating — transcription errors propagate straight into the cover.

The reported cover numbers are striking: 0.647 CLEWS mAP with a full score versus 0.006 without one, on 948 works, using the general checkpoint with no cover-specific fine-tuning. The score is doing essentially all the work of preserving musical identity.

Where it actually ranks

From the project's WildSongBench evaluation — 192 prompts, automatic metrics. Abbreviated to the relevant rows; † marks models with publicly available weights.

SystemSongBench Avg ↑MuLan ↑PER ↓
YuE2 (best-of-8) †6.96320.50519.79%
Mureka 96.93770.439411.69%
Suno v56.87210.54288.10%
YuE2 †6.73160.50688.44%
Suno v4.56.69950.50225.80%
Suno v66.55620.49167.58%
ACE-Step 1.5 †6.01180.43727.46%
YuE 1 †4.91650.262336.38%

Read these carefully, and with the usual caution that they are the authors' own evaluation of their own model:

Reproducibility and decoders

Two decoders ship, and which you use changes the audio:

DecoderUse
m-a-p/YuE2-VaeDefault, for generation and listening
m-a-p/YuE2-Vae-legacyReproducing the published benchmark protocol
with YuE2Pipeline.from_pretrained(
        'm-a-p/YuE2-3B',
        vae='m-a-p/YuE2-Vae-legacy',
        device='cuda') as pipe:
    ...

# or decode cached latents again with a different VAE,
# instead of generating a whole new song
python skills/yue2-music/scripts/run_yue2.py decode \
  --source outputs/song --output outputs/song-benchmark \
  --vae m-a-p/YuE2-Vae-legacy

from_pretrained also accepts local model directories, revision, vae_revision, cache_dir and local_files_only=True. Pin both model and VAE revisions when comparing runs — and note that a seeded generation can still differ across GPUs, runtime versions or sampling settings. A seed is not a guarantee here.

Troubleshooting

SymptomCause and fix
CUDA out of memory24 GB is the floor and there is no quantised path. Close everything else, or rent a bigger GPU
Song ends abruptlyHit a token limit. Check the truncated flags in result.json — audio can be playable even when truncated
Your ABC is rejectedArbitrary ABC dialects may need conversion. Native melody input has Vocal and Ins voices and no chord symbols
abc supplied but ignoredabc requires cot="full" or "melody" — it does nothing with "off"
Cover loses the tuneReview the transcription first; errors carry straight through. Use melody mode and a score without chord symbols
SheetSage2 and YuE2 conflictThey need different dependency versions. Separate environments, run sequentially
Translated lyrics scan badlyMatch phrasing and syllable counts to the melody — the score fixes note durations
Same seed, different songDifferent GPU, runtime version or sampling settings. Pin revisions

Licensing: the catch

The code and the weights are licensed differently, and this has changed. YuE2's first-party code, agent skill and documentation are Apache 2.0. The model weights are CC BY-NC 4.0 — non-commercial. Older write-ups describing YuE as a fully permissive, commercially usable Suno alternative are describing version 1 and are out of date. Check MODEL_LICENSE in the repository before building anything commercial on this.

That puts YuE2 in the same commercial position as MusicGen: excellent, open to inspect, not licensed for you to sell the output of. Among open song models with vocals, ACE-Step remains the one whose weights are Apache-2.0.

ModelCodeWeightsCommercial use
YuE2Apache-2.0CC BY-NC 4.0No
ACE-StepApache-2.0Apache-2.0Yes
MusicGenMITCC-BY-NC 4.0No
Stable Audio OpenMITStability Community LicenseConditional

Where it fits

YuE2 is the best-sounding open song model, and the only one where you can read and edit the composition before it becomes audio. If you are researching music generation, doing zero-shot covers, or want musical control rather than prompt roulette, it is the most interesting thing in open source right now.

It is also Linux-only, needs 24 GB, and its weights are non-commercial. For a product, use ACE-Step. For instrumental texture, use MusicGen. For sound design, use Stable Audio Open. For a song you want to shape like a composer rather than describe like a customer, this is the one.

See also YuE vs ACE-Step and the open models overview.

Generate songs with ACE-StepApache-2.0 weights, 8 GB, and it runs on macOS.Train your own RAVE modelNeural timbre transfer you can play in real time.YuE vs ACE-StepThe two open lyrics-to-song models, compared.

← AI music generation hub