JR MiniMax H3 Progressive Sampler (Experimental)
Denoise at half res, then lift the latent
- model
- positive
- noise
- sampler
- sigmas
- latent_image
- output
- status
MiniMax H3 is a 33B omni-modal model that generates picture and stereo audio in one pass, and it charges you in GPU minutes: a 15-second render means a lot of full-resolution denoiser evaluations over a two-stream latent. The old image fix for that - generate small, then refine big, the "hires fix" pattern - is what this node does, with one twist: the refine step is a neural lift of the predicted clean latent, not a pixel upscale plus img2img.
JR MiniMax H3 Progressive Sampler runs the first N steps of your Euler schedule at a fraction of the canvas, grabs the predicted clean video x0 from the last low-res evaluation, lifts that latent with JR's neural latent upscaler to the exact final grid, re-noises it at the boundary sigma, and finishes the same sigma schedule at full resolution. Total Euler evaluations do not increase - you just buy a few of them cheaply. That's the whole pitch, and it's a real one if you're resolution-bound.
Know what it isn't, though. This is the plain T2VA node - the description is blunt that masks, keyframes and audio-driven/continuation latents are unsupported. Want refs or keyframes? Use its sibling, the Guided variant. Chunked long video or audio-driven MV? Stay on the legacy path.
The knobs that matter
Assuming model, positive, noise, sampler and sigmas are wired, there are only three knobs you'll actually think about:
latent_image- an empty native H3 AV latent at your final target resolution, batch 1. Not an encoded latent, not something you sampled once already. It's the noise field, not the content.transition_step(default 3) - how many denoiser evaluations run at low resolution before the switch.lowres_scale(default 0.5, spatial only) - set it to 1.0 and the node becomes a native Euler baseline: no upscaler, no transition. That's your A/B.
transition_seed_offset (default 1) derives the independent video noise seed used when re-noising the lifted latent as (noise seed + offset) mod 2^64, so it's reproducible. aggressive_memory_cleanup (default false) calls ComfyUI's soft_empty_cache between stages; leave it off unless you're actually fighting for memory, because it usually costs time.
Then the rules bite: sampler must be plain Euler with no churn, noise must be official RandomNoise or DisableNoise, sigmas must be one full schedule from sigma 1 down to zero (denoise = 1), and the target H/W has to sit on H3's 2×2 patch grid.
Outputs are output (the full-res H3 AV LATENT, into your decode/combine chain) and status - a STRING worth reading: grid sizes, per-stage evaluation counts, seeds, and the wall-clock split between the low stage and the lift.
Install
ComfyUI Manager → search ComfyUI_JR_MiniMaxH3Node, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Goldlionren/ComfyUI_JR_MiniMaxH3Node.git
<ComfyUI-Python> -m pip install -r ComfyUI_JR_MiniMaxH3Node/requirements.txt
Use the same Python that runs ComfyUI - portable, Launcher and system Pythons are not interchangeable, and that's the single most common install failure with this pack. The dependency list is refreshingly boring: imageio-ffmpeg>=0.5 and nothing else (torch/numpy/Pillow come from ComfyUI). Then restart ComfyUI and hard-refresh the browser.
Model files, though, are on you. Progressive sampling needs JR's H3-specific neural latent upscaler checkpoint, dropped into:
ComfyUI/models/latent_upscale_models/
The file name must contain both h3 and upscal (e.g. minimax_h3_latent_upscaler_3d_*.safetensors), .safetensors/.pth/.pt. Nothing downloads it for you and there's no interpolation fallback - missing means a hard error, not a blurry video. lowres_scale: 1.0 never touches the upscaler, so you can validate the wiring before hunting weights.
What people actually hit
- "No compatible MiniMax H3 neural latent-upscaler checkpoint was found." See above. This is the #1 first-run error.
- "Only standard Euler is supported" or "Unexpected Euler callback sequence; remove sampler-changing wrappers." Something is re-implementing Euler under you, or you picked a different sampler, or you left churn on. Don't wrap this node's sampler in custom-sampler tricks.
- Schedule rejections. denoise below 1, a partial sigma list, or a schedule not starting at 1 all get refused, because the empty-latent prototype assumes a full denoise.
- Mask/continuation latents. A
noise_mask, a non-empty video latent, batch > 1, keyframes - all rejected. Those workflows live on the Temporal Chunk Sampler and the Sequential Audio path. - Speed expectations. The author's own acceptance note is the honest one: on a 5090,
lowres_scale=0.5came in roughly five seconds faster than the traditional dual-sampling chain - basically a tie - while0.65was acceptable quality with worse prompt adherence and0.6was their pick for those clips. With an 8-step turbo LoRA andtransition_step=3, only three of eight evaluations are cheap and you still pay for the lift. This buys throughput on heavy, high-resolution, generous-step renders; it is not a 2× button for turbo workflows. For the first quality test, turn Adaptive Cache, Sol-Attn andtorch.compileoff, then A/Blowres_scale1.0 vs 0.5 with everything else frozen.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| noise | NOISE | — | |
| sampler | SAMPLER | — | |
| sigmas | SIGMAS | — | |
| latent_image | LATENT | Empty native H3 AV latent at FINAL target resolution. | |
| transition_step | INT | 31–10000 | Number of low-resolution denoiser evaluations; must be smaller than total steps. |
| lowres_scale | FLOAT | 0.500.25–1 | Spatial scale only. 1.0 bypasses the transition for a native Euler A/B baseline. |
| transition_seed_offset | INT | 10–18446744073709550000 | — |
| aggressive_memory_cleanup | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output | LATENT | — |
| status | STRING | — |