The Patchbay_

Generate Full Songs with ACE-Step

ACE-Step generates full songs with vocals from a style prompt and your lyrics, under Apache-2.0, fast enough to iterate with — and it is the one serious music model that runs properly on Apple Silicon.

Last updated 2026-09-12

ACE-Step is the open model that comes closest to what Suno and Udio do: give it a style prompt and lyrics, get back a full song with singing. It is Apache-2.0 licensed, which makes it the most permissive serious music model available, and it is fast — on an RTX 4090 it generates roughly 34× faster than real time, so a one-minute track takes under two seconds.

It also has the most interesting editing model of any open music generator. Retake, repaint, extend and lyric-editing let you change part of a track without regenerating the whole thing, which is the workflow difference that actually matters once you get past the first novelty generation.

Why ACE-Step is worth the setup

 ACE-StepMusicGenStable Audio Open
LicenceApache-2.0CC-BY-NC (non-commercial)Stability Community License
VocalsYes, with your lyricsNoNo
Typical lengthMinutes30 s window, stitched beyond47 s maximum
SpeedVery fast (diffusion, ~34× real time on a 4090)Slow (autoregressive)Moderate
EditingRetake, repaint, extend, lyric editContinuation onlyAudio-to-audio
Languages19, with 10 performing wellEnglish promptsEnglish prompts

The Apache-2.0 licence is the headline. It covers a 3.5B-parameter model that produces full songs, and it is the only combination of those three facts currently on offer.

Hardware, honestly

RTF here is real-time factor — how many seconds of audio per second of compute. Higher is better.

DeviceRTF @ 27 steps1 min of audioRTF @ 60 steps1 min of audio
RTX 409034.48×1.74 s15.63×3.84 s
A10027.27×2.20 s12.27×4.89 s
RTX 309012.76×4.70 s6.48×9.26 s
MacBook M2 Max2.27×26.43 s1.03×58.25 s

Two things to take from that table. First, even a 3090 generates a minute of music in under ten seconds — this is a model you can iterate with rather than wait on. Second, and unusually for this field, it runs on Apple Silicon: roughly real time at 60 steps on an M2 Max. That makes ACE-Step the most Mac-friendly serious music model available, where MusicGen is a fight and Stable Audio Open effectively needs CUDA.

With optimisation flags, VRAM comes down to around 8 GB.

Install

git clone https://github.com/ace-step/ACE-Step.git
cd ACE-Step

conda create -n ace_step python=3.10 -y
conda activate ace_step

# Windows + NVIDIA: install CUDA torch first
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126

pip install -e .
macOS. Set --bf16 false. The pipeline coerces to float32 on MPS anyway, but being explicit avoids confusing dtype errors. Do not pass --torch_compile on Mac.

Weights download to ~/.cache/ace-step/checkpoints on first run — the checkpoint is ACE-Step/ACE-Step-v1-3.5B, and it is several gigabytes. Point --checkpoint_path somewhere else if your home directory is small.

The web UI first

Start here even if you intend to use the Python API. The Gradio interface exposes every parameter with working defaults, and the fastest way to learn what the knobs do is to move them.

acestep --port 7865

For a machine with 8 GB of VRAM:

acestep --port 7865
8
FlagDefaultWhat it does
--checkpoint_pathautoWhere weights live; auto-downloads to the cache if unset
--port7865Gradio port
--server_name127.0.0.1Set to 0.0.0.0 to reach it from another machine on your network
--device_id0Which GPU
--bf16truebfloat16 precision; set false on macOS
--torch_compilefalseCompiles the model — slow first run, faster after. Windows needs triton-windows
--cpu_offloadfalseKeeps only the active stage on the GPU. The big VRAM saver
--overlapped_decodefalseSliding-window decode; faster, and reduces peak memory
--sharefalsePublic Gradio link
Don't use --share casually. It exposes a model that generates audio from arbitrary text to anyone with the URL, through a tunnel you don't control. Use --server_name 0.0.0.0 on a trusted network instead.

Writing prompts and lyrics

ACE-Step takes two separate inputs, and they do different jobs.

The prompt is a comma-separated tag list, not a sentence. It describes production, not narrative:

funk, soul, rhythm and blues, electric guitar, horn section, 105 bpm,
warm analog production, male vocal, groovy bassline

The lyrics field takes structure tags in square brackets, which is how you get song form rather than an undifferentiated stream:

[verse]
Neon signs across the empty street
Rain is falling to a steady beat
Every window holds a different light
Nobody sleeping in this town tonight

[chorus]
And we run, and we run
Till the morning comes undone
And we run, and we run

[verse]
Coffee cooling on the window sill
Half a story that I never will
Finish writing, finish saying out loud
Lost the melody somewhere in the crowd

[chorus]
And we run, and we run
Till the morning comes undone
And we run, and we run

The Python API

The UI is for exploring. For anything repeatable, drive the pipeline directly:

from acestep.pipeline_ace_step import ACEStepPipeline

pipeline = ACEStepPipeline(
    checkpoint_dir=None,       # auto-download to ~/.cache/ace-step/checkpoints
    dtype='bfloat16',          # 'float32' on macOS
    torch_compile=False,
    cpu_offload=False,
    overlapped_decode=False,
)

prompt = 'funk, soul, electric guitar, horn section, 105 bpm, male vocal'
lyrics = '''[verse]
Neon signs across the empty street
Rain is falling to a steady beat

[chorus]
And we run, and we run
Till the morning comes undone'''

pipeline(
    prompt=prompt,
    lyrics=lyrics,
    audio_duration=120.0,
    infer_step=60,
    guidance_scale=15.0,
    scheduler_type='euler',
    cfg_type='apg',
    manual_seeds=[42],
    save_path='./out/song.wav',
)

Setting save_path writes the file for you. Leave it unset and you get the audio back to handle yourself.

Every generation parameter

These are the real defaults from ACEStepPipeline.__call__. It is a long list; these are the ones worth touching.

ParameterDefaultWhat it does
audio_duration60.0Seconds. Unlike MusicGen there's no hard 30 s window — ask for 180 and you get a composed three-minute track
infer_step60Diffusion steps. 27 is the documented fast preset, 60 the quality default. Past 100, returns diminish
guidance_scale15.0Overall prompt adherence. Much higher scale than diffusion image models — don't port intuitions from those. 10–20 is the working band
scheduler_type'euler'Sampler. 'euler' or 'heun'; heun is slower per step and sometimes cleaner
cfg_type'apg'Guidance algorithm. APG is adaptive projected guidance — the default, and generally the best
omega_scale10.0Granularity of the guidance schedule
guidance_interval0.5Fraction of the denoising trajectory over which guidance is applied. Lower gives the model more freedom late in the process
guidance_interval_decay0.0Decays guidance across that interval; raise to loosen adherence as generation settles
min_guidance_scale3.0Floor that decay falls to
guidance_scale_text0.0Separate guidance for the style prompt. Raise to push style over lyric fidelity
guidance_scale_lyric0.0Separate guidance for lyrics. Raise when words come out slurred or wrong
use_erg_tag / use_erg_lyric / use_erg_diffusionTrueEnhanced rescaled guidance on tags, lyrics and diffusion. Leave enabled unless debugging
manual_seedsNoneList of seeds for reproducibility
batch_size1Candidates per call
format'wav'Output format

The two most useful non-obvious dials are guidance_scale_text and guidance_scale_lyric. When vocals are mumbled or the wrong words come out, raise the lyric one. When the track ignores your genre tags, raise the text one. A single global guidance_scale can't make that distinction.

Retake: variations without starting over

Retake regenerates with different seeds while holding most of the structure, controlled by retake_variance:

pipeline(
    task='retake',
    prompt=prompt,
    lyrics=lyrics,
    audio_duration=120.0,
    retake_seeds=[1234],
    retake_variance=0.3,   # 0 = near-identical, 1 = effectively a new track
    save_path='./out/retake.wav',
)

At 0.2 you get the same song performed slightly differently. At 0.8 you get a different song in the same style. This is the dial for "almost — try again" and it's far more useful than re-rolling from scratch.

Repaint: fix one section

Repainting regenerates a time range and leaves the rest intact. This is the feature that turns generation into editing — when a track is good except for a bad eight seconds, you fix those eight seconds.

pipeline(
    task='repaint',
    src_audio_path='./out/song.wav',
    prompt=prompt,
    lyrics=lyrics,
    repaint_start=45,      # seconds
    repaint_end=60,
    retake_variance=0.5,
    save_path='./out/repainted.wav',
)

repaint_start and repaint_end are in seconds. The model conditions on the surrounding audio so the repainted region joins up in key and tempo.

Edit: change the words, keep the tune

Edit mode alters the prompt or lyrics of existing audio. The edit_n_min and edit_n_max parameters control how much of the original is preserved — a narrow range keeps the melody and changes the words, a wide range lets the whole arrangement move.

pipeline(
    task='edit',
    src_audio_path='./out/song.wav',
    prompt=prompt,
    lyrics=lyrics,
    edit_target_prompt=prompt,           # unchanged style
    edit_target_lyrics=revised_lyrics,   # new words
    edit_n_min=0.6,   # higher = preserve more of the original
    edit_n_max=1.0,
    save_path='./out/edited.wav',
)

Keeping edit_n_min high preserves the melody, which is how you fix a bad line without losing the take.

Extend and audio-to-audio

Extend adds music before or after existing audio — the way to build a long track in coherent sections rather than one long generation. Audio-to-audio conditions generation on a reference recording:

pipeline(
    task='extend',
    src_audio_path='./out/song.wav',
    prompt=prompt,
    lyrics=lyrics,
    audio_duration=180.0,
    save_path='./out/extended.wav',
)

pipeline(
    audio2audio_enable=True,
    ref_audio_input='./reference_track.wav',
    ref_audio_strength=0.5,   # 0 = follow prompt, 1 = follow reference
    prompt=prompt,
    lyrics=lyrics,
    save_path='./out/a2a.wav',
)

ref_audio_strength runs 0 to 1: low follows the prompt, high follows the reference.

LoRA fine-tuning

ACE-Step ships training code, and LoRA adapters specialise the model without retraining 3.5B parameters. The project has published several:

pipeline(
    prompt='hip hop, boom bap, vinyl drums, 90 bpm, rap vocal',
    lyrics=lyrics,
    lora_name_or_path='ACE-Step/ACE-Step-v1-chinese-rap-LoRA',  # RapMachine
    lora_weight=1.0,
    save_path='./out/rap.wav',
)

lora_weight scales the adapter's influence — 1.0 is full strength, 0.5 blends it with base behaviour. Passing a Hugging Face repo id downloads it automatically; a local path works too. For training your own on a personal library, see TRAIN_INSTRUCTION.md in the repository.

Batch generation

styles = [
    'indie rock, jangly guitars, 120 bpm, female vocal',
    'synthwave, analog pads, gated reverb drums, 110 bpm, male vocal',
    'bossa nova, nylon guitar, brushed drums, 88 bpm, soft female vocal',
]

for i, style in enumerate(styles):
    pipeline(
        prompt=style,
        lyrics=lyrics,
        audio_duration=90.0,
        infer_step=60,
        manual_seeds=[i],
        batch_size=2,             # two candidates per style
        save_path=f'./out/style_{i}.wav',
    )

Troubleshooting

SymptomCause and fix
CUDA out of memoryAdd --cpu_offload true --overlapped_decode true, then shorten audio_duration, then drop batch_size to 1
Vocals mumbled or words wrongRaise guidance_scale_lyric. Check the lyrics have real line breaks and structure tags
Ignores the genre tagsRaise guidance_scale_text, and use comma-separated tags rather than a sentence
No song structureMissing [verse] / [chorus] tags in the lyrics field
dtype errors on macOS--bf16 false, and don't use --torch_compile
torch_compile fails on Windowspip install triton-windows, or drop the flag
First run very slowDownloading several GB of weights, and compiling if --torch_compile is on. Second run is representative
Output degrades late in long tracksGenerate in sections and use extend rather than one long generation

Licensing and the ethical bit

ACE-Step is Apache-2.0 — code and weights — which is as permissive as this field gets, and the main reason to build a product on it rather than on MusicGen.

Permissive licence, real obligations. Apache-2.0 says nothing about whether a given output is safe to release. The project's own disclaimer flags the risk: a model that produces work stylistically close to existing artists can create copyright exposure regardless of how the weights are licensed. Prompting for a named artist's style and publishing the result is a problem the licence does not solve. Disclose AI-generated tracks — several platforms now require it, and listeners increasingly expect it.

Where it fits

ACE-Step is the open model to reach for when you need songs — structure, vocals, minutes rather than seconds — and when licensing has to be clean. It is also the one that runs acceptably on a Mac, and the only one with a genuine editing workflow.

It is not the best-sounding music model available; Suno and Udio remain ahead on raw audio quality, and MusicGen is arguably still better at pure instrumental texture. What ACE-Step gives you is speed, control, editing and a licence you can build on. See how it compares with YuE, the other open lyrics-to-song model.

Generate music with MusicGenInstrumental generation with melody conditioning.Run Stable Audio Open locallyStereo 44.1 kHz sound design and loops.YuE vs ACE-StepThe two open lyrics-to-song models, compared.

← AI music generation hub