Nodes/ComfyUI_Swan_Bits/Swan H3 Tiled Model (High Stage)
ComfyUI Node

Swan H3 Tiled Model (High Stage)

Your H3 high-res pass doesn't have to fit in VRAM

By swan7-py·Created 26 days ago·Updated 5 days ago· 7
Swan H3 Tiled Model (High Stage)
  • model
  • stage_latent
  • model
tiles0
enable_tilingtrue

MiniMax H3 video gets to 2K the way image models do it: generate small, lift, sample again. A SamplerCustom runs the low-res stage on a schedule that ends at zero, the Swan SelfLift transition lift hands a clean latent up to the target grid, and a second SamplerCustom re-noises it and samples the high tail. Stage one is cheap. Stage two is where your card taps out - lift the latent 2x per axis and you quadruple the elements, and every denoise step pays for the whole grid at once. This node wraps the model so each forward runs on spatial tiles: what has to fit in memory becomes one slice, not the picture.

H3 is also an audio-visual model, and its latent is a packed pair of streams - a 5D video latent and a 4D audio latent, generated together. You can't tile the audio, because the mouth has to match the words. So this tiles the video stream only, and forwards the complete audio through every tile.

How it works

Each model evaluation is cut along the longer 2x2-patch axis of the video latent - whichever of height or width has more patches - into 1 to 8 overlapping regions. Every tile is forwarded with the full audio stream and audio conditioning, and gets its global coordinates back: the node rebuilds the packed layout per tile and copies the matching rows of position_ids out of the full one, so a tile knows where it lives instead of thinking it's the origin. Tile predictions accumulate on CPU in fp32 and fuse through a normalized linear ramp across the overlap - a weighted average, not a hard cut.

The limitation, straight from the upstream docs this was ported from: there's no cross-tile attention, and only the first tile's audio prediction is kept. Tiling buys VRAM, not fidelity, and the result isn't identical to the untiled pass.

The plumbing is the clever part: a MODEL patch made of two ModelPatcher hooks - a forward wrapper and a PREPARE_SAMPLING memory planner that reserves memory as if the largest tile were the entire job. Because they're hooks rather than a sampler subclass, any sampler works, and the wrapper key is namespaced so it coexists with the original facok/comfyui-SelfLift plugin.

The inputs that matter

model is the model object your high-res sampler uses. Leave the low-res stage on the unwrapped model - wrapping both is pointless and slow. It only accepts MiniMax H3 models.

stage_latent is the latent that sampler is actually sampling: the lift output, or the target-size Empty H3 AV Latent. Its shape must match the sampling input exactly, or you get tiled memory planning received a different latent shape than the sampling input.

tiles is the only real dial. 0 picks the largest count that fits the estimated workspace, 1 hands the unwrapped model back untouched (a free bypass), 28 forces the count. The single output is model (MODEL), wired into the high-res SamplerCustom's model input:

low-res SamplerCustom (low_sigmas, original MODEL) ──→ Transition Lift
    ├─→ Swan H3 Tiled Model (High Stage).stage_latent
    └─→ high-res SamplerCustom (high_sigmas).latent_image   ← same latent, two wires

Masks: plan around this

Tiling accepts exactly one mask shape - video all-ones, audio all-zeros, which is what the lift's keep_audio produces. Anything else is refused with a clear error (tiled video preservation is not supported, tiled audio conditioning requires a fully preserved audio mask), and ControlNet isn't supported at all. No inpainting with tiling.

Install

Manager → search the pack title ComfyUI_Swan_Bits, or:

cd ComfyUI/custom_nodes
git clone https://github.com/swan7-py/ComfyUI_Swan_Bits
# restart ComfyUI

No requirements.txt, no pip step, nothing to download - the pack is pure ComfyUI and torch. What you do need is a ComfyUI new enough to ship H3: the tiling code imports comfy.ldm.minimax.model.PackedLayout, so an install older than H3 support (August 2026) fails at import. One licence note, since H3 is the point: the MiniMax H3 Community License excludes the US, EU, UK and South Korea, so in those regions the local weights aren't licensed to you at all.

Where people get burned

OOM anyway. tiles=0 estimates your free workspace optimistically - the pack's README flags that this ComfyUI reports MIN_WEIGHT_MEMORY_RATIO = 0.0, which effectively assumes weights can spill. Set tiles by hand (2, then 4) and read the console: [Swan_Bits tiling capacity], [Swan_Bits tiling plan] and [Swan_Bits tiling memory] print free memory, the chosen axis and tile count, and the estimated footprint of the largest tile. Heuristics, not measured peaks.

tiled H3 keyframes must match the target latent height and width. Keyframe latents are on the wrong grid for this stage. The high-res stage wants them at target resolution and narrows them per tile itself; that's what the pack's KeyframeResize node does, one stage down.

Seams or per-tile drift. Fewer tiles is the only lever you get - overlap is computed internally and isn't exposed. If 2 tiles look clean and 8 don't, that's the no-cross-tile-attention limit showing.

CategorySwanBits/H3

Inputs (4)

NameTypeDefaultDescription
modelMODELModel used by the high-res SamplerCustom. Leave the low-res stage on the unwrapped model.
stage_latentLATENTThe latent the high-res sampler samples (the transition lift output, or the target Empty H3 AV Latent). Its shape must match.
tilesINT00–80 = pick the largest tile count that fits the estimated workspace. 1 = tiling off (identical to the unwrapped model). 2-8 = force that count.
enable_tilingBOOLEANtrue

Outputs (1)

NameTypeDescription
modelMODEL