# Architecture > Full technical reference for acestep.cpp. For a quick start guide, see [README.md](../README.md). # acestep.cpp Portable C++17 implementation of ACE-Step 1.5 music generation using GGML. Text + lyrics in, stereo 48kHz MP3 or WAV out. Runs on CPU, CUDA, ROCm, Metal, Vulkan. ## Build ```bash git submodule update --init mkdir build && cd build # macOS (Metal + Accelerate BLAS auto-enabled) cmake .. # Linux with NVIDIA GPU cmake .. -DGGML_CUDA=ON # Linux with AMD GPU (ROCm) cmake .. -DGGML_HIP=ON # Linux with Vulkan cmake .. -DGGML_VULKAN=ON cmake --build . --config Release -j$(nproc) ``` ### Windows Install [Visual C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) (select "Desktop development with C++" workload) and optionally the [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) and/or the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home). ```cmd git submodule update --init call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat" mkdir build cd build rem NVIDIA GPU cmake .. -DGGML_CUDA=ON rem AMD/Intel GPU (Vulkan) cmake .. -DGGML_VULKAN=ON rem all backends (CUDA + Vulkan + CPU, runtime loading) cmake .. -DGGML_CPU_ALL_VARIANTS=ON -DGGML_CUDA=ON -DGGML_VULKAN=ON -DGGML_BACKEND_DL=ON cmake --build . --config Release -j %NUMBER_OF_PROCESSORS% ``` Builds seven binaries: `ace-lm` (LLM), `ace-synth` (DiT + VAE), `ace-server` (HTTP server), `ace-understand` (reverse: audio -> metadata), `neural-codec` (VAE encode/decode), `mp3-codec` (MP3 encoder/decoder) and `quantize` (GGUF requantizer). ## Models Pre-quantized GGUFs on [Hugging Face](https://huggingface.co/Serveurperso/ACE-Step-1.5-GGUF). ```bash pip install hf ./models.sh # Q8_0 turbo essentials (~7.7 GB) ./models.sh --all # every model, every quant (~97 GB) ./models.sh --quant Q6_K # pick a specific quant (Q4_K_M, Q5_K_M, Q6_K, Q8_0, BF16) ./models.sh --sft # add SFT DiT variant ./models.sh --shifts # add shift1/shift3/continuous variants ``` Default downloads 4 files into `models/`: | GGUF | Arch | Size | |------|------|------| | Qwen3-Embedding-0.6B-Q8_0.gguf | text encoder (28L, H=1024) | 748 MB | | acestep-5Hz-lm-4B-Q8_0.gguf | Qwen3 causal LM | 4.2 GB | | acestep-v15-turbo-Q8_0.gguf | DiT 2B + CondEncoder (24L, H=2048) | 2.4 GB | | vae-BF16.gguf | AutoencoderOobleck | 322 MB | Three LM sizes: 0.6B (fast), 1.7B, 4B (best quality). Six DiT variants: turbo, sft, base, turbo-shift1, turbo-shift3, turbo-continuous. XL (4B DiT) variants: xl-turbo, xl-sft, xl-base (32L, H=2560, higher quality, ~9.5 GB BF16). VAE is always BF16 (small, bandwidth-bound, quality-critical).
Building GGUFs from source (checkpoints + convert) If you want to convert from the original safetensors yourself: ```bash pip install gguf hf ./checkpoints.sh # download raw HF checkpoints (turbo + 4B LM) ./checkpoints.sh --all # all variants (SFT, shift1/3, 0.6B/1.7B LM) python3 convert.py # convert all checkpoints to GGUF (models/) ./quantize.sh # quantize BF16 -> Q4_K_M/Q5_K_M/Q6_K/Q8_0 ``` `checkpoints.sh` downloads safetensors, config.json, and tokenizer files into `checkpoints/`. `convert.py` packs everything into self-contained GGUF files in `models/`, bundling BPE tokenizer, silence_latent, and config metadata so no external file is needed at runtime.
## CLI `ace-lm` generates lyrics and audio codes, `ace-synth` synthesizes audio. The input JSON is never modified. Output is always numbered: `request0.json`. ```bash cat > /tmp/request.json << 'EOF' { "caption": "Upbeat pop rock with driving guitars and catchy hooks", "inference_steps": 8, "shift": 3.0, "vocal_language": "fr" } EOF # LLM: request.json -> request0.json (enriched with metadata + lyrics + codes) ./ace-lm \ --request /tmp/request.json \ --lm models/acestep-5Hz-lm-4B-Q8_0.gguf # DiT+VAE: request0.json -> request00.mp3 ./ace-synth \ --request /tmp/request0.json \ --embedding models/Qwen3-Embedding-0.6B-Q8_0.gguf \ --dit models/acestep-v15-turbo-Q8_0.gguf \ --vae models/vae-BF16.gguf ``` With an adapter (LoRA today, PEFT directory or ComfyUI single file): ```bash # PEFT directory (contains adapter_model.safetensors + adapter_config.json) ./ace-synth \ --request /tmp/request0.json \ --embedding models/Qwen3-Embedding-0.6B-Q8_0.gguf \ --dit models/acestep-v15-turbo-Q8_0.gguf \ --vae models/vae-BF16.gguf \ --adapter /path/to/peft-adapter # ComfyUI single .safetensors file (alpha baked in, no config needed) ./ace-synth \ --request /tmp/request0.json \ --embedding models/Qwen3-Embedding-0.6B-Q8_0.gguf \ --dit models/acestep-v15-turbo-Q8_0.gguf \ --vae models/vae-BF16.gguf \ --adapter best_sft_v2_2338_comfyui.safetensors ``` Generate multiple songs at once with `lm_batch_size` in the JSON: ```bash # 2 different songs from one prompt (different lyrics, codes, metadata) cat > /tmp/request.json << 'EOF' { "caption": "Upbeat pop rock anthem with driving guitars and catchy hooks", "vocal_language": "fr", "lm_batch_size": 2 } EOF # LM: request.json (lm_batch_size=2) -> request0.json, request1.json ./ace-lm \ --request /tmp/request.json \ --lm models/acestep-5Hz-lm-4B-Q8_0.gguf # DiT+VAE: both requests in one GPU batch -> request00.mp3, request10.mp3 ./ace-synth \ --request /tmp/request0.json /tmp/request1.json \ --embedding models/Qwen3-Embedding-0.6B-Q8_0.gguf \ --dit models/acestep-v15-turbo-Q8_0.gguf \ --vae models/vae-BF16.gguf ``` `lm_batch_size` controls how many songs the LM generates. User-provided fields are preserved in all outputs. Empty fields are filled independently per batch item, producing genuinely different songs. ace-synth takes all request files as CLI arguments and runs them in a single GPU batch. Transform an existing song with `--src-audio` (no LLM needed): ```bash cat > /tmp/cover.json << 'EOF' { "task_type": "cover", "caption": "Jazz piano cover with brushed drums and walking bass", "lyrics": "[Instrumental]" } EOF ./ace-synth \ --src-audio song.wav \ --request /tmp/cover.json \ --embedding models/Qwen3-Embedding-0.6B-Q8_0.gguf \ --dit models/acestep-v15-turbo-Q8_0.gguf \ --vae models/vae-BF16.gguf \ ``` Ready-made examples in `examples/`: ```bash cd examples ./simple.sh # caption only, LLM fills everything ./simple-batch.sh # 2 songs from one prompt (lm_batch_size=2) ./partial.sh # caption + lyrics + duration ./full.sh # all metadata provided ./dit-only.sh # skip LLM, DiT from noise ./server-turbo.sh # start HTTP server (turbo model) ./server-sft.sh # start HTTP server (SFT model) ./client.sh # test server (single song) ./client-batch.py # test server batch (2 songs) ./client-understand.sh