๐ฆ Tiled VAE Decode - Yaser
Decode a 4K latent on an 8GB card without OOMing โ the VAE hack that still works
- samples
- vae
- IMAGE
Here's the scene: you've upscaled or tiled-sampled a latent to something enormous - 4K, 8K, bigger - and then the VAE decode blows up your GPU. The VAE is the piece that turns a latent back into a visible image (see the KB's concepts doc for why that's a separate, memory-hungry component), and it's famously greedy. Tiled VAE Decode - Yaser exists for exactly this: it decodes a giant latent in chunks so you can get the image out on a card that otherwise couldn't touch it. The original version of this code claimed ~10GB for 8K images, and the approach has been saving people's runs for years - "tiled vae" shows up in hundreds of threads across the community.
It's a port of the tiled VAE from LI YI's famous multidiffusion upscaler (the A1111 extension whose header comment literally calls itself "a wild hack"). The _for_testing category is not a lie: this is a hack, but it's a good hack.
How it works
The idea is almost comically straightforward: split the latent into tiles, decode each tile separately, and stitch the results back. The subtlety is that a VAE's GroupNorm layers compute statistics over the whole image, so you can't just decode tiles in isolation or the seams and tone will be wrong. The code handles that by hijacking the decoder's forward pass with a VAEHook and doing one of two things:
- Fast mode (default,
fast = true): downsample the whole image, run it through the VAE once to capture the GroupNorm mean/var, then apply those stats to every tile. No RAMโVRAM shuffling, minimal overhead. This is the one you'll use. - Slow mode: decompose the decoder into a task queue, process tiles one at a time, suspend at each GroupNorm, accumulate stats in RAM, then apply. More faithful, much slower, and the code even runs tiles in zigzag order to cut data transfer.
Tiles are padded (11 pixels in the decoder, 32 in the encoder) so seams don't show, and the merged output is seamless - no post-processing.
The inputs you'll set
- samples - the
LATENTyou want decoded. vae - yourVAE. - tile_size - 384 to 4096, step 16, default 512. Lower it if you OOM; raise it if you want speed and have headroom. On 8GB, 512 is a safe start; 1024 often works if the rest of your graph is quiet.
- fast - leave it on. It's the entire reason the node is practical.
Output: IMAGE, wired to a preview or save node like any other decode.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/YaserJaradeh/comfyui-yaser-nodes.git
restart, or ComfyUI Manager โ "Yaser-nodes". No models - it works with the VAE you already have.
The gotchas (real ones, from the source itself)
- fp16/half VAE + 8K = NaNs. The header comment says it outright: NaN artifacts appear for giant images when the VAE runs at half precision. Fix: launch ComfyUI with
--no-half-vae. If your decode comes out as grey/black noise at extreme sizes, this is why. - No gradients through the VAE. The hook breaks
backward()/autograd paths through the VAE, so you can't train with it - fine for generation, wrong for training data pipelines. - ComfyUI now ships its own tiled VAE nodes. Core
VAEDecodeTiledexists and is well maintained. This one's edge is thefastpath and the family connection to the tiled-diffusion nodes in this same pack. If you just want "decode huge image without OOM," core's is the safer default - but if you're already in this pack and the core version gives you trouble, this is a solid Plan B.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | โ | |
| vae | VAE | โ | |
| tile_size | INT | 512384โ4096 | โ |
| fast | BOOLEAN | true | โ |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | โ |