acestep.cpp

repository·master·Indexed 18 days ago

https://github.com/serveurpersocom/acestep.cpp

A local AI music generation server using GGML to generate stereo 48kHz audio from text descriptions. It features a browser-based UI and supports CUDA, Metal, and Vulkan backends. The system utilizes a pipeline of four GGUF model types: an LM for lyrics and audio codes, a Text encoder for captions, a DiT for audio code rendering, and a VAE for final audio decoding. It supports PEFT, ComfyUI, and LyCORIS adapter formats and provides a REST API for generation and audio processing.

Tokens
10.8K
Snippets
27
Records
45
Agent score
63%

What's inside acestep.cpp

  1. Understand the VRAM policy and ModelStore

    master

    The project manages GPU memory through a ModelStore using two distinct modes controlled by a single flag. This determines how modules (LM, DiT, VAE, etc.) are loaded and evicted from VRAM.

    VRAM Modes

    • Default Mode (Optimizes VRAM): Uses a STRICT eviction policy. At most one GPU module is resident at a time. When a new module is requested, the previous one is evicted. This allows the full stack to run on consumer-grade hardware by swapping weights (e.g., DiT loads, then evicts; VAE loads, then evicts).
    • --keep-loaded Mode (Optimizes Latency): Uses a NEVER eviction policy. Everything stays resident in VRAM across requests. This is intended for workstations with high VRAM capacity to eliminate reload overhead.

    ModelStore Mechanics

    • Module Keys: Modules are keyed to prevent redundant loading.
      • LM: Keyed by (path, max_seq, n_kv_sets). This ensures ace-lm and ace-understand share the same single LM instance.
      • DiT: Keyed by (path, adapter_path, adapter_scale).
      • Others: Keyed by (path).
    • RAII Management: The system uses ModelHandle (an RAII handle) to ensure that when a pipeline finishes using a module, it is correctly released back to the store, triggering the appropriate eviction policy.
  2. Understand Generation Modes in acestep.cpp

    master

    The generation process depends on the content of your input JSON. The LLM fills missing fields and generates audio codes, while existing fields are treated as fixed. All modes output numbered files (request0.json .. requestN-1.json) and never modify the original input JSON.

    Core Generation Modes

    • Caption only (lyrics=""): Performs two LLM passes. Phase 1 expands the caption into enriched metadata (bpm, keyscale, etc.) via Chain of Thought (CoT). Phase 2 generates audio codes. CFG is forced to 1.0 in Phase 1.
    • Caption + lyrics (+ optional metadata): A single LLM pass. Missing metadata is filled via CoT, and the caption is enriched. User-provided metadata is preserved.
    • Everything provided: If caption, lyrics, bpm, duration, keyscale, and timesignature are all present, the LLM skips CoT and generates audio codes directly.
    • Instrumental (lyrics="[Instrumental]"): Uses the single-pass path. The DiT is specifically trained to handle this string as a no-vocal condition.
    • Passthrough (audio_codes present): The LLM is skipped entirely. Use ace-synth to decode existing codes.

    Audio Transformation Modes

    • Cover ("task_type": "cover" + --src-audio): Creates a free reinterpretation. It uses an FSQ roundtrip (5:1 temporal compression) which destroys micro-timings and transients, causing the DiT to diverge from the source. Control divergence with audio_cover_strength.
    • Cover-nofsq ("task_type": "cover-nofsq" + --src-audio): Creates a faithful remix. It skips the FSQ roundtrip, providing clean VAE latents to the DiT. For best results, pass --ref-audio pointing to the same file as --src-audio.
    • Repaint ("task_type": "repaint" + --src-audio): Regenerates a specific time region. Use repainting_start and repainting_end (in seconds).
      • Inpainting: repainting_start and repainting_end are within the source duration.
      • Outpainting: Use negative values for repainting_start to generate audio before the source, or an end value beyond the source duration to generate after.
    • Lego ("task_type": "lego" + --src-audio): Layers a new instrument track over an existing backing track. Requires acestep-v15-base DiT (Turbo and SFT are not supported). Requires a track field in the JSON.

    Track Names for Lego, Extract, and Complete

    vocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds.

  3. Understand VRAM management and ModelStore

    master

    The server manages GPU memory via a ModelStore.

    Memory Modes:

    • STRICT (Default): Only one module is kept resident in VRAM at a time. This minimizes 'Peak' VRAM usage but increases latency due to reloading modules.
    • --keep-loaded: Keeps the entire working set resident in VRAM. This requires more 'Working set' VRAM but significantly reduces latency for subsequent requests.

    VRAM Estimates (Q8 1.7B LM / 2B DiT):

    • LM: ~2-3 GB.
    • Synth: ~2-3 GB (Peak) / ~3-4 GB + tiles (Working set).
    • Understand: ~2-3 GB (Peak) / ~2-3 GB + tiles (Working set).

    Note: VAE tile activations scale with --vae-chunk and --vae-overlap. Larger tiles increase speed but also transient VRAM usage.

  4. Reference: ace-lm two-phase pipeline

    master

    The ace-lm is a specialized autoregressive pipeline for music generation, not a general chat engine.

    Phase 1: CoT (Chain of Thought)

    Generates structured metadata: bpm, keyscale, timesignature, caption, duration, and language. It uses a Finite State Machine (FSM) built from a prefix tree to enforce valid field names and values during decoding.

    Phase 2: Audio Codes

    Generates 5Hz FSQ (Finite Scalar Quantization) tokens. The FSQ codec uses levels [8,8,8,5,5,5] to produce 64,000 distinct codes. The tokenizer reserves 65,535 slots (audio_code_0 to audio_code_65534) in the Qwen3 vocabulary.

  5. Supported adapter formats for ACE-Step

    master

    The ACE-Step server supports three different trainer formats for adapters. The server automatically detects the format by inspecting the safetensors payload.

    Supported formats include:

    • PEFT: Provided as a folder. It is identified by the presence of lora_alpha in the adapter_config.json file.
    • ComfyUI: Provided as a single .safetensors file. It is identified by a per-tensor .alpha scalar.
    • LyCORIS: Provided as a single .safetensors file. It is identified by a per-module .alpha scalar. LyCORIS LoKr supports both factorized weights (lokr_w2_a + lokr_w2_b) and monolithic weights (lokr_w2), with optional DoRA support via the dora_scale parameter.
    | Trainer | Layout                | Alpha source                          | Example                                |
    |---------|-----------------------|---------------------------------------|----------------------------------------|
    | PEFT    | folder                | `lora_alpha` in `adapter_config.json` | `ACE-Step-v1.5-chinese-new-year-LoRA/` |
    | ComfyUI | single `.safetensors` | per tensor `.alpha` scalar            | `turbo_v9_1850_comfyui.safetensors`    |
    | LyCORIS | single `.safetensors` | per module `.alpha` scalar            | `acestep-qinglong-lokr.safetensors`    |
  6. Configure text conditioning and vocals

    master

    Control how the model interprets your prompt and handles vocals using caption and lyrics:

    • caption (string, required): A natural language description of style, mood, and instruments. This is fed to both the LLM and the DiT text encoder.
    • lyrics (string): The single source of truth for vocal content. Use one of these three states:
      • "" (empty): The LLM generates lyrics based on the caption.
      • "[Instrumental]": No vocals. The LLM skips lyrics generation and the DiT receives this instruction.
      • "Any other string": Use your own lyrics. The LLM will only fill in missing metadata.

    Metadata (Auto-filled by LLM if unset):

    • bpm: Beats per minute (defaults to 0 for auto-generation).
    • duration: Target length in seconds. 0 lets the LLM decide (constrained to [10, 600]s).
    • keyscale: Musical key/scale (e.g., "C major").
    • timesignature: Numerator as a string (e.g., "4" for 4/4).
    • vocal_language: BCP-47 code (e.g., "en"). If "", the LLM detects it via CoT. If "unknown", it signals the DiT to expect no specific language.
  7. How the ACE-Step pipeline components work together

    master

    The project consists of three primary functional blocks that form a generative loop:

    1. ace-lm (Generation): A two-phase autoregressive pipeline using Qwen3.
      • Phase 1: Generates structured metadata (BPM, keyscale, lyrics, etc.) using Chain-of-Thought (CoT) and FSM constraints.
      • Phase 2: Generates 5Hz FSQ audio codes.
    2. ace-synth (Synthesis): Converts audio codes into playable audio.
      • Uses BPE tokenization, Qwen3-Embedding, and a DiT (Diffusion Transformer) with flow matching to transform FSQ codes into VAE latents, which are then decoded into 48kHz stereo WAV.
    3. ace-understand (Analysis): The reverse pipeline.
      • Takes audio, encodes it via VAE, tokenizes it via FSQ, and uses an LM to produce a JSON summary containing caption, lyrics, BPM, key, duration, and language.
  8. Use ace-server as an asynchronous API

    master

    The ace-server provides an HTTP interface for ace-lm, ace-synth, ace-understand, and ace-vae pipelines.

    Workflow:

    1. Submit Job: Send a POST request to an endpoint (e.g., /lm, /synth). The server returns a job id immediately.
    2. Poll Status: Use GET /job?id=N to check if the status is running, done, failed, or cancelled.
    3. Fetch Result: Once status is done, use GET /job?id=N&result=1 to retrieve the data.
    4. Cancel: Use POST /job?id=N&cancel=1 to stop a running job.

    Concurrency Model: All requests are pushed to a single FIFO queue processed by one worker thread. This ensures serial execution without GPU mutex contention. Completed jobs are cached in memory (up to 32 entries) before being evicted FIFO.

    # Example: Start server with custom port and batch limit
    ./ace-server --models /path/to/models --host 0.0.0.0 --port 8085 --max-batch 2
  9. CLI and API usage for advanced tasks

    master

    While ace-synth and ace-lm expose cover and repaint via dedicated --src-audio flags, other advanced modes like lego, extract, and complete do not have dedicated CLI flags.

    To use these modes via the CLI, you must:

    1. Pass the --src-audio flag.
    2. Set the task_type field directly inside your JSON request file.
    3. Ensure you are using a Base or SFT model (Turbo models do not support these tasks).
  10. Generate music using ace-lm and ace-synth

    master

    Music generation is a two-step process involving ace-lm (which generates lyrics and audio codes) and ace-synth (which synthesizes the audio).

    Step 1: Generate Metadata and Codes with ace-lm

    Input a JSON request file. The output is a new JSON file (e.g., request0.json) enriched with metadata, lyrics, and codes.

    ./ace-lm --models models --request /tmp/request.json

    Step 2: Synthesize Audio with ace-synth

    Input the enriched JSON file from the previous step to produce the audio file (e.g., request00.mp3).

    ./ace-synth --models models --request /tmp/request0.json

    Advanced Usage

    • Using Adapters (LoRA/PEFT): Set the adapter and adapter_scale in your input JSON, then point the CLI to the directory containing the adapter using --adapters.
    • Batch Generation: Set lm_batch_size in the input JSON. ace-lm will generate multiple request files (e.g., request0.json, request1.json), and ace-synth can process them all in a single GPU batch by passing them as multiple arguments.
    • Audio Covers: To transform an existing song, use the --src-audio flag with ace-synth and set task_type to "cover" in your JSON.
    # 1. Generate metadata
    ./ace-lm --models models --request /tmp/request.json
    
    # 2. Synthesize audio
    ./ace-synth --models models --request /tmp/request0.json
  11. Download and prepare required models

    master

    To run acestep.cpp, you must place specific GGUF model files in the models/ directory. The system requires four distinct types of models to function: an LM for generation, a Text encoder for caption processing, a DiT for audio code rendering, and a VAE for final audio decoding.

    You can download these manually from Hugging Face or use the provided automation script.

    ./models.sh