{"record":{"id":"aa5e77b0414b597d","repo":"mudler/LocalAI","slug":"acestep-cpp-error-vae-decode-failed-n","errorCode":null,"errorMessage":"[acestep-cpp] ERROR: VAE decode failed\\n","messagePattern":"\\[acestep-cpp\\] ERROR: VAE decode failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"backend/go/acestep-cpp/cpp/goacestepcpp.cpp","lineNumber":268,"sourceCode":"    std::vector<float> noise(Oc * T);\n    philox_randn((long long)seed, noise.data(), Oc * T, true);\n\n    // 10. DiT generate\n    std::vector<float> output(Oc * T);\n    fprintf(stderr, \"[acestep-cpp] DiT generate: T=%d, steps=%d, guidance=%.1f\\n\", T, num_steps, guidance_scale);\n\n    dit_ggml_generate(&g_dit, noise.data(), context.data(), enc_hidden.data(), enc_S,\n                      T, 1, num_steps, schedule.data(), output.data(), guidance_scale,\n                      nullptr, nullptr, -1);\n    fprintf(stderr, \"[acestep-cpp] DiT generation done\\n\");\n\n    // 11. VAE decode\n    int                T_audio_max = T * 1920;\n    std::vector<float> audio(2 * T_audio_max);\n\n    int T_audio = vae_ggml_decode_tiled(&g_vae, output.data(), T, audio.data(), T_audio_max, 256, 64);\n    if (T_audio < 0) {\n        fprintf(stderr, \"[acestep-cpp] ERROR: VAE decode failed\\n\");\n        return 6;\n    }\n    fprintf(stderr, \"[acestep-cpp] VAE decode done: %d samples (%.2fs @ 48kHz)\\n\", T_audio,\n            (float)T_audio / 48000.0f);\n\n    // 12. Peak normalization to -1.0 dB\n    {\n        float peak      = 0.0f;\n        int   n_samples = 2 * T_audio;\n        for (int i = 0; i < n_samples; i++) {\n            float a = audio[i] < 0 ? -audio[i] : audio[i];\n            if (a > peak) {\n                peak = a;\n            }\n        }\n        if (peak > 1e-6f) {\n            const float target_amp = powf(10.0f, -1.0f / 20.0f);\n            float       gain       = target_amp / peak;","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/go/acestep-cpp/cpp/goacestepcpp.cpp#L250-L286","documentation":"The final VAE decode stage failed: vae_ggml_decode_tiled() returned a negative sample count after the DiT diffusion run completed. Inputs to it are the DiT latent output (T frames), a stereo audio buffer sized 2*T*1920, and tile parameters 256/64. A negative return means the tiled decoder rejected the latent shape or the VAE (g_vae) was not in a state to decode. The shim aborts with exit code 6.","triggerScenarios":"Generating audio when the DiT produced a latent with unexpected T (e.g., T=0 or larger than the VAE's trained positional range), when g_vae was never loaded or was freed, when T_audio_max (T*1920) is smaller than what the tiled decode produces, or when the tile sizes 256/64 are incompatible with the VAE checkpoint.","commonSituations":"Requesting a duration that pushes T past the VAE's max latent frames; mismatched VAE checkpoint versus DiT checkpoint (different latent rate than 1920 samples/frame); memory exhaustion during tiled decode on CPU-only hosts.","solutions":["Check the preceding '[acestep-cpp] DiT generation done' line and the T value — clamp the requested duration so T stays within the VAE's supported range.","Verify the VAE model path matches the same ACEStep release as the DiT (latent rate must agree with the 1920 samples-per-frame sizing in this code).","Look at the ggml log lines immediately before the error for the specific tensor/shape failure inside vae_ggml_decode_tiled.","Reduce concurrency / free other backends if the tiled decode is failing from buffer allocation."],"exampleFix":"// before: duration longer than the VAE supports\nT = requested_seconds * 16; // arbitrary large T\n// after: clamp T to the VAE's supported latent-frame maximum\nif (T > T_MAX) { fprintf(stderr, \"clamping T %d -> %d\\n\", T, T_MAX); T = T_MAX; }","handlingStrategy":"validation","validationCode":"// clamp requested duration so T stays within the VAE's latent-frame budget\nconst maxT = 2048 // VAE-specific limit\nif t := secondsToLatentFrames(req.Duration); t > maxT {\n    req.Duration = latentFramesToSeconds(maxT)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match VAE and DiT checkpoints from the same release so the 1920 samples/frame assumption holds.","Clamp generation duration to the model's trained maximum.","Free other resident backends before long generations on memory-constrained hosts."],"tags":["acestep-cpp","vae","decode","audio","shape-mismatch"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}