Nodes/JR MiniMax H3/JR MiniMax H3 Tail Frame Latent (Experimental)
ComfyUI Node

JR MiniMax H3 Tail Frame Latent (Experimental)

Get the real last frame without decoding the whole clip

By Goldlionren·Created 3 months ago·Updated 3 days ago· 65
JR MiniMax H3 Tail Frame Latent (Experimental)
  • video_latent
  • vae
  • decoded_frames
  • tail_latent
  • tail_image
  • status
  • tail_context_latent
◄decode_modetail_context►

Chaining H3 generations means feeding the end of clip A into the start of clip B. The naive way is "decode the whole video, take the last frame", which costs you a full decode of a 15-second clip to look at one image. JR H3 Tail Frame Latent does it the cheap way: H3's decoder contract lets you decode only the final seven latent tokens - the window that actually produces the final frames - grab the endpoint, and encode it once into a reusable image-keyframe latent.

It's marked experimental by the author, and it deserves the label for one specific reason the docs are happy to admit to (more below). But the mechanism itself is sound, and it's the node you want for last-frame continuation, wallpaper endpoints, and round-two Director handoffs.

The mechanism

Give it a finished video_latent in [1,24,T,H,W] shape - that means it came out of Split AV Latent's video output, not the AV pair and not the audio stream. It checks T is 1 or 5k+2, that the tensor is float and finite, and that the VAE is a real H3 video VAE (24 latent channels, 16× spatial compression) with a working encoder.

With decode_mode = tail_context (the default), and only when the VAE exposes the exact decoder configuration the author reviewed - clip length 17, chunk size 5 tokens, overlap 2, token drop 3, pre-pad 3, temporal ratio 4, frame overlap 5 - the node decodes just the last 7 latent time slices, which yields 22 frames for a full-length clip. The last decoded frame becomes tail_image, and a single VAE encode of it becomes tail_latent, an [1,24,1,H/16,W/16] keyframe in the shape Director takes for first_latent / last_latent. Unknown temporal configurations fall back to a full decode rather than inventing a window size.

It also keeps tail_context_latent: the raw last-7-token window, cloned without re-encoding, so you can upscale or refine the tail for that lovely-4K-wallpaper trick without paying an encode/decode round trip on the endpoint.

Inputs and outputs

  • video_latent (LATENT) - the finished final-pass latent, after any upscale or refinement. Never an intermediate sampling state or the noise you fed in; tensor shape can't detect residual diffusion noise for you.
  • vae (VAE) - a matching H3 video VAE that has an encoder. The native one is the recommended first test.
  • decode_mode - tail_context vs full_video. Use full_video once as an A/B check that your endpoint matches.
  • decoded_frames (optional IMAGE) - pre-compression frames at source resolution; the node takes their last frame and skips decoding. Connect them before MP4/JPEG compression, not a reloaded movie, and note the supplied input takes precedence over decode_mode.
  • Outputs: tail_latent (keyframe LATENT), tail_image (IMAGE - the exact selected pre-encode frame), status (STRING), tail_context_latent (LATENT).

Install

ComfyUI Manager, search JR MiniMax H3, or clone it yourself:

cd ComfyUI/custom_nodes
git clone https://github.com/Goldlionren/ComfyUI_JR_MiniMaxH3Node.git
python -m pip install -r ComfyUI_JR_MiniMaxH3Node/requirements.txt   # same Python that runs ComfyUI

Restart ComfyUI and hard-refresh the browser. This node needs no extra downloads beyond your H3 weights and VAE; the pack's own requirement list is just imageio-ffmpeg>=0.5, and the KJNodes / SageAttention / Sol-Attn extras are for the acceleration nodes, not this one.

Where people get burned

  • It is not lossless, and the single-frame path had a real bug. The author's tests found darkening and striping in the legacy single-frame encode/decode round trip, even with no upscale and no sampling. So tail_latent is an interface-correct keyframe, not a visually validated reconstruction - don't "fix" it with a gamma correction on your end. When quality matters, use tail_context_latent.
  • Context is not a Director keyframe. [1,24,7,H,W] is a 22-frame local timeline. Decode it, take the last IMAGE to check it against tail_image - same VAE, no supplied frames - then send it through the Neural Latent Upscaler and the AV Latent Builder, with Empty Audio Latent for Tail supplying the matching audio side.
  • Resolution is whatever the video was. A 768p generation gives you a 768p tail even if the original reference image was 1440p. There's no megapixel widget here, on purpose.
  • A decode-only TRT engine isn't enough - the node needs an encoder for the one encode. You can still feed a TRT decoder's already-decoded IMAGE frames through decoded_frames while the native VAE sits on the vae input for the encode.
  • T=1 in means it's already a keyframe. It gets cloned and decoded rather than re-encoded, unless you supply authoritative decoded_frames.
  • Don't build a cycle. Across runs, save the paired IMAGE and LATENT and load them back with Load Image / Load Latent; one graph that loops the tail into its own head is asking for trouble.
CategoryJR MiniMax H3/Latent

Inputs (4)

NameTypeDefaultDescription
video_latentLATENTFinal sampling output -> Split AV Latent -> video_latent.
vaeVAEMatching H3 video VAE with encoder. Native VAE recommended for the first test.
decode_modeCOMBOtail_contextTail context uses the reviewed H3 final 7-token window; unknown contracts fall back to full decode.
decoded_framesoptIMAGEOptional matching decoded/trimmed video frames at source resolution. Uses their last frame, skips decode. No MP4/JPEG round trip.

Outputs (4)

NameTypeDescription
tail_latentLATENT—
tail_imageIMAGE—
statusSTRING—
tail_context_latentLATENT—