MMH3 Ultimate Upscale
The one-node way to upscale MiniMax H3 video without nuking your VRAM
- model
- conditioning
- latent
- noise
- sampler
- sigmas
- negative
- latent_upscale_param
- temporal_split_param
- spatial_split_param
- latent
- segments_info
- tiles_info
Your MiniMax H3 clip looks great at 768p. Then you want it bigger, hit the "Upscale Latent" node, and get either an error or a soggy result - because H3 doesn't store video the way you're used to. Its latent is a nested bundle: 24 channels of video plus 32 channels of audio in one tensor. Standard upscale nodes don't understand that structure, so they either choke on it or quietly wreck the audio half. MMH3 Ultimate Upscale exists to make upscaling H3 feel like upscaling a normal latent again - and to do it on cards that would OOM on a single high-res pass.
What it actually does
It runs the whole re-enhancement loop in one node: temporal chunking (so arbitrarily long clips fit in memory), an optional latent upscale per chunk, spatial tiling (so arbitrarily high resolutions fit in memory), then per-tile diffusion sampling and spatial + temporal stitching. This is the tiled-diffusion pattern from image upscaling - think Ultimate SD Upscale - ported to H3's nested latent, with the audio track carried through untouched on every chunk and seam. Peak VRAM stays bounded to a single tile, because only one tile is sampled at a time and the 3D upscaler gets offloaded to CPU while the diffusion model unloads around it. They're never resident together.
A few of the seam details are genuinely clever. Each chunk's frame-0 keyframe is pinned to the previous chunk's re-sampled boundary frame (that's the anchor_strength business), and overlapping chunks are stitched with a linear cross-fade instead of a hard cut, so you don't get a visible jump between chunks. Tile seams use a frozen overlap mask: the strip a tile shares with an already-stitched neighbor is pre-filled and locked, so the re-sample can only change the tile's free interior. That's how you avoid blocky, tiled-up-looking video.
The inputs that matter
The node takes the standard sampling kit - model, conditioning, latent, noise, sampler, sigmas - plus cfg (default 1.0), which only kicks in when you connect negative; without a negative it uses a basic positive-only guider. The three optional inputs are where the real power is:
temporal_split_param- from MMH3 Temporal Split Params; leave unconnected to process the latent as one chunk.spatial_split_param- from MMH3 Spatial Split Params; leave unconnected to sample each chunk whole.latent_upscale_param- from either upscale-params node; leave unconnected to skip upscaling entirely.
That's the whole trick: every stage is optional, so you can add chunking, tiling, and upscaling one at a time. Start with nothing connected to prove the loop works, then turn on pieces.
The single latent output is the upscaled, re-sampled, stitched H3 AV latent - decode it with the H3 VAE. The other two outputs, segments_info and tiles_info, are marked DEBUG ONLY and are plain dicts of metadata (frame ranges, tile extents, stitching mode). Don't wire them into anything expecting a latent.
Install
Via ComfyUI Manager, search Comfyui-MMH3-UltimateUpscale, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bbaudio-2025/Comfyui-MMH3-UltimateUpscale
Then restart ComfyUI. There are no pip dependencies - the pyproject declares dependencies = [] - but the pack is written against the newer comfy_api.latest node API, so it needs a reasonably current ComfyUI; on an old install the nodes simply won't register. The upscale model itself is optional and lives in models/latent_upscale_models (more on that in the params-node articles).
Issues you'll actually hit
- "expects a MiniMax H3 AV latent" - you fed it a normal latent. This node only accepts H3 output, so route it through the H3 VAE/decode path.
- "Upscale width must be >= tile_width" - if you tile, the target upscale size has to be at least your tile size; otherwise the tiling grid doesn't make sense.
- Size mismatch artifacts - the width/height you set for upscaling must match the conditioning's generation size. This one is subtle and the source of most "why is it blurry/warped" posts.
- One honesty note: the author flags this as vibe-coded, and the README's advice for bugs is literally "search with AI". It's a young, niche pack with basically zero community track record yet, so treat odd behavior as plausibly a bug - but the architecture and the audio preservation are solid on paper.
One background check worth mentioning: H3's open weights carry a community licence that excludes the US, EU, UK and Korea from running them locally, so depending on where you are, this whole upscaling pipeline may sit on the wrong side of the model's terms.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | The diffusion model used to re-sample every chunk/tile (guider is built internally). | |
| conditioning | CONDITIONING | Conditioning used to generate this latent. Per chunk it is re-anchored in time; per tile its keyframes are spatially cropped; the frame-0 keyframe is pinned to the previous chunk's re-sampled frame. | |
| latent | LATENT | Denoised MiniMax H3 AV latent to enhance. | |
| noise | NOISE | Noise source; one noise tensor is generated per piece. | |
| sampler | SAMPLER | Sampler used for every chunk/tile. | |
| sigmas | SIGMAS | Sigma schedule used for every chunk/tile. | |
| cfg | FLOAT | 1.00–100 | CFG scale used when 'negative' is connected. |
| negativeopt | CONDITIONING | Negative conditioning. When connected, a CFGGuider is used with the 'cfg' value; otherwise a basic guider (positive only). | |
| latent_upscale_paramopt | H3_UPSCALE_PARAM | Output of 'MMH3 Latent Upscale with Model Params' (H3 3D upscaler) OR 'MMH3 Latent Upscale Params' (model-free interpolation). Leave unconnected to skip upscaling. | |
| temporal_split_paramopt | H3_TEMPORAL_PARAM | Output of 'MMH3 Temporal Split Params'. Leave unconnected to process the latent as a single chunk. | |
| spatial_split_paramopt | H3_SPATIAL_PARAM | Output of 'MMH3 Spatial Split Params'. Leave unconnected to sample each chunk whole (no tiling). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | Upscaled, re-sampled, stitched MiniMax H3 AV latent. |
| segments_info | DICT | DEBUG ONLY. Per-chunk metadata: frame start/count, video/audio token ranges, upscale applied. |
| tiles_info | DICT | DEBUG ONLY. Per-chunk spatial grid metadata: offsets, tile extents, overlaps, stitching mode. |