ROCMOptimizedVAEDecode
The ROCm VAE Decode that actually knows what GPU you're on
- samples
- vae
- IMAGE
The stock VAE Decode doesn't care what GPU you have. It decodes, and if your AMD card runs out of memory mid-way, you find out the hard way. This node is the answer to that: a drop-in replacement from the ROCm Ninodes pack that inspects your hardware - it detects your GPU family and the type of VAE you've connected - and picks tile sizes, precision, and batching for you. If you're on an AMD card with ROCm (the author's target is the gfx1151 / Strix Halo APU, but it covers RDNA 2/3 and CDNA too), it's the version of VAE decode you'd reach for first.
What it actually does differently
The magic is in detection, not exotic math. It figures out what VAE you're using - standard, WAN, LTX Video, or a pixel-space passthrough like z-image - and what architecture you're running, then applies defaults that match. LTX's VideoVAE has 128 latent channels and 32x spatial compression, and decoding it wrong is how you get OOM crashes and banding; WAN's causal VAE needs the full video in one pass or you get jitter at chunk boundaries. The node handles those cases instead of treating every latent like an SDXL image. It also defaults to fp16 on AMD, which halves memory for those big-channel VAEs.
The important knobs are the first two you'll ever touch:
- tile_size (default 768): how big each decode tile is. Bigger is faster but eats VRAM. 768 is conservative; 1024+ is the speed play if you have the memory.
- overlap (default 96): how much tiles overlap so seams don't show. Higher is smoother, more expensive.
Two more defaults worth knowing: use_rocm_optimizations is on (that's the point), and precision_mode defaults to "auto," which picks fp16 on AMD and fp32 elsewhere - you can force fp32/fp16/bf16 if you have a reason. The compatibility_mode toggle is the escape hatch: flip it and the node runs pure stock ComfyUI decode so you can prove a problem isn't the node's fault.
For long LTX/WAN videos there's enable_temporal_tiling (auto/enable/disable). "Auto" kicks in when the estimated output is huge; it decodes in overlapping temporal chunks with blending instead of one giant decode. Set temporal_chunk_size (16 latent frames ≈ 121 output frames for LTX) and temporal_overlap, and the frame count comes out exact - the changelog has literally been a series of fixes for seams and extra frames in this path, so this is the frontier of the pack's QA.
Output is a single IMAGE tensor, wired straight into Save Image, Preview, or video tools.
Install and the AMD reality check
Grab the whole pack once and you get every node here: in ComfyUI Manager search "ROCm Ninodes," or
cd ComfyUI/custom_nodes
git clone https://github.com/iGavroche/rocm-ninodes.git
Restart ComfyUI and you'll find it under ROCm Ninodes → VAE. Dependencies are light - numpy, Pillow, psutil, gguf, safetensors - and no model files ship with it. It expects you to already be running ROCm PyTorch; the README's Linux path for gfx1151 uses the ROCm nightly index:
uv pip uninstall torch torchaudio torchvision
uv pip install --index-url https://rocm.nightlies.amd.com/v2/gfx1151/ --pre torch torchaudio torchvision --upgrade
export TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL=1
That's the honest catch: this pack is only as good as your ROCm stack. On Windows, native ROCm is a rough ride (the changelog is full of "access violation" fixes for the ZLUDA path), and the README's advice - WSL2 or Linux - is worth taking. On a working AMD setup it's a straight swap: same LATENT and VAE inputs, same IMAGE output, no workflow surgery.
Where people get burned
OOM on a big video decode usually means temporal tiling is off or the tile size is too aggressive - drop tile_size to 768 and let temporal tiling do the work. Dark vertical bands or washed colors on LTX are a precision issue; force fp16/bf16 via precision_mode rather than leaving fp32. And if a new release behaves oddly after you update the pack, remember the v1.x→v2 migration script (uv run python tools/upgrade_to_v2.py) exists because the old package layout left stale files behind. One restart with a cleared cache fixes most post-update weirdness.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | The latent to be decoded. | |
| vae | VAE | The VAE model used for decoding the latent. | |
| tile_size | INT | 768256–2048 | Tile size. Larger values use more VRAM but are faster. |
| overlap | INT | 9632–512 | Overlap between tiles. Higher values reduce artifacts but use more VRAM. |
| use_rocm_optimizations | BOOLEAN | true | Enable ROCm-specific optimizations for AMD GPUs |
| precision_mode | COMBO | auto | Precision mode. 'auto' selects optimal for your GPU. |
| batch_optimization | BOOLEAN | true | Enable batch processing optimizations |
| compatibility_modeopt | BOOLEAN | false | Enable stock ComfyUI compatibility mode (disables all ROCm optimizations) |
| enable_temporal_tilingopt | COMBO | auto | For LTX/WAN videos: 'auto' enables temporal tiling for large outputs, 'enable' forces it on, 'disable' turns it off. |
| temporal_chunk_sizeopt | INT | 164–256 | Temporal tile size in LATENT frames. 16 latent = ~121 output frames for LTX. |
| temporal_overlapopt | INT | 21–8 | Overlap in LATENT frames between temporal tiles. Higher = smoother but more overhead. |
| last_frame_fixopt | BOOLEAN | false | Repeat last latent frame before decode, then discard extra output frames. Fixes end artifacts. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |