MiniMax H3 Loop Decode
A plain VAE Decode can't see across the join
- samples
- vae
- audio_vae
- IMAGE
- AUDIO
You can put a lot of work into a clean loop point and lose it at the last step. The VAE is recursive along the temporal axis too - each decoded frame is influenced by its neighbours - so if you hand it a latent whose first frame is the beginning of the loop and whose last frame is the end, it has no idea those two are adjacent. It decodes the edges blind, and you get a subtle flash or colour shift exactly where you didn't want one.
MiniMax H3 Loop Decode is the other half of the pack's loop trick, and it's not optional. If you sampled with MiniMax H3 Loop, you decode here.
What it does differently
It takes the latent, wraps it - pad_clips 17-frame clips of the loop's own latent on each side, plus the same short tail the sampler uses - and decodes that whole thing. Then it throws the padding away and hands you back exactly one loop of frames. The author's tooltip says it plainly: the decoder never starts or ends inside the loop.
The audio gets the same treatment, on its own clock. H3 stores audio latents at 40 per second against 24 video fps, so the audio padding is scaled accordingly, decoded through the audio VAE, and cropped back at sample level. You get a waveform that's the same length as the picture, with no half-frame of dead air at the ends.
One quiet detail worth knowing: the output is exactly one loop, which is five frames shorter than the length you sampled. Ask for length 158, you get 153 frames - a 6.4-second loop at 24 fps. That's not a dropped frame, that's the tail being consumed. Set 107 and you get 102. The README's table is the authoritative list.
Inputs and outputs
samples is the LATENT out of SamplerCustomAdvanced. vae is the H3 video VAE and audio_vae is the H3 audio VAE - two separate sockets because they're two separate models (minimax_h3_video_vae_fp16 and minimax_h3_audio_vae_fp32). Feeding the video VAE into both will not work; the latent shapes are different animals.
pad_clips (1–8, default 1) is how much wrapped latent the decoder looks at on each side. It's independent of the sampler's pad_clips - you don't have to match them, though matching is the sane starting point. Raising it costs decode time and memory, not sampling time, so if you still see a faint edge flicker at the join it's a cheap thing to try before you re-render anything.
Two outputs. IMAGE goes to Loop Interpolate if you're doubling the frame rate, or straight into Create Video / VHS Video Combine if you're not. AUDIO goes into Create Video's audio socket, or a Save Audio node. If you ignore the audio output you'll get a silent clip and wonder where the native stereo went - H3 generates it jointly with the picture, and this socket is where it comes out.
Install
Same pack, same command:
cd ComfyUI/custom_nodes
git clone https://github.com/pxl-pshr/ComfyUI-MiniMaxH3-Loop
Restart ComfyUI. No requirements.txt to pip-install, but the pack imports H3 internals at load time, so ComfyUI v0.42.0 or newer is a hard requirement - on an older build none of the four nodes appear at all.
Both VAEs come from Comfy-Org's MiniMax-H3 repo, listed in the pack README. The example workflows carry the download links, so loading MiniMax-H3-Loop.json will offer to fetch whatever you're missing.
Troubleshooting
Frame count looks wrong. Count the output before assuming a bug: loop frames are always length − 5, and the total is a multiple of 17. If you sampled 209 and got 204, everything is fine.
First and last frames still differ. That's the decoder's own boundary, so push pad_clips up to 2 and re-decode. If the seam survives that, it's in the latent, which means it's the sampler's pad_clips or the prompt - decode can only smooth what it's given.
Everything looks shifted, one clip short. The node assumes your latent ends with that two-latent tail and slices the last two latents off before decoding. Decode here a latent that never went through MiniMax H3 Loop and it'll happily chew up real frames doing it. Put the loop patch back upstream.
Out of memory at decode, after sampling worked. Long loops decode with padding on both sides, and video VAE decode is the memory spike of this whole graph. Drop pad_clips to 1 or decode in a shorter length - 158 instead of 311 is a much bigger saving than it feels like.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | — | |
| vae | VAE | — | |
| audio_vae | VAE | — | |
| pad_clips | INT | 11–8 | 17-frame clips of wrapped latent decoded on each side, so the decoder never starts or ends inside the loop. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| AUDIO | AUDIO | — |