MiniMax H3 Image to Video 2-Pass
MiniMax H3 image-to-video in two passes
- clip
- vae
- first_frame
- last_frame
- positive_1
- positive_2
- latent
The name makes this sound like it dials into MiniMax's hosted API. It doesn't - no key, no network call. This node is pure local conditioning prep for MiniMax H3, the 33B open-weights omni video model, and it exists to make the "two-pass" way of running H3 less wasteful.
Here's the situation it solves. Generating H3 video on a consumer card is slow, so a popular pattern is to render a cheap low-res pass first, eyeball it, and only then spend the GPU time on a high-res refinement pass. Set that up naively and you build the prompt conditioning twice - which means running H3's CLIP twice and VAE-encoding your keyframe images twice, once per resolution. MiniMaxH3ImageToVideo2Pass does all of it in one node. The author's own comment in the source flags the point: CLIP runs exactly once, on the high-res frames, and both passes share that single encode.
What it actually hands you
positive_1- conditioning for the low-res first passpositive_2- conditioning for the high-res refinement passlatent- the empty audio-video latent for pass one, sized at the low-res dimensions
Wire positive_1 and latent into your first H3 sampler, then positive_2 into the second-stage sampler. Because the latent is only built for the cheap pass, you can bail after previewing pass one - this pack even ships a sibling LatentPreviewTinyVAE node that pauses the queue so you can look before committing to the expensive half.
The inputs you actually set
clipandvae- from your local H3 checkpoint, loaded with ComfyUI's MiniMax H3 loader. Hook a Stable Diffusion clip or vae up here and you'll get quietly wrong conditioning, not an error.prompt- plain text; it's also fed the high-res keyframe images as context, which is the H3 "unified context" trick for grounding motion and subject.length- frame count at 24fps. Default 124 ≈ 5 seconds. The tooltip spells out the catch: it's snapped up to the model's 17k+5 frame grid, so type 100 and you'll actually get 107. The trained range is roughly 124–362 (about 5–15s); anything longer is untested.width_1/height_1(default 768×432) andwidth_2/height_2(default 1344×768) - pass-one and pass-two resolutions, both 16:9 by default. If your start frame isn't that aspect, change these, because the node resizes your images to fit rather than asking nicely.first_frame/last_frame- optional. Supply just a start frame for image-to-video; add the end frame and you're pinning both ends of the clip, the Kling-style motion-control move people were most excited about at H3's launch.
Installation
It ships in the lhaoyun6/ComfyUI-lhyNodes pack, so the usual applies:
cd ComfyUI/custom_nodes
git clone https://github.com/lihaoyun6/ComfyUI-lhyNodes.git
python -m pip install -r ComfyUI-lhyNodes/requirements.txt
Or search "lhyNodes" in ComfyUI Manager and restart. The requirements (ultralytics, opencv, yarl) exist for the pack's other nodes - face reformer, batch tools - not for this one. You do need the actual H3 weights in your models folder (reported ~42.5GB full; the sampler is the VRAM hog, this node is light). Note the pack README hasn't caught up with these newer MiniMax nodes - the code is the doc, and it's under model/conditioning/minimax.
Where people get burned
Before anything else: check you're licensed to run H3 locally. The MiniMax H3 Community License excludes the US, EU, UK and South Korea from its Applicable Territory - running these weights there isn't licensed, outputs included. This node needs the local weights; if you're in an excluded territory, only the hosted API path (not this) is open to you.
Other than that, the usual suspects: match your frame aspect to the pass resolutions, expect your requested length to snap upward, and remember the latent output is an AV latent - decode it through H3's own decode path, not a plain SD VAE. Treat this node as a newer addition from an author better known for the hugely popular FlashVSR video upscaler; it's young, so if the two-pass wiring feels awkward, it's because the pattern is still settling.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| vae | VAE | — | |
| prompt | STRING | — | |
| width_1 | INT | 76832–16384 | — |
| height_1 | INT | 43232–16384 | — |
| width_2 | INT | 134432–16384 | — |
| height_2 | INT | 76832–16384 | — |
| length | INT | 1245–3600 | Frame count at 24 fps, snapped up to the model's 17k+5 grid (124 = ~5s; trained range is ~124-362, longer is untested) |
| first_frameopt | IMAGE | — | |
| last_frameopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| positive_1 | CONDITIONING | — |
| positive_2 | CONDITIONING | — |
| latent | LATENT | — |