Distributed VAE (Ray)
The last node in every Raylight graph
- ray_actors
- samples
- IMAGE
Every Raylight workflow ends here. Distributed VAE (Ray) is the node that turns the latent tensor your Ray samplers produced back into an actual image, and it does it by spreading the decode work across all your GPUs. If you've copied a raylight example workflow and wondered why the "VAE Decode" node is this weird one with extra knobs - this is it, and it's not optional in the multi-GPU setup.
Raylight is Komikndr's multi-GPU pack for ComfyUI - the "two 5070s beat one 5090" philosophy. USP splits the sequence work, FSDP splits the weights, and the samplers leave you with a latent sitting in the workers. The vanilla ComfyUI VAE Decode can't see that; this node can, because it talks to the Ray workers directly.
How it works
The source is refreshingly honest about the trick: ComfyUI's VAE is already parallelized via tiling. What this node does is hand that tiling to the Ray workers - each worker decodes a slice of the spatial tiles on its own GPU, the partials get combined, and worker 0 finalizes the image and hands it back to the host. That's why it's a meaningful speedup on multi-GPU instead of just a different way to do the same work.
The knobs:
- tile_size (default 512) - spatial tile size in pixels. Larger tiles = fewer seams but more VRAM per worker. If you're tight on memory, drop it toward 256–384.
- overlap (default 64) - pixel overlap between tiles so you don't get visible seams. If you see tile artifacts, raise it before you blame anything else.
- temporal_size and temporal_overlap - here's the gotcha the tooltips flag: these are retained for workflow compatibility but ignored. Distributed video decoding always keeps the complete temporal sequence on one worker, so temporal tiling isn't used. Change them all you want; nothing happens.
The inputs
- ray_actors - from your sampler's
ray_actorsoutput (the samplers pass it through precisely so you can wire the decoder). - samples - the
LATENTfrom your Ray sampler. - vae_name - pick the VAE matching your model's latent format (16-channel for the Flux/Qwen/Wan family, 4-channel for SD/SDXL). Wrong channel count = noise or flat color.
Install
Same pack, same story:
cd ComfyUI/custom_nodes
git clone https://github.com/komikndr/raylight
cd raylight
<your_python> -m pip install -r requirements.txt
or find raylight in ComfyUI Manager. No extra dependencies beyond the pack's ray + xfuser set.
Common issues
The decode step needs at least one Ray worker, so if you killed the cluster (RayKill) and forgot to re-init, this node throws. The more subtle one: because the full temporal sequence stays on one worker, long videos can push that worker's VRAM hard even though the sampling was nicely spread - if you OOM at decode time on an 81-frame clip, drop tile_size rather than the frame count. And don't confuse this with Load VAE (Ray): that one only loads a VAE for the ControlNet path, this one actually produces the IMAGE you can preview and save.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| ray_actors | RAY_ACTORS | Ray Actor to submit the model into | |
| samples | LATENT | Latent samples to decode. | |
| vae_name | COMBO | Name of the VAE model to use for decoding. | |
| tile_size | INT | 51264–4096 | Tile size for spatial decoding. Larger tiles use more memory. |
| overlap | INT | 640–4096 | Pixel overlap between tiles to prevent artifacts. |
| temporal_size | INT | 648–4096 | Retained for workflow compatibility. Distributed video decoding always keeps the complete temporal sequence on one worker; this value is not used for tiling. |
| temporal_overlap | INT | 84–4096 | Retained for workflow compatibility. Distributed video decoding always keeps the complete temporal sequence on one worker; this value is not used for tiling. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |