mudler/LocalAI · error

[acestep-cpp] ERROR: T=%d exceeds max 15000\n

Error message

[acestep-cpp] ERROR: T=%d exceeds max 15000\n

What it means

acestep-cpp duration limit: latent frame count T = duration * 25 Hz, rounded up to a multiple of the DiT patch size, must not exceed 15000 (the silence_latent tensor length). Exceeding it returns 2 before tokenization. Since T is patch-aligned, the practical safe maximum duration is just under 15000/25 = 600 s, with a few frames of headroom lost to rounding.

Source

Thrown at backend/go/acestep-cpp/cpp/goacestepcpp.cpp:154

        snprintf(bpm_str, sizeof(bpm_str), "N/A");
    }

    int   num_steps      = 8;
    float guidance_scale = g_is_turbo ? 1.0f : 7.0f;
    float shift          = 1.0f;

    if (seed < 0) {
        std::random_device rd;
        seed = (int)(rd() & 0x7FFFFFFF);
    }

    // Compute T (latent frames at 25Hz)
    int T = (int)(duration * FRAMES_PER_SECOND);
    T     = ((T + g_dit.cfg.patch_size - 1) / g_dit.cfg.patch_size) * g_dit.cfg.patch_size;
    int S = T / g_dit.cfg.patch_size;

    if (T > 15000) {
        fprintf(stderr, "[acestep-cpp] ERROR: T=%d exceeds max 15000\n", T);
        return 2;
    }

    int Oc     = g_dit.cfg.out_channels;      // 64
    int ctx_ch = g_dit.cfg.in_channels - Oc;  // 128

    fprintf(stderr, "[acestep-cpp] T=%d, S=%d, duration=%.1fs, seed=%d\n", T, S, duration, seed);

    // 1. Load BPE tokenizer from text encoder GGUF
    BPETokenizer tok;
    if (!load_bpe_from_gguf(&tok, g_text_enc_path.c_str())) {
        fprintf(stderr, "[acestep-cpp] FATAL: failed to load BPE tokenizer\n");
        return 3;
    }

    // 2. Build formatted prompts (matches dit-vae.cpp text2music template)
    std::string instruction = "Fill the audio semantic mask based on the given conditions:";

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Lower duration to at most 590 s (safe margin under the 600 s / 15000-frame ceiling).
  2. For longer pieces, generate segments and concatenate in post-processing.
  3. Clamp/validate duration at the API boundary before calling generate_music.

Example fix

// before
generate_music(..., duration=700.0f, ...);   // T=17500 -> exceeds max 15000

// after
float d = duration > 590.0f ? 590.0f : duration;  // or split into segments
generate_music(..., duration=d, ...);
Defensive patterns

Strategy: validation

Validate before calling

// clamp to the patch-aligned ceiling before calling generate_music
const int FRAMES_PER_SECOND = 25;
int T = (int)(duration * FRAMES_PER_SECOND);
T = ((T + patch_size - 1) / patch_size) * patch_size;  // mirror backend rounding
if (T > 15000) duration = 590.0f;  // safe margin under 600s

Type guard

bool duration_supported(float duration, int patch_size) {
    int T = (int)(duration * 25);
    T = ((T + patch_size - 1) / patch_size) * patch_size;
    return T > 0 && T <= 15000;
}

Prevention

When it happens

Trigger: Calling generate_music(duration=600) or more (or a large duration after defaulting: duration<=0 becomes 30, but explicit big values pass through) where ceil-to-patch pushes T past 15000.

Common situations: Requesting 10+ minute tracks; UI sliders allowing beyond-limit values; duration taken from unvalidated user input; forgetting that patch rounding can push a borderline 599.9 s request over.

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/3aad73c72907961a. Report an issue: GitHub.