🎬🧊AGSoft Minimax H3 Latent Upscaler
Make MiniMax H3 Clips Bigger Without Touching the VAE
- latent
- video_latent
- video_audio_latent
The honest way to make a MiniMax H3 clip bigger is decode to pixels, run a pixel upscaler, then encode back to latent - two full VAE passes over the whole clip, and the encode half quietly eats the detail the upscaler just invented. This node skips both. It takes the H3 video latent - 24 channels, [B, 24, T, H, W] - and resizes it in latent space with a small learned 3D network.
That matters more for H3 than for an image model. Its VAE compresses 16× spatially, so a 1280×704 frame is an 80×44 latent, and this turns 80×44 into, say, 160×88 before anything is decoded. Since H3 is the 33B omni-modal model with native stereo audio, its latents also usually arrive fused with audio - the interesting half of this node.
How it works
The network is LatentResizer3D in the source: conv_in to 512 channels, a stack of residual blocks carrying a scale embedding (AdaGN - the target scale projected into per-channel scale/shift), depthwise temporal convolutions every second block, a trilinear interpolate up to the target latent H/W, then decoder blocks and conv_out back to 24 channels. Time is never resized. Latents are normalized with fixed per-channel mean/std from the author's training code, then un-normalized after.
So: no VAE round trip, no re-compression, and temporal convs that keep frames coherent instead of upscaling each as an independent image. What you don't get is new information - this is the hi-res-fix half of upscaling, not a generative restorer. For real detail, upscale here and then run a second sampler at low denoise on the bigger latent.
The inputs that matter
latent is the smart one. Feed it a plain H3 video latent (image or video - a 4D [B, 24, H, W] gets a temporary T=1 and squeezed back) or the native joint AV latent, a NestedTensor of [video, audio] where audio is 32-channel. The joint form is split automatically, only the video member is upscaled, audio passes through untouched.
model_name is your upscaler checkpoint from ComfyUI/models/latent_upscale_models - .safetensors or .pth, with the architecture auto-detected from state-dict keys (channels, block counts, temporal kernel; no temporal weights switches temporal handling off). Get that file first - with an empty folder the dropdown is blank and the node refuses to run.
Sizing is three modes in one node: scale by multiplier (default 2.0, capped at 4.0), target dimensions (width/height in pixels), or megapixels (frame area at the source aspect ratio). align is the output pixel grid, default 32 - internally LCM'd with the VAE's 16, so you can't knock the result off H3's alignment. keep_proportion (on by default) hunts neighbouring grid pairs for the one that holds your aspect best, and worth knowing: with it on the height field is basically advisory, since the node fits your width and derives height from the source ratio.
precision (fp16 default, plus fp32 and bf16) and offload_after_upscale are your VRAM dials. device silently falls back to CPU with no CUDA - it works, slowly.
Outputs: video_latent is the upscaled video alone, and video_audio_latent is that video re-joined with the original untouched audio - it replaces the Separate AV Latent / Concat AV Latent pair. Wire the latter into a second sampler pass, or decode and save.
Install
ComfyUI Manager, search comfyui-AGSoft, install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/Art-xmaster/comfyui-AGSoft.git
# restart ComfyUI
Then put your checkpoint in ComfyUI/models/latent_upscale_models/. The node registers that path itself, so you don't need to create it before ComfyUI starts - but refresh the node UI if you dropped the file in afterwards.
The pack's requirements.txt pulls numpy, opencv-python and translators - none needed by this node, which wants torch and Comfy's own comfy.utils. The loader imports every .py file in its folder in a try/except, so a module missing a dependency is logged and skipped rather than killing the pack. If Manager skipped requirements:
cd ComfyUI/custom_nodes/comfyui-AGSoft
pip install -r requirements.txt
Where people get burned
Long clips, big VRAM spike. Temporal convs mean the whole clip goes through in one shot - the author notes in the code that chunking isn't equivalent, so VRAM scales with frame count, not just resolution. If a 5-second 2× pass OOMs, try bf16, turn on offload_after_upscale, or split the clip with the pack's own MiniMaxH3 Latent Slice / Stitch Latent nodes and upscale the pieces.
"Only upscaling is supported." Every mode rejects a target smaller than the source, so target dimensions below your real clip size errors out. Scale 1.0, or a target equal to the source, returns the latent unchanged.
video_audio_latent wired to a video-only latent. Hard error - the node checks whether slot 1 is linked in the graph. Use video_latent, or feed a joint AV latent.
Old ComfyUI builds. The joint path needs comfy.nested_tensor; without it, re-joining the AV latent raises instead of silently dropping audio.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | Smart input: plain 24-channel MiniMax H3 video latent (image or video) OR native joint audio-video latent (NestedTensor [video, audio]); the joint form is split automatically and only the video member is upscaled. --- Умный вход: обычный видеолатент MiniMax H3 на 24 канала (изображение или видео) ИЛИ совместный аудио-видео латент (NestedTensor [video, audio]); совместная форма разделяется автоматически, апскейлится только видеочасть. | |
| model_name | COMBO | Checkpoint of the learned 3D upscaler from models/latent_upscale_models (.safetensors or .pth, architecture auto-detected). --- Чекпоинт обученного 3D-апскейлера из models/latent_upscale_models (.safetensors или .pth, архитектура определяется автоматически). | |
| mode | COMBO | scale by multiplier | How the target pixel size is computed: source size x scale, exact width/height, or total area in megapixels at the source aspect ratio. --- Как вычисляется целевой размер в пикселях: размер источника x scale, точные width/height или общая площадь в мегапикселях с пропорцией источника. |
| scale | FLOAT | 2.001–4 | Upscale multiplier applied to the source pixel size (mode: scale by multiplier). --- Множитель апскейла к пиксельному размеру источника (режим: scale by multiplier). |
| width | INT | 128064–4096 | Target pixel width (mode: target dimensions); snapped to the alignment grid. --- Целевая ширина в пикселях (режим: target dimensions); приводится к сетке выравнивания. |
| height | INT | 70464–4096 | Target pixel height (mode: target dimensions); snapped to the alignment grid. --- Целевая высота в пикселях (режим: target dimensions); приводится к сетке выравнивания. |
| megapixels | FLOAT | 1.00.1–8 | Target frame area in megapixels at the source aspect ratio (1024x1024 = 1 MP, mode: megapixels). --- Целевая площадь кадра в мегапикселях с пропорцией источника (1024x1024 = 1 МП, режим: megapixels). |
| align | INT | 321–512 | Output pixel grid step: both output axes are rounded to multiples of this value, kept compatible with the 16-pixel grid of the H3 VAE. --- Шаг пиксельной сетки выхода: обе оси результата округляются до кратных этому значению с сохранением совместимости с сеткой 16 пикселей VAE H3. |
| keep_proportion | BOOLEAN | true | Search nearby grid pairs and pick the one that best preserves the source aspect ratio; off rounds width and height to the grid independently. --- Перебирает соседние пары сетки и выбирает наилучшую по сохранению пропорций источника; off округляет ширину и высоту по сетке независимо. |
| device | COMBO | cuda | Compute device for the upscaler network; silently falls back to CPU when CUDA is unavailable. --- Устройство вычислений сети апскейлера; молча откатывается на CPU, если CUDA недоступна. |
| precision | COMBO | fp16 | Inference precision of the upscaler network; fp16/bf16 roughly halve VRAM usage. --- Точность инференса сети апскейлера; fp16/bf16 примерно вдвое снижают потребление VRAM. |
| offload_after_upscale | BOOLEAN | false | Move the cached network to CPU after the run to free VRAM; the next run pays the transfer back. --- После запуска переносить кэшированную сеть на CPU для освобождения VRAM; следующий запуск платит обратным переносом. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_latent | LATENT | Upscaled video-only latent; if the input was joint AV, the audio member is dropped here. --- Апскейленный латент только видео; если вход был совместным AV, аудиочасть здесь отброшена. |
| video_audio_latent | LATENT | Joint AV latent: upscaled video re-joined with the original untouched audio member. Raises an error if connected while the input had no audio part. --- Совместный AV-латент: апскейленное видео, собранное обратно с исходной нетронутой аудиочастью. Выдаёт ошибку, если выход подключён, а на входе не было аудиочасти. |