HALO VAE Decode (FP32)
Black images on AMD? This VAE Decode forces FP32 and tells you why
- samples
- vae
- IMAGE
This is the node the pack is named for, and it's the one you actually reach for. If you're on an AMD ROCm card and your images keep coming out black with a RuntimeWarning: invalid value encountered in cast in the log, swap your normal VAE Decode for this one. It forces the whole decode into FP32 and shouts what happened into the terminal along the way.
The backstory matters. The VAE is the codec that turns the latent (the compressed representation the diffusion model works in) back into pixels - without it there's no viewable image at all. On some hardware, especially the AMD Strix Halo APUs with unified memory this pack was built on, the VAE runs in bf16, and when a bf16 tensor gets converted to numpy for image output the cast silently fails. The README calls numpy's lack of native bfloat16 support "the elephant in the room," and it's a real, recurring complaint in the community - you don't have to own a Strix Halo to hit it.
How it works
Normal VAE Decode trusts ComfyUI's dtype handling. This one doesn't. Looking at the source, the node:
- Logs the incoming latent's dtype, shape, min, and max - and warns if it's a "dead" (all-zero) latent.
- Saves the VAE's current dtype, then casts the entire
first_stage_modelto FP32. - Converts the latent to FP32, decodes it under
torch.no_grad(), and pushes the result through the VAE's normal output processing. - Restores the original dtype in a
finallyblock, so your VAE is left exactly as it was. - Prints a final verdict: NaN, black, or
✓ Output looks valid!.
There's also a nicety for video latents - if the VAE is a 2D video VAE and the latent is 5-dimensional, it slices to the first frame before decoding.
Inputs and outputs
- samples (
LATENT, required) - from your sampler. - vae (
VAE, required) - from your VAE loader. - Output:
IMAGE, ready for a Save Image / Preview node.
It's a drop-in replacement for the stock VAE Decode. Same two inputs, same one output, same wiring.
Installation
Part of the HALO Debug Pack. ComfyUI Manager → search "HALO Debug Pack", or:
cd ComfyUI/custom_nodes
git clone https://github.com/bkpaine1/halo_pack
Restart ComfyUI and it appears under the HALO category. No model downloads, no requirements.txt - the pack is a single file, so install is genuinely trivial.
Where people get burned
- The diagnostics are in the terminal, not the UI. Every
[HALO-VAE]line prints to the console where you launched ComfyUI. If you use a launcher that hides it, you'll miss the whole story. - It fixes the cast bug, not upstream NaN. If the node reports NaN in its output, the damage happened earlier - the latent or model is already poisoned, and FP32 decoding can't resurrect it. That's the moment to check the Latent Debug node and the
--force-fp32launch flag. - There's a small cost. Casting the VAE to FP32 and back every run adds overhead, and the VAE can use noticeably more memory in FP32. On a 128 GB Strix Halo that's nothing; on a tight 8 GB card it's a real consideration.
If your black image came from the bf16-to-numpy path specifically, this node is the fix. If it didn't, it'll tell you that too - honestly, which is more than most workarounds do.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | — | |
| vae | VAE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |