⬡ Polyhedron VAE Codec
VAE encode, decode, and the round-trip test that tells you what the VAE eats
- vae
- pixels
- samples
- audio_vae
- latent
- image
- audio
⬡ Polyhedron VAE Codec is the encode/decode node that replaces the stacked pair, with three things the stock nodes don't do: it decides whether to tile before the pass instead of after the OOM, it has a round-trip mode that answers "is this detail worth adding before the VAE?" with a number, and it handles a joint audio/video latent - the MiniMax H3 shape - in one box.
The tiling bit matters on Windows more than anywhere. ComfyUI's stock VAE decode attempts the full pass and waits for an out-of-memory error, and on WDDM (the Windows GPU driver model) that OOM often never gets thrown - instead the system pages and grinds, and your "decode" quietly takes five minutes. This node runs comfy's own memory formulas first, estimates need against free VRAM, and switches to tiled above ~85% of free - before the pass, not after the crash.
Modes and what they're for
both(default) - two independent lanes: pixels → LATENT and samples → IMAGE, whichever is wired. One box replaces a stacked Encode + Decode pair.encode/decode- force a single lane; the other input is ignored and the console says so.roundtrip- a quality test, not a workflow step. The pixels are encoded and decoded straight back, and the console prints a sharpness ratio before/after. Near 1.0 the VAE kept the detail; a low number means it ate it - fine texture like lace, hair or embroidery usually doesn't survive. That's the answer to "should I add this detail now or after decode?" with a measurement instead of a guess.
The MiniMax H3 path
H3's latents carry audio and video together. This node decodes the video half through the wired vae, and if you wire audio_vae (the audio VAE - the node checks and names it if the model declares no sample rate) the audio output carries the decoded soundtrack too. The split happens once, correctly, instead of twice in two separate stock nodes. There's also h3_still_fix: core decodes a single-frame H3 latent through a branch that hands the ViT decoder a time coordinate of 0.0, which produces a 16px grid over the whole image (ComfyUI issue #15416). auto decodes two time tokens and keeps the last frame - the fix, and it only touches single-frame H3 latents.
The rest of the inputs
tiling (auto/off/on) with tile_size, tile_overlap (spatial, in pixels) and temporal_size, temporal_overlap (frames, for video VAEs). mute_staging_logs silences ComfyUI's staging INFO lines during the pass; the capsule reports how many it muted.
Installing it
Part of the ⬡ Polyhedron Suite pack. ComfyUI Manager → "Polyhedron Suite", or:
cd ComfyUI/custom_nodes
git clone https://github.com/PolyhedronAI/ComfyUI-PolyhedronLoRAStack.git
# restart ComfyUI
No extra dependencies.
Gotchas
Roundtrip is a test - it isn't meant to sit in a production graph, so don't leave it in roundtrip mode and wonder where your latent went. And the MiniMax H3 stuff only does anything on H3 AV latents; on a normal VAE it's inert. For the common "image came out grey" case, that's a VAE/model mismatch - the ⬡ Polyhedron Load VAE node's cross-check is the tool for that; this node is about the codec pass itself.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| vae | VAE | — | |
| mode | COMBO | both | both = two independent lanes; whatever is wired runs (pixels -> LATENT, samples -> IMAGE; wire both and one box replaces a stacked Encode+Decode pair). encode / decode = force one lane; the other input is ignored and the console says so. roundtrip = a quality TEST, not a workflow step: the pixels are encoded and decoded straight back, and the console prints a sharpness ratio before/after -- near 1.0 the VAE kept the detail, low means it ate it (fine texture like lace, hair or embroidery usually does not survive). Answers 'is this detail worth adding BEFORE the VAE?' with a number. |
| tiling | COMBO | auto | auto = decide BEFORE the pass from comfy's own memory formula vs free VRAM (tiled above 85% of free). Stock instead attempts the full pass and waits for an OOM that WDDM often never throws - it pages and grinds. off/on force the verdict. |
| tile_size | INT | 51264–4096 | Spatial tile in PIXELS (decode converts to latent internally, like stock). |
| tile_overlap | INT | 640–4096 | Spatial overlap in pixels. |
| temporal_size | INT | 648–4096 | Video VAEs only: frames per temporal tile (stock semantics). |
| temporal_overlap | INT | 84–4096 | Video VAEs only: frames of temporal overlap. |
| mute_staging_logs | BOOLEAN | true | Silence ComfyUI's staging INFO lines during the pass; the capsule reports how many it muted. |
| h3_still_fix | COMBO | auto | MiniMax H3 only, single-frame latents only. Core decodes ONE latent frame through a branch that hands the ViT decoder a time coordinate of exactly 0.0, which no even token count produces -- the result is a 16 px grid over the whole image (ComfyUI issue #15416). 'auto' decodes two time tokens instead and keeps the last frame; it does nothing on any other VAE or for any length above 1. 'off' is the stock path, for A/B with the same seed. |
| pixelsopt | IMAGE | — | |
| samplesopt | LATENT | — | |
| audio_vaeopt | VAE | OPTIONAL, and only for a joint audio/video latent: the AUDIO vae. Wire it and the audio output carries the decoded soundtrack; leave it and the audio output is None and says so. This must be the audio VAE, not the video one -- the node checks and names it if the model declares no sample rate. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |
| image | IMAGE | — |
| audio | AUDIO | — |