Nodes/HALO Debug Pack/HALO VAE Encode (FP32)
ComfyUI Node

HALO VAE Encode (FP32)

The other half of the FP32 fix — encode your img2img input safely

By bkpaine1·Created 7 months ago·Updated 7 months ago· 3
HALO VAE Encode (FP32)
  • pixels
  • vae
  • LATENT

If HALO VAE Decode (FP32) is the pack's hero, this is its quieter partner. Where decode turns latent back into a picture, encode goes the other way: pixels into latent. You only hit it in img2img-style workflows, where your starting image has to be compressed into the latent space the sampler works in. If you're doing plain text-to-image, you may never need this node - which is fine. It exists for the day the black-image gremlin follows you into an img2img pass.

The mechanism mirrors the decode node almost exactly. Looking at the source: it saves the VAE's current dtype, casts the whole first_stage_model to FP32, feeds the image through the VAE's normal input processing (which also drops the alpha channel - pixels[:,:,:,:3]), encodes under torch.no_grad(), casts the result to float32, and restores the original dtype in a finally block. Nothing about your VAE is permanently changed; the FP32 mode is a temporary costume it wears for one run.

The reasoning is the same as decode: on AMD ROCm and similar setups, a bf16 VAE encode produces latents that can carry the seeds of a black output - the bf16-to-numpy cast that fails downstream. Doing the encode in pure FP32 sidesteps the whole class of bug, and doing both halves of the cycle in FP32 is what actually protects you, since a black image can come from either direction.

Inputs and outputs

  • pixels (IMAGE, required) - the source image, usually from a Load Image node.
  • vae (VAE, required) - from your VAE loader.
  • Output: LATENT - wire it into your sampler's latent input in place of an Empty Latent.

Swap VAE Encode → LATENT into your img2img path and everything else stays the same. The output latent feeds the sampler exactly like the stock node's would.

Installation

Ships in the HALO Debug Pack alongside the other four. ComfyUI Manager → search "HALO Debug Pack", or:

cd ComfyUI/custom_nodes
git clone https://github.com/bkpaine1/halo_pack

Restart ComfyUI; nodes appear under the HALO category. No dependencies beyond what ComfyUI already ships, no models to fetch - a single-file pack.

Where people get burned

  • Pair it with the FP32 decode. Fixing only the encode half is like fixing one tire. If black images are your problem, use this node for the encode and HALO VAE Decode (FP32) for the decode, so the whole pixel→latent→pixel round trip stays in FP32.
  • Still not enough? Check the model, not the VAE. If encode runs clean but the output stays black, the node's console log will only confirm the encode side. The README is blunt about the boundary: the FP32 VAE nodes fix the numpy bf16 bug, but they can't fix upstream NaN from the diffusion model. That's the Latent Debug and Model Debug nodes' job.
  • The logs are in your terminal, every [HALO-VAE] line, same as the decode node. Launcher hiding the console? You'll see nothing.
  • Memory is a little higher in FP32. One pass is usually nothing; chained img2img loops on a small card are where you'd notice.

It's the node you'll forget exists until the moment you need it - and for AMD img2img users with black output, that moment comes eventually. Cheap to install, drop-in compatible, and it closes the loop on the pack's actual fix.

CategoryHALO

Inputs (2)

NameTypeDefaultDescription
pixelsIMAGE
vaeVAE

Outputs (1)

NameTypeDescription
LATENTLATENT