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-Step | MusicGen | Stable Audio Open | |
|---|---|---|---|
| Licence | Apache-2.0 | CC-BY-NC (non-commercial) | Stability Community License |
| Vocals | Yes, with your lyrics | No | No |
| Typical length | Minutes | 30 s window, stitched beyond | 47 s maximum |
| Speed | Very fast (diffusion, ~34× real time on a 4090) | Slow (autoregressive) | Moderate |
| Editing | Retake, repaint, extend, lyric edit | Continuation only | Audio-to-audio |
| Languages | 19, with 10 performing well | English prompts | English 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.
| Device | RTF @ 27 steps | 1 min of audio | RTF @ 60 steps | 1 min of audio |
|---|---|---|---|---|
| RTX 4090 | 34.48× | 1.74 s | 15.63× | 3.84 s |
| A100 | 27.27× | 2.20 s | 12.27× | 4.89 s |
| RTX 3090 | 12.76× | 4.70 s | 6.48× | 9.26 s |
| MacBook M2 Max | 2.27× | 26.43 s | 1.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 .
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 78658
| Flag | Default | What it does |
|---|---|---|
| --checkpoint_path | auto | Where weights live; auto-downloads to the cache if unset |
| --port | 7865 | Gradio port |
| --server_name | 127.0.0.1 | Set to 0.0.0.0 to reach it from another machine on your network |
| --device_id | 0 | Which GPU |
| --bf16 | true | bfloat16 precision; set false on macOS |
| --torch_compile | false | Compiles the model — slow first run, faster after. Windows needs triton-windows |
| --cpu_offload | false | Keeps only the active stage on the GPU. The big VRAM saver |
| --overlapped_decode | false | Sliding-window decode; faster, and reduces peak memory |
| --share | false | Public Gradio link |
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
- [verse], [chorus] and [bridge] are the tags that carry real weight — the model changes its melodic and dynamic behaviour at each.
- Use [inst] or leave the lyrics empty for an instrumental.
- Line breaks matter. They map to phrasing, and lyrics written as a single paragraph get sung as one long run-on.
- Repeating your chorus verbatim gets it sung recognisably the same way, which is what makes the track feel structured.
- 19 languages are supported, with the top ten — English, Chinese, Russian, Spanish, Japanese, German, French, Portuguese, Italian, Korean — performing noticeably better than the rest.
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.
| Parameter | Default | What it does |
|---|---|---|
| audio_duration | 60.0 | Seconds. Unlike MusicGen there's no hard 30 s window — ask for 180 and you get a composed three-minute track |
| infer_step | 60 | Diffusion steps. 27 is the documented fast preset, 60 the quality default. Past 100, returns diminish |
| guidance_scale | 15.0 | Overall 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_scale | 10.0 | Granularity of the guidance schedule |
| guidance_interval | 0.5 | Fraction of the denoising trajectory over which guidance is applied. Lower gives the model more freedom late in the process |
| guidance_interval_decay | 0.0 | Decays guidance across that interval; raise to loosen adherence as generation settles |
| min_guidance_scale | 3.0 | Floor that decay falls to |
| guidance_scale_text | 0.0 | Separate guidance for the style prompt. Raise to push style over lyric fidelity |
| guidance_scale_lyric | 0.0 | Separate guidance for lyrics. Raise when words come out slurred or wrong |
| use_erg_tag / use_erg_lyric / use_erg_diffusion | True | Enhanced rescaled guidance on tags, lyrics and diffusion. Leave enabled unless debugging |
| manual_seeds | None | List of seeds for reproducibility |
| batch_size | 1 | Candidates 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:
- RapMachine (ACE-Step/ACE-Step-v1-chinese-rap-LoRA) — fine-tuned on Chinese rap. It transfers to rap delivery generally, but it is strongest on the material it was trained on.
- Lyric2Vocal — trained on isolated vocals, so it generates a vocal take alone rather than a full arrangement. Useful if you want to sit an AI vocal on top of a production you made yourself.
- Text2Samples — tuned for short one-shots and samples rather than songs.
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
| Symptom | Cause and fix |
|---|---|
| CUDA out of memory | Add --cpu_offload true --overlapped_decode true, then shorten audio_duration, then drop batch_size to 1 |
| Vocals mumbled or words wrong | Raise guidance_scale_lyric. Check the lyrics have real line breaks and structure tags |
| Ignores the genre tags | Raise guidance_scale_text, and use comma-separated tags rather than a sentence |
| No song structure | Missing [verse] / [chorus] tags in the lyrics field |
| dtype errors on macOS | --bf16 false, and don't use --torch_compile |
| torch_compile fails on Windows | pip install triton-windows, or drop the flag |
| First run very slow | Downloading several GB of weights, and compiling if --torch_compile is on. Second run is representative |
| Output degrades late in long tracks | Generate 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.
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.
How this model’s licence compares with every other open model → · GPU & VRAM requirements →