ComfyUI SeedVR2 vae (tiled) decode has superlinear runtime
- Dominant language
- Python
- Stars
- 133k
- Forks
- 15.7k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 158
Description
# SeedVR2 tiled VAE decode scales superlinearly with video length
## Description
I run the default comfyUI workflow "SeedVR2 3B Int8 workflow : Upscale Video", what i observed is that the execution time is highly non linear with the input video length.
From what i understand is because SeedVR2's VAE decode keeps every temporal decode result alive until a complete spatial tile has been decoded, then accumulates that complete temporal tile into a full-video.
On my 12 GB RTX 4070 Ti this caused strongly superlinear runtime scaling without any change to the model or output resolution.
## Proposed fix
Keep the existing causal execution, but expose the temporal slices as an iterator and consume them immediately from the tiled decode path:
1. preserve one `memory_cache` for the full causal decode of each spatial tile;
2. keep the existing `INITIALIZING` -> `ACTIVE` sequence unchanged;
3. spatially weight each completed temporal slice immediately;
4. copy/accumulate that completed slice on ComfyUI's intermediate device;
5. release the large VAE-device output before decoding the next temporal slice.
The encoder path is intentionally unchanged.
This does not independently decode temporal chunks, add temporal overlap, or change the model math (in theory). It only changes output retention/accumulation.
## Reproduction / benchmark
Environment:
- ComfyUI 0.33.3
- Windows
- Python 3.13.12
- PyTorch 2.12.1+cu130
- RTX 4070 Ti 12 GB
- SeedVR2 3B INT8 ConvRot
- seedvr2_ema_vae_fp16.safetensors
- VAE Decode (Tiled): 512 tile size, 128 overlap, 64 temporal size, 8 temporal overlap
- Input : 976x544
- Output: 1952x1088
Observed before the change:
- ~4 s/16Fps input: ~198 s workflow time
- ~9 s/16Fps input: ~13 min workflow time
With this tentative prototype:
- 4 s/16Fps 6.40 GiB peak CUDA allocation, 200.99 s
- 9 s/16Fps input: , 6.44 GiB peak CUDA allocation, 440.18 s
The long/short workload ratio is ~2.31x by causal decode calls and ~2.19x by wall time, while peak CUDA allocation is effectively flat.
Visual side-by-side comparison showed no detectable output difference.
## Final toughts
I do not know if this the right place or way to post, this propose modification seems to work and for me it is very usefull so i think it can be useful for other people but the mechanism is extremely complex (for me at least) and i am not sure how much this implementation is "comformal" to comfyui standards.....
[vae.py](https://github.com/user-attachments/files/31301781/vae.py)
[seedvr2_streaming_tiled_decode.patch](https://github.com/user-attachments/files/31301787/seedvr2_streaming_tiled_decode.patch)
Contributor guide
Research direction
Start by comparing the attached vae.py and seedvr2_streaming_tiled_decode.patch with the VAE Decode (Tiled) path and SeedVR2 workflow described. Trace temporal slices, memory_cache, the INITIALIZING -> ACTIVE sequence, and intermediate-device accumulation; validate completion with the supplied short and long benchmarks, flat peak CUDA allocation, and unchanged visual output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- machine-learning, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100