Nodes/ComfyUI-Easy-Media/MiniMax H3 Latent Upscaler
ComfyUI Node

MiniMax H3 Latent Upscaler

The second pass that never decodes your video

By yolain·Created 4 months ago·Updated a day ago· 186
MiniMax H3 Latent Upscaler
  • latent
  • latent
model_nameNone
mode
align32
enable_temporal_chunkingtrue
force_unloadtrue

This is not an upscaler you point at a PNG. It's the middle step of a two-pass MiniMax H3 generation - the video cousin of hi-res fix - and the reason to care is what it doesn't do: it never decodes your video to pixels and re-encodes it. The latent goes in small, comes out bigger, and the second pass does the detail work at target resolution.

Why you'd reach for it

H3 clips want to be generated small and finished big. The standard way is: decode the first-pass video with the VAE, resize the frames, re-encode, sample again. That round trip costs VRAM, time and a little quality, because the VAE encode is lossy.

This node replaces the resize with a small learned 3D upscaler that works directly in H3's 24-channel latent space, so nothing becomes pixels in the middle. The pack bundles the runtime - you download only the checkpoint weights, and you do not need the external Comfyui_Minimax_h3_latent_Upscaler custom node alongside it.

And be clear about the job: this isn't ESRGAN, and it isn't SeedVR2. It's an enabler for the second pass. The detail comes from H3 sampling again at the bigger size; this node just gets the latent there.

How it works

It confirms the latent is 24 channels (H3's video VAE), works out a target size from your mode, and calls the bundled 3D upscaler. Latents are normalized with the H3 VAE's stored mean/std, the model gets your scale as a conditioning embedding, and the result comes back as float32. In a nested AV latent, only the video stream is upscaled - the audio passes through untouched, which is what you want, since it doesn't need resizing to stay in sync. A noise_mask on the latent gets nearest-neighbour resized to the new grid so masked regions still line up.

Pixel dims are latent dims × 16, H3's spatial compression.

The inputs that matter

Three, really:

  • model_name - the combo of checkpoints found in ComfyUI/models/latent_upscale_models. If that folder is empty the only entry is None and running the node just errors out, so download the weights before you wire anything.
  • mode - a dynamic combo with three shapes: scale by multiplier (a scale of 1.0–4.0, default 2.0), target dimensions (explicit width and height in pixels), or megapixels (area target that preserves the aspect ratio). Pick the mode and the extra fields appear inside it.
  • align - pixel-space alignment, default and recommended 32 for H3. Don't expect your arithmetic to survive it: the pack's own README example, 1344×768 at 1.250, lands on 1664×960 rather than 1680×960, because alignment rounds to the nearest multiple rather than up. A few dozen pixels per side routinely disappear.

The two booleans are worth leaving on: enable_temporal_chunking runs long latents through overlapping temporal windows instead of all at once (lower peak memory), and force_unload drops the upscaler out of VRAM after the run. One output only, latent - wire it into your second-pass sampler (or into the AV concat feeding your decode). Nothing here saves a file.

Installing it

ComfyUI Manager, search ComfyUI-Easy-Media, or:

cd ComfyUI/custom_nodes
git clone https://github.com/yolain/ComfyUI-Easy-Media

Restart ComfyUI. The pack declares no Python dependencies of its own - the README's optional pip installs belong to the subtitle and TTS nodes, not this one. Its FFmpeg requirement is for the assembly nodes, also not this one.

Then grab the weights - minimax_h3_latent_upscaler_3d_fp16.safetensors from LBH-123-AI/Minimax_h3_latent_Upscaler - and drop them in:

ComfyUI/models/latent_upscale_models/

That's the same core folder the LTX latent upsampler uses. Restart, then pick the file in model_name. Its model card gives a 1–4× range; stay inside what the checkpoint supports even though the multiplier field will happily accept more.

Where people get burned

Only the H3 latent is accepted. Hand it a Wan or LTX latent and you get "expects a 24-channel 4D/5D video latent". This node is H3-only, full stop.

Target equal to source is a no-op. Scale 1.0, or a target that matches the input, returns the latent unchanged. It is not a cheap refresh pass.

VRAM does not scale down with the shortcut. Direct latent upscaling saves the decode/encode round trip, but the second pass still runs at the larger resolution, so the budget is set by the second pass, not by this node. Keep enable_temporal_chunking on for anything long, and leave force_unload on unless you're upscaling several latents in a row - the model is cached per device, so unloading it just means reloading it next time.

Alignment surprises. If your second pass comes out at a size you didn't ask for, check align before you file a bug; multiples of 32 are what H3 wants.

Last thing, and it isn't the node's problem but it is yours: H3's weights are licensed out of the US, EU, UK and South Korea. Nodes enforce nothing.

CategoryEasyUse/MiniMax

Inputs (6)

NameTypeDefaultDescription
latentLATENT
model_nameCOMBONoneCheckpoint under ComfyUI/models/latent_upscale_models.
modeCOMBO3 options: [object Object], [object Object], [object Object]
alignINT3216–512Pixel-space alignment; 32 is recommended for MiniMax H3.
enable_temporal_chunkingBOOLEANtrueProcess long video latents in overlapping temporal chunks to reduce peak memory usage.
force_unloadBOOLEANtrueUnload the latent upscaler from VRAM after execution.

Outputs (1)

NameTypeDescription
latentLATENT