H3 Inject Video Latent (img2img)
The missing img2img path for MiniMax H3
- av_latent
- images
- vae
- av_latent
- report
H3 Inject Video Latent (img2img) is the node that makes H3 face refinement a refinement instead of a re-generation. It encodes real frames into the video stream of H3's joint audio-video latent, giving the sampler a real starting point - and that's something H3's stock nodes don't do at all.
Here's the gap it fills. H3's own nodes always build a zeros latent. Its references aren't a starting image; they're conditioning that gets re-injected at every step. So out of the box there is no video-to-video path - nothing tells H3 "here's what the actual footage looks like, improve this." In the FaceRefine workflow, that would mean asking H3 to invent the face from scratch rather than fix the one that's there. This node is the bridge: it takes the crops from H3 Face Track + Crop, encodes them with the video VAE, and splices them into the video stream of the AV latent while leaving the audio stream completely untouched.
How it works
The AV latent is a NestedTensor with a video stream and an audio stream. This node unbinds it, encodes your frames, and replaces just the video member. It also guards your mistakes: if the encoded spatial size doesn't match what the latent expects, it raises - that's your signal that the crop canvas and the H3 node's width/height disagree (both are pixels/16, so they must match). If the temporal length is off, it trims or pads instead of failing, and says so loudly in the report - that's the "your frame count is off H3's 17k+5 grid" warning (5, 22, 39 …).
Inputs and outputs
It has no widgets - pure wiring, which keeps it simple:
av_latent- theLATENToutput ofMiniMaxH3ReferenceToVideo.images-cropsfrom H3 Face Track + Crop.vae- the video VAE.
Outputs: av_latent (onward to MiniMaxH3NativeAudioLock, then H3 Per-Frame Denoise) and a report string confirming what got injected.
The denoise rule that matters
Because this node is the "starting image," strength is set downstream by BasicScheduler's denoise - never by SplitSigmas. This is the one that bites people who know SDXL. H3 is flow matching with a large sigma shift (sigma = shift * t / (1 + (shift - 1) * t)), and at the default shift of 12, a denoise of 0.25 - a perfectly ordinary FaceDetailer value - lands at an effective sigma of 0.800, which rewrites the frame. SplitSigmas walks its own schedule and even its last split point on a short schedule sits around sigma 0.8. BasicScheduler instead builds a full-range schedule and keeps only the lowest sigmas, which is why steps and denoise stay independent: 4 steps with a turbo LoRA is both fast and gentle. Push the denoise ceiling too high and the head drifts relative to the body - a content problem no mask can hide.
Install
The node ships in the ComfyUI-H3-FaceRefine pack, so it's one clone and a restart:
cd ComfyUI/custom_nodes
git clone https://github.com/Carasibana/ComfyUI-H3-FaceRefine.git
Restart ComfyUI and it appears under MiniMax H3/Face Refine (ComfyUI Manager finds the pack by searching "ComfyUI-H3-FaceRefine"). It needs the H3 model stack and VAEs you already have if you're generating H3 video - nothing extra for this node itself. The example workflows run the whole thing with ComfyUI-VideoHelperSuite for load/save and MiniMaxH3NativeAudioLock for lipsync.
Troubleshooting
- "Spatial latent mismatch" error - the crop canvas and the H3 node's
width/heightdisagree. Wire the tracker'scanvas_w/canvas_hinto the H3 node instead of typing values, and it stops happening. - Warning about temporal mismatch - frame count off the 17k+5 grid; the node trims/pads to keep you running, but your
lengthon the H3 node should match the clip exactly.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| av_latent | LATENT | — | |
| images | IMAGE | — | |
| vae | VAE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| av_latent | LATENT | — |
| report | STRING | — |