MiniMax-H3 Single-Frame Decode / direct (BFS)
Your H3 output looks like a checkerboard — this is the decode that fixes it
- vae
- samples
- IMAGE
If you've generated with MiniMax-H3 in ComfyUI and run the latent through the stock VAEDecode, you've seen it: a blocky, quadriculado grid instead of a frame. MiniMax-H3 is the open-weight multimodal video/image model that the community has been running locally since mid-2026, and it has a quirk - its latents refuse to decode the boring way. This node is the fix. It's the exact decode recipe from the single-frame VAE card (iamkaikai/MiniMax-H3-Single-Frame-VAE-500K) and the multimodalart/MiniMax-H3-images Space: the path those workflows use instead of vae.decode().
Why stock VAEDecode fails: the H3 latent is a video-style latent (nested video + audio, actually - more on that below), and ComfyUI's temporal chunker can't form a chunk when you hand it only a couple of latent slices. The reference path skips the chunker entirely and calls the decoder directly. This node reproduces that, and it's careful about four details that corrupt the output silently if any one of them changes:
- It calls
decoder(post_quant_conv(z))directly - nevervae.decode(). - It takes
decoded[:, :, -1], the last output slice, not index 0. - It de-normalizes the latent back to pixel space (
z * latents_std + latents_mean). - It de-normalizes pixels out of ImageNet space (mean 0.485/0.456/0.406, std 0.229/0.224/0.225). Skip this and the image comes out dark with blown contrast, like a tone-mapping bug.
The inputs are exactly three, and only one deserves your attention:
vae- the H3 VAE with the single-frame decoder, i.e. loaded throughMiniMaxH3SingleFrameVAELoaderfrom this same pack. A stock-loaded H3 VAE gets a clear error instead of garbage.samples- the H3 latent straight off the sampler/DiT. This is where stockVAEDecodechokes.latent_index- which temporal slice to decode.0is the first,-1is the last (it accepts -64 to 64 for the longer clips). Since H3's minimal clip is only a couple of latent steps, in practice you decode the last slice and get the crispest still.
The output is a single IMAGE, ready for Save Image or any image node. One piece of plumbing worth knowing: H3 latents arrive nested - video and audio components - and the node unbinds them and keeps the video part, so it works with the raw DiT output without you doing anything extra.
Installing it
This is one node in a bigger grab-bag pack. Through ComfyUI Manager, search for ComfyUI-BFSNodes. Or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/alisson-anjos/ComfyUI-BFSNodes.git
cd ComfyUI-BFSNodes
pip install -r requirements.txt
Then restart ComfyUI. You'll also need the H3 model and the official VAE, plus the single-frame decoder file, all sitting in ComfyUI/models/vae (the loader picks them up from there).
Common issues
The one real error you'll hit: "este VAE nao e o do MiniMax-H3 (sem first_stage_model.decoder)" - you plugged in a VAE that wasn't loaded through this pack's single-frame loader. Fix the loader, not the decode.
The subtler trap is the opposite: everything loads fine but the image is dark with punched-up contrast. That's the missing ImageNet de-normalization, and it only shows up if you hand-roll the decode instead of using this node. If you're ever tempted to skip this and use VAEDecode, remember the checkerboard. The name isn't marketing - "direct" is the whole point.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| vae | VAE | VAE do H3 com o decoder single-frame (use o loader deste pacote). | |
| samples | LATENT | Latente do H3. Funciona com o latente gerado pelo DiT, que e onde o VAEDecode padrao falha. | |
| latent_index | INT | 0-64–64 | Qual fatia temporal decodificar. 0 = primeira, -1 = ultima. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |