IAMCCS H3 Disk Upscale · 2 Learned 3D (Grid-Free) + Stream
Bigger H3 Clips With No Tiles and No Seams
- video_vae
- segment_path
- segment_manifest_path
- report
If you have ever looked at a tiled upscale and seen a faint rectangular ghost in flat areas of sky or wall, you already know why this node exists. Tiled Refine samples the clip tile by tile, and tiles have edges. This one takes the other route: a single learned 3D latent upscaler, applied over the whole spatial frame, with the memory saving done along the time axis instead.
That's the trick, and the node's own docstring is refreshingly specific about it: the provider's built-in temporal chunking is hardcoded to 32 latent tokens and expands each segment with halos, which at Full HD still OOMs on 12 GB. So this wrapper keeps every spatial operation full-frame - no texture grid, no seams - and limits the Conv3D activation peak to core + 2*halo latent tokens at a time, stitching the windows together on CPU.
What you feed it
checkpoint_path from Save AV Checkpoint, a video_vae, and an upscaler_model - the dropdown lists models/latent_upscale_models entries whose filenames contain minimax, h3 and 3d. Then:
- target_preset -
full_hd_1920x1080by default, withhd_1280x720,qhd_2560x1440,uhd_3840x2160, and relativesource_1_5x/source_2x/source_3x, orcustomto use the width/height widgets below. The relative presets resolve against the actual low-res source recorded in the checkpoint, not against a guess. - temporal_core_tokens (4) and temporal_halo_tokens (4) - the memory lever. Core is how many latent tokens get produced per pass; halo is the extra context carried around them so the seams between windows stay invisible. This is the single most useful knob on the node: drop the core if you OOM, and if you see faint temporal pulsing at window boundaries, raise the halo.
- decode_groups_per_chunk - how much gets VAE-decoded per streaming step after the lift.
- upscaler_device / upscaler_precision -
cuda/fp16. On CPU the node insists onfp32and will refuse anything else. - output_render_id - optional new folder name for the upscaled output. Leave it empty and the stage writes back under the source run's id.
Outputs: segment_path, segment_manifest_path, report.
The detail nobody expects: cover and crop
The learned H3 upscaler uses one effective scale for both spatial axes. Ask it to map a 5:3 latent straight onto a 16:9 canvas and you get anisotropic deformation - squeezed faces, stretched motion. So the node computes an aspect-preserving cover canvas that fully contains your delivery target, runs the lift at that size, then crops to the delivery dimensions during the encode. If you're wondering why your 640×384 source to 1920×1080 target doesn't look distorted, that's why.
Two more hard rules, both enforced before any work starts: it will not downscale below the native H3 canvas, and it needs a real installed upscaler model - a blank upscaler_model is an error, not a fallback.
Install and dependencies
cd ComfyUI/custom_nodes
git clone https://github.com/IAMCCS/IAMCCS-nodes.git
Restart, hard-refresh, and keep one copy of the repo. You'll need:
- Comfyui_Minimax_h3_latent_Upscaler, which provides the
MinimaxH3LatentUpscaler3Dnode this one calls. Missing it gives you a clear "install/enable and restart" error. - ffmpeg on PATH and a reasonably current PyAV (
av>=17.0.0); the encode and the exact frame validation use them. - The 3D latent upscaler weights in
models/latent_upscale_models. The pack ships no models - that's true of the whole repo.
Queue it as a separate prompt from your generation. The node unloads resident models before the lift and clears cache again before the streaming decode, precisely so the two stages don't overlap in VRAM.
When this is the wrong tool
It's a latent lift, so it does not re-run diffusion and cannot invent detail that the low-res pass never had. Soft faces stay soft; they just get bigger and smoother. That's the honest split with the sampled route, and it maps onto the general upscaling taxonomy: this is job #1 - more pixels, quickly - not job #2, more detail. If the clip is already clean and you just need 1080p out of it, this is the node you want. If it's mush, run the tiled sampler instead and budget the time. And if you're in the US, EU, UK or South Korea, remember the H3 weights themselves are licence-restricted in your territory before you build a delivery pipeline on top of them.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| checkpoint_path | STRING | — | |
| output_render_id | STRING | — | |
| video_vae | VAE | — | |
| upscaler_model | COMBO | 1 options: | |
| target_preset | COMBO | full_hd_1920x1080 | 8 options: full_hd_1920x1080, hd_1280x720, qhd_2560x1440, uhd_3840x2160, source_1_5x, source_2x, +2 |
| target_width | INT | 1920256–3840 | — |
| target_height | INT | 1080256–2160 | — |
| upscaler_device | COMBO | cuda | 2 options: cuda, cpu |
| upscaler_precision | COMBO | fp16 | 3 options: fp16, bf16, fp32 |
| temporal_core_tokens | INT | 41–32 | — |
| temporal_halo_tokens | INT | 40–16 | — |
| decode_groups_per_chunk | INT | 11–8 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| segment_path | STRING | — |
| segment_manifest_path | STRING | — |
| report | STRING | — |