Nodes/ComfyUI-Continuity/MiniMax H3 Motion Fix
ComfyUI Node

MiniMax H3 Motion Fix

Why your spinning kick is a smear, and the node that slows it down to redraw it

By roadmaus·Created about a month ago·Updated about 19 hours ago· 87
MiniMax H3 Motion Fix
  • model
  • positive
  • negative
  • vae
  • source
  • latent
  • reel
  • reel
  • pass
head0
seed0
steps20
cfg1.00
sampler_name
scheduler
denoise0.50
abstain2.5

MiniMax H3 smears bursty motion - a backflip, a sword arc, a whip-fast turn - into mush, and no seed, steps or sampler fixes it. The cause is structural: one latent time token spans four pixel frames, and four frames of a fast limb need four different poses a single token cannot hold - and re-denoising can't recover poses that were never generated. H3 leads the open-weights image-to-video arena and it still can't draw a kick.

MiniMax H3 Motion Fix is the pack's answer, and like the rest of the internal nodes you don't add it - it's is_dev_only, hidden from node search, and written into the graph when you flip the Motion fix chip on a card (H3 only, never on footage; on a lone shot it's a pill on the row).

How it actually works

The idea is test-time and slightly sneaky: if the model can't hold the poses at this speed, give it a longer clock. The finished pass is retimed by repeating frames where the motion is too hot, the slowed copy is encoded with the video VAE and sampled again from partway down the schedule - video-to-video, so the choreography survives and the rendering is re-rolled - then the original clock comes back by keeping the first frame of every hold group. Every returned frame is generated, never interpolated.

Which frames to hold comes off the pass's own latent: the third difference of latent values over time per token, normalised so H3's uneven (1, 4, 4, 4, 4) token spans don't skew the ranking. Hot tokens get up to four copies, and valleys inside one burst get bridged rather than left as a dip.

That core method is matlowai's Motion Lab (ComfyUI-MAINodes); the pack is upfront that this is a clean reimplementation written from the published method, with the dials its author measured. Five frames at either end are never held, are frozen through the second pass and have their original pixels spliced back byte-for-byte, so the fix can't become a seam step of its own.

The inputs you'll actually touch

Everything here is normally wired by the pack from the shot's own sampler row, but two dials are worth setting by hand:

  • denoise (default 0.5) - how much of the schedule runs over the slowed init. The tooltip is the whole story: 0.5–0.8 keeps the choreography and re-rolls the rendering, lower keeps the smear, higher invents its own choreography.
  • abstain (default 2.5) - the gate. A pass whose peak frame-to-frame change, at thumbnail scale on 0–255, is under this is left alone and says so in the render history; 0 fixes every pass. It matters more than the rest put together, because the method's own profile-contrast measure ranked a static fern higher than a spinning kick - forced through the pass, the fern came back sharper and moving unnaturally. Measured 4.4 on the kick, 1.9 on the fern: the gate is the difference between a feature and a tax. The settings page exposes it as motion_fix_abstain.

The rest: model, positive, negative, vae (the video VAE that encodes the slowed clip), source (the pass as written by the reel node), latent (the sampler's AV latent - only its motion profile is read), head (frames trimmed off the front of the latent when the pass was written), plus seed, steps, cfg, sampler_name, scheduler and reel inherited from the shot. Outputs are reel and pass. The node runs after the one that put the pass on the reel, so it returns the reel with that pass replaced in place, which is what lets a later seam inherit the fixed frames; the soundtrack rides through untouched.

Install

Nothing separate - the node ships with the pack. Manager → search "Continuity", or:

cd ComfyUI/custom_nodes
git clone https://github.com/roadmaus/ComfyUI-Continuity

Restart. No pip install - the pack declares zero Python dependencies. You do need the H3 weights: the checkpoint in models/diffusion_models and minimax_h3_video_vae_fp16.safetensors in models/vae. Missing files are refused before the queue starts, naming the file and the folder.

What it costs, and where it hurts

Measured on a 2-second turbo card: 30 of 56 frames held, the clip slowed to 124 frames, and the second pass cost about twice the card's own sampling time. Per-step cost isn't linear in token count (attention dominates), so a more violent clip pays more than proportionally.

Two things error rather than silently do nothing: hand latent anything but H3's nested (video, audio) AV latent and it raises "expected MiniMax H3's AV latent", and the slowed clip has to land on H3's 17k+5 grid.

The evidence is thin: two measured clips, and the fix hasn't been tried on a pan, which will clear the motion gate on camera movement alone. Start with the gate at its default and A/B one card.

CategoryContinuity/internal

Inputs (15)

NameTypeDefaultDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING
vaeVAE
sourceMMC_PASSThe pass as written by the reel node.
latentLATENTThe sampler's AV latent the pass was decoded from; only its motion profile is read.
headINT00–64Frames trimmed off the front of the latent when the pass was written.
seedINT00–18446744073709550000
stepsINT201–200
cfgFLOAT1.000–30
sampler_nameCOMBO44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBO9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT0.500.05–0.99How much of the schedule runs over the slowed init. 0.5–0.8 keeps the choreography and re-rolls the rendering; lower keeps the smear, higher invents.
abstainFLOAT2.50–50A pass whose peak frame-to-frame change, at thumbnail scale on 0-255, is under this is left alone. 0 fixes every pass.
reelMMC_REEL

Outputs (2)

NameTypeDescription
reelMMC_REEL
passMMC_PASS