VAE Decode New
Skip the decode, get a black frame instead
- samples
- vae
- IMAGE
VAE Decode New is the mirror image of its sibling in this pack, VAE Encode New: same idea, flipped around. Instead of encoding pixels into a latent, it decodes a latent back into pixels - and when the has_face boolean is False, it returns a black 512×512 canvas without running the VAE at all.
The official description calls it exactly what it is: "Decodes latent images back into pixel space images." The tooltip on the output says the same in plainer words - "The decoded image." So what's the "New" doing? It's the escape hatch for the no-face branch of a face-restoration workflow, and it's genuinely useful once you've hit the batch-size wall.
The workflow it's built for. This is from the comfyui_sunxAI_facetools pack by Sunx.ai, an InstantID-flavored face toolkit. The stock pattern looks like: detect a face → refine/restore it in latent space → decode back to pixels → save or preview. But if you're processing a folder where only some images have faces, you don't want to run the full decode on every single frame. The stock VAEDecode has no way to say "skip me." This one does - it takes samples (LATENT), vae (VAE), and an optional has_face boolean, and only calls vae.decode() when has_face is True. When it's False you get a zeroed-out 512×512 image, cost-free.
Why a black frame and not an error? Because most graph endpoints expect an IMAGE. Your SaveImage or preview node needs something, and a cheap placeholder keeps the pipeline flowing. Wire has_face from DetectFaceByIndex's output, and the whole no-face path costs you a few milliseconds instead of a VAE decode.
The catch, and it's a real one. The placeholder is hardcoded to 512×512, regardless of what resolution your actual latent decodes to. If you're generating 1024×1024 images, the empty branch hands you a 512×512 black square, and if you blindly feed that into a SaveImage you'll save a tiny black file next to your real outputs. The safe pattern is the same one the pack pushes everywhere: gate which branch's output you keep with the has_face signal rather than letting both branches write. The blank canvas is a graph-shape convenience, not something you're meant to look at.
Anything else to know? The node also flattens 5D decode output back into a batch, so multi-image latents come through as a clean IMAGE tensor. And like everything in this pack, installing it means installing the whole pack - ComfyUI Manager, search comfyui_sunxAI_facetools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/upseem/comfyui_sunxAI_facetools
then restart. The dependency tree (insightface, onnxruntime, ultralytics, mediapipe, transformers…) is heavy and InsightFace is the usual pain point - it also auto-downloads model files on first use, which surprises people the first time.
If you never run batches with face-less frames, this node is just VAE Decode with extra steps. If you do, it's the difference between a run that wastes a decode per useless frame and one that doesn't.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | The latent to be decoded. | |
| vae | VAE | The VAE model used for decoding the latent. | |
| has_faceopt | BOOLEAN | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The decoded image. |