Windows fatal access violation constructing LTX-2.5 VAE diffusion decoder after sampling — DiT not evicted before decode on 32GB GPU
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 158
Description
### Environment
- ComfyUI 0.33.0 (also reproduced on 0.32.0), frontend 1.49.6
- Windows, Python 3.13.12, RTX 5090 (32 GB, `cudaMallocAsync`), 64 GB system RAM
- Model: `ltx-2.5-22b-distilled-transformer-comfy-int8-convrot.safetensors` (UNETLoader)
+ `ltx-2.5-video-vae-bf16.safetensors` + `ltx-2.5-audio-vae-bf16.safetensors`
+ `gemma4-12b-with-proj-ltx-2.5-comfy-int8-convrot.safetensors` (CLIPLoader, type `ltxv`)
### Summary
Running an LTX-2.5 graph equivalent to the built-in `video_ltx2_5_t2v` / `_i2v` templates,
**sampling completes normally** (8/8 steps, ~3 it/s), then the whole process dies with a
Windows fatal access violation while the video VAE's diffusion decoder
(`comfy/ldm/lightricks/vae/na_diffusion_decoder.py`) is being constructed at decode time.
No Python exception is raised — the process just exits, so the queue and all state are lost.
```
100%|██████████| 8/8 [00:02<00:00, 2.96it/s]
Windows fatal exception: access violation
Stack (most recent call first):
File "...\.venv\Lib\site-packages\torch\nn\modules\linear.py", line 109 in __init__
File "...\ComfyUI\comfy\ldm\lightricks\vae\na_diffusion_decoder.py", line 180 in __init__
```
Relevant load lines from the same session:
```
[INFO] VAE load device: cuda:0, offload device: cpu, dtype: torch.float32
[INFO] Model LTXAVTEModel_ prepared for dynamic VRAM loading. 14612MB Staged.
[INFO] Model LTXAV prepared for dynamic VRAM loading. 20484MB Staged.
```
### Evidence that this is a memory-management interaction, not a decoder bug
Bisected on the same box, same weights, same seed:
| Test | Result |
|---|---|
| Full graph at 320×192×9 frames | ✅ succeeds |
| Full graph at 768×448×49 frames | 💥 access violation at decode |
| **Decode-only** (EmptyLTXVLatentVideo 768×448×49 → VAEDecodeTiled) on an otherwise empty GPU | ✅ succeeds in 3.5 s |
| Full graph at 768×448×49 **with KJNodes `VRAM_Debug` (unload_all_models + empty_cache) spliced between the sampler and the decode** | ✅ succeeds (22 s end-to-end) |
So the decoder itself is fine at full size; the crash only happens when the ~20 GB DiT is
still resident when `na_diffusion_decoder` is constructed/loaded. It looks like the new
dynamic VRAM loading does not evict the sampled DiT before the VAE's lazily-constructed
diffusion decoder allocates, and on Windows + `cudaMallocAsync` the failed allocation
surfaces as a native access violation that kills the process instead of a catchable OOM.
### Expected behavior
Either evict/offload the DiT before constructing the LTX-2.5 diffusion decoder (as the
pre-0.33 loader logic effectively did for other model families), or fail with a normal
`torch.cuda.OutOfMemoryError` so the queue survives.
### Repro
Built-in `video_ltx2_5_t2v` template, default settings (1280×704, 121 frames), on a 32 GB
card with the int8-convrot distilled transformer. Smaller renders (e.g. 320×192×9) do not
trigger it, which can make this look machine- or model-specific when it is size-dependent.
Happy to provide the exact API-format graph JSON or run further tests.
Contributor guide
Research direction
Start with `comfy/ldm/lightricks/vae/na_diffusion_decoder.py`, especially the decoder construction near line 180, and trace how model memory is managed between sampling and decode. Compare the full-graph failure with the successful decode-only run and the run with `unload_all_models` and `empty_cache` between sampling and decoding. Done means the large LTX-2.5 graph decodes without a process crash, or reports a catchable out-of-memory error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- backend, machine-learning
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100