Comfyui-MMH3-UltimateUpscale README

The project's README from github.com/bbaudio-2025/Comfyui-MMH3-UltimateUpscale. As one markdown file: README.md.

Comfyui-MMH3-UltimateUpscale

Upscale long, high-resolution MiniMax H3 video on a VRAM-limited GPU — in a single node.

This node re-samples (enhances / upscales) an already-denoised MiniMax H3 AV latent through the full auto pipeline under tight VRAM constraints: it processes the clip with temporal chunking (so arbitrarily long videos fit in memory) + spatial tiling (so arbitrarily high resolutions fit in memory), keeping peak VRAM bounded to a single tile, while preserving the audio track intact.

MiniMax H3 generates video as a nested latent that bundles 24-channel video and 32-channel audio in one tensor. Standard ComfyUI upscale nodes do not understand this structure. MMH3 Ultimate Upscale wraps the entire temporal split -> latent upscale -> spatial split -> per-tile sampling -> spatial stitch -> temporal stitch loop into one node, so you can upscale a finished H3 clip the same way you would upscale a normal latent — without breaking audio and without running out of VRAM even on small cards.


Changelog


Features


Advantages

Temporal consistency & smooth time transitions

Pixel-space consistency & smooth spatial transitions

Other


Why chunked re-sampling beats dynamic VRAM offloading

Modern PyTorch/CUDA can shuffle weights between RAM and VRAM on demand, so in principle you can generate without tiling even when the working set exceeds VRAM. In practice this is dramatically slower, and the reason is a bandwidth gap of one to two orders of magnitude:

Path Typical bandwidth
GPU VRAM (GDDR/HBM) ~1000 GB/s
PCIe 4.0 x16 (RAM ↔ GPU) ~32 GB/s
PCIe 5.0 x16 ~64 GB/s

Diffusion sampling runs tens of sequential denoising steps, and a transformer revisits its blocks in the same cyclic order every step — the worst case for any residency cache. If the weights do not fit, nearly all non-resident bytes are re-moved over PCIe on every step:

T(offload) ≈ steps × non-resident bytes / PCIe_bandwidth      ← bandwidth-bound
T(chunked) ≈ pieces × FLOPs_piece / GPU_FLOPS                 ← compute-bound

Unified-memory page faults additionally serialize the CUDA stream, so GPU utilization collapses to single digits. Chunked re-sampling instead bounds the peak working set to all weights + one piece's activations, keeping every forward pass compute-bound. The price is only a small, predictable redundancy:

A constant factor of ~1.2–1.8× always beats a 15–60× per-byte penalty. Host↔VRAM offloading only pays when the excess is small and every moved byte gets high reuse; large-DiT multi-step denoising satisfies neither.


Tuning chunk & tile sizes for your VRAM

Per-piece sampling VRAM ≈ model weights + activations, where the activation part scales roughly with chunk_length × tile_width × tile_height:

Aim for the largest pieces that keep peak VRAM just under capacity (watch ComfyUI's VRAM meter during the first tile), keeping total redundancy within roughly ×1.3–1.8. Starting points for H3:

GPU VRAM tile_width × tile_height chunk_length (multiple of 17 px frames)
8 GB 320–384 34–68
12 GB 384–512 51–102
16 GB 512–576 102–153
24 GB 576–768 136–170

Notes:


Nodes

Node Role
MMH3 Ultimate Upscale Main node. Runs the whole loop. Inputs: latent, conditioning, model, noise, sampler, sigmas, optional negative + cfg, and the three optional param inputs.
MMH3 Temporal Split Params chunk_length (px frames, multiple of 17), temporal_overlap (multiple of 17), anchor_strength.
MMH3 Spatial Split Params tile_width / tile_height (px, multiple of 32), spatial_w_overlap / spatial_h_overlap (px, multiple of 32), fade_width / fade_height (seam mask fade), min_tile_size, overlap_mode, overlap_blend.
MMH3 Latent Upscale with Model Params H3 3D model upscaler: model_name, width, height (snapped to a multiple of 32), device, precision.
MMH3 Latent Upscale Params Model-free interpolation: method, width, height (snapped to a multiple of 32).

Typical workflow

  1. Generate an H3 AV latent with MiniMax H3 (video + audio in one latent).
  2. (Optional) MMH3 Temporal Split Params → connect to temporal_split_param.
  3. (Optional) MMH3 Latent Upscale with Model Params or MMH3 Latent Upscale Params → connect to latent_upscale_param.
  4. (Optional) MMH3 Spatial Split Params → connect to spatial_split_param.
  5. Feed latent, conditioning, model, noise, sampler, sigmas into MMH3 Ultimate Upscale.
  6. Decode the output latent with the H3 VAE.

The width/height you set for upscaling must match the conditioning's generation size (the size the video was conditioned at, after upscale).

Upscale model format: .safetensors only

MMH3 Latent Upscale with Model Params only lists and loads .safetensors checkpoints (.sft is accepted as well, matching ComfyUI core). Pickle formats (.pth / .pt / .ckpt) are skipped while scanning and are rejected before the file is opened.

Why: torch.load() on a pickle checkpoint can execute arbitrary code the moment the model is selected. weights_only=True reduces the risk but is not a reliable mitigation on torch < 2.6 (pickle-time bypass, CVE-2025-32434). Refusing pickle entirely removes that surface.

If you have a .pth checkpoint you trust (for example minimax_h3_latent_upscaler_3d_fp32.pth), convert it once:

import torch, safetensors.torch
sd = torch.load('model.pth', map_location='cpu', weights_only=True)
sd = sd['model'] if isinstance(sd, dict) and 'model' in sd else sd
safetensors.torch.save_file(sd, 'model.safetensors')

If weights_only=True fails, the file is not a plain state dict and should not be trusted — don't work around it by switching back to weights_only=False. Checkpoints left in the folder are reported as ignored in the console at startup.


Reference Projects

This node is built on top of following existing community projects:

The H3 3D upscaler network code and normalization statistics are adapted from the second project; the temporal/spatial split, anchor and append logic follow the first.


Extra

This project was vibe-coded by AI, If you run into any problems, it's best to search with AI.😂

Comfyui-MMH3-UltimateUpscale (bbaudio-2025/Comfyui-MMH3-UltimateUpscale)

Searching Database…

Что это?Кастомная нода ComfyUI, которая апскейлит длинные высокоразрешённые видеолатенты MiniMax H3 AV на GPU с ограниченной VRAM, используя временное разбиение на чанки и пространственный тайлинг внутри одной ноды и сохраняя аудиодорожку нетронутой.
Это отдельное приложение или кастомная нода ComfyUI?Это пакет кастомных нод ComfyUI (Python), встраиваемый в существующую установку ComfyUI и добавляющий ноды вроде «MMH3 Ultimate Upscale», а не работающий самостоятельно.
Как использовать это в ComfyUI-workflow?Установите его как кастомную ноду ComfyUI, сгенерируйте H3 AV latent с помощью MiniMax H3, затем подключите его к MMH3 Ultimate Upscale вместе с опциональными нодами параметров Temporal Split, Spatial Split и Latent Upscale и декодируйте выходной latent через H3 VAE.
Нужны ли модель MiniMax H3 и конкретные файлы checkpoint?Да — он работает с H3 AV latent от MiniMax, а режим апскейла с моделью загружает файлы checkpoint minimaxh3latentupscaler3d.safetensors из папки latentupscalemodels; режиму интерполяции без модели дополнительный checkpoint не нужен.
Есть ли подводные камни, прежде чем полагаться на это?Загружаются только checkpoint-файлы апскейлера .safetensors/.sft — pickle-форматы (.pth/.pt/.ckpt) отклоняются по соображениям безопасности, связанным с CVE-2025-32434. Экспериментальная поддержка LTX2.5 также помечена как проблемная в части аудио и прямо названа пока ненадёжной.
Есть ли что-то необычное в лицензии или обращении с checkpoint-файлами?Проект распространяется под лицензией MIT и сознательно отвергает pickle-форматы checkpoint-файлов (.pth/.pt/.ckpt), потому что torch.load() на них может исполнить произвольный код — риск, который weightsonly=True устраняет не полностью.
Сколько VRAM мне реально нужно?В README есть таблицы подбора: от 8 ГБ с тайлами 320–384 px и чанками 34–68 кадров до 24 ГБ с тайлами 576–768 px; пиковая VRAM остаётся ограниченной примерно активациями одного тайла независимо от длины видео.
Почему бы не положиться на автоматическую выгрузку CPU/GPU в PyTorch вместо тайлинга?Пропускная способность PCIe (32–64 ГБ/с) в 15–60 раз ниже, чем у VRAM, поэтому подгрузка весов модели по требованию во время многошагового диффузионного сэмплирования обрушивает утилизацию GPU; чанковое повторное сэмплирование стоит лишь небольшой избыточности около 1,2–1,8x.
Аудиодорожка переживает апскейл?Да, аудиоканалы во вложенном AV latent переносятся без изменений через каждый чанк и сшивку и никогда не пересэмплируются, поэтому артефактов звука от апскейла нет.
Что за экспериментальная нода LTX2.5?LTX25 Ultimate Upscale распространяет тот же конвейер чанков и тайлов на вложенные латенты видео и аудио LTX2.5 с фиксированным модельным апскейлом 2x, но он помечен как сильно экспериментальный, а его аудиовыход отмечен как глючный.
Size
0.2 MB
Stars
236
Updated
CommitOct 07
Age
1mo
Commits · 90 Days