H3 Jerk Oracle (profile / window / hold map)
The oracle that reads H3's latent and finds the frames that smear
- samples
- hold_map
- segments
- window_start
- window_len
- profile
- report
This is the node the whole Motion Lab half of ComfyUI-MAINodes is built around. If you've ever rendered an H3 clip of a backflip or a sword arc and watched it dissolve into a smear, you already know the problem this pack exists to fix: MiniMax H3 (the 33B omni-modal video model) blurs bursty motion because one latent token spans four pixel frames, and at high speed those four frames need four distinct poses a single token can't hold. Re-denoising the region doesn't help - the missing poses were never generated. H3 Jerk Oracle is what decides where and when to do something about it, and it does that by reading the clip's own latent. No extra model, no training.
How it works
The oracle takes the finished pass-1 latent and computes per-token jerk - the third time difference, |Δ³| - across the clip's token grid. High jerk means the motion is changing so fast the model gave up and smeared. Those hot tokens become the hold map: an integer per source frame telling the de-rope pipeline "hold this frame 4x" so the regeneration pass has more temporal room to work with. Quiet spans keep a hold of 1, which is exactly why the pipeline costs what it does: you pay for the bursts, not the whole clip.
The knobs you'll actually touch:
samples- the LATENT from pass 1, not the decoded frames. That's the whole trick: it reads the latent directly, so it costs almost nothing.q(0.75 default) - the jerk quantile that counts as "hot". Raise toward 0.85 for tighter spans and less cost, lower toward 0.7 to catch more of the burst.d_max(4) - peak hold count. This is the measured sweet spot; 2–3 saves time but the smear starts coming back.ramp(on) - smooth C1 shoulders on the hold curve instead of hard steps. Leave it on; hard steps visibly jitter.preset- balanced / max quality / economy, each of which overrides the knobs. If you don't want to think, this is where you don't think.
Optional extras worth knowing: bridge (8) fills dips between peaks of the same burst so the plateau doesn't sag mid-burst, abstain_below lets the oracle shut up entirely on clips whose jerk contrast is too low to need anything, and model_profile lets you feed it an LTX-2.5 or Wan 2.2 latent for the "de-rope any model" branch.
What it hands you
hold_map- the string that drives H3 Time Smear's adaptive dilation. This is the money output.segments- the same map in segment form, for H3 Local Rate.window_start/window_len- where the detected burst sits.profile- the raw jerk profile, if you want to look at what the oracle sees.report- the price tag before you pay. World length in, effective regeneration length out. Expect a 5-second action clip to run as 11–13 seconds of frame data, and note the two multipliers aren't the same number: per-step cost scales as tokens^1.7, so 2.5x the frames is roughly 4.9x the time per step. Plug your measureds_per_stepin for a real minutes estimate.
Install
ComfyUI Manager: search for ComfyUI-MAINodes, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/matlowai/ComfyUI-MAINodes
The pack itself has zero Python dependencies (the pyproject.toml dependencies = []). The example graphs do need ComfyUI-KJNodes for a few attention patches, so grab that too if you're loading one of them. Nodes appear under latent/minimax/motion.
Common issues
The classic miss is a mid-burst artifact where the hold plateau dips inside a burst - that's the bridge knob (default 8) closing the valley; if it still hiccups, lower q or raise d_max so the whole burst sits at the plateau. Hard stutter at the edges of a held span means ramp got turned off. And a clip that needs nothing still gets dilated, because q is a quantile - the oracle can rank but it can't abstain on its own; that's what abstain_below is for (the author measured the contrast gap, try 1.5–2.5).
Honestly, for most people: leave it on balanced and let the report tell you what you're about to pay.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | — | |
| length | INT | 1245–3600 | — |
| q | FLOAT | 0.750.5–0.99 | jerk quantile that counts as hot; higher = tighter span, lower cost |
| d_max | INT | 42–8 | peak hold count on the hottest tokens; 4 = measured sweet spot |
| ramp | BOOLEAN | true | C1 ramp shoulders (1,2,..,d_max,..,2,1) instead of hard steps — keep ON |
| presetopt | COMBO | balanced (default) | any choice but 'custom' overrides the knobs above |
| bridgeopt | INT | 80–20 | bridge inter-peak valleys within a burst at d_max (measured production rule: a plateau dip between peaks of the same burst causes mid-burst artifacts). Max gap in tokens to fill; 0 disables. |
| profile_modeopt | COMBO | value |d3| (default) | (alpha) which signal to threshold. The default is the shipped one. |d1| is the honest cheap baseline (on real clips it correlates 0.96-0.98 with |d3|, so the default is closer to motion ENERGY than to jerk). 'trajectory' differentiates the energy CENTROID's path instead, which is closer to the physical quantity; on real textured clips it gave a narrower profile than velocity. EXPERIMENTAL: on SMOOTH synthetic content the centroid is nearly noise-free, so its contrast is not comparable to the value domain's there. Ablate it, do not assume it. |
| abstain_belowopt | FLOAT | 0.00–10 | (alpha) ABSOLUTE gate, 0 = off (shipped behaviour). q is a quantile, so the oracle always dilates the top (1-q) of tokens even on a clip that needs nothing: a synthetic clip with EXACTLY zero trajectory jerk still got 3.06x. If the profile's peak-to-mean contrast is below this, the oracle abstains and returns a flat hold map (no dilation, no cost). Measured contrast ran about 2x higher on a jerky clip than a smooth one, so try 1.5-2.5 and check against a clip you know is calm. |
| fpsopt | INT | 241–120 | only used to phrase the report in seconds |
| s_per_stepopt | FLOAT | 0.000–120 | seconds per step from a baseline render of this clip; 0 skips the minutes estimate |
| est_stepsopt | INT | 181–100 | steps the regen pass will actually run (total_steps x inject) |
| overhead_sopt | FLOAT | 6.70–600 | fixed non-sampling seconds per render (setup, VAE encode/decode). 40 measured at 1.5 MP on a warm instance; take it from the gap between your own 1-step and 2-step wall times |
| model_profileopt | COMBO | minimax-h3 | which model's latent is wired in. minimax-h3 is the shipped path, bit-identical. Any other preset reads THAT model's video latent (LTX-2.5: 128 channels, 1+8k token clock; Wan 2.2: 16 channels, 1+4k) with the same planner, no phase normalisation, and emits holds per SOURCE frame as before - wire into H3 Clock Remap or straight into H3 Time Smear. |
| protect_tailopt | INT | 00–96 | (alpha) hold the LAST n frames at 1 whatever the profile says. A burst that runs into the end of the clip has no 'after' for the model to slow into: measured 2026-08-23 on a chained segment, hold 4 on the closing gesture played it 1.55x fast after recovery; 17 (one token group) brought it to 1.06x. Untested on a single clip; 0 = off |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| hold_map | STRING | — |
| segments | STRING | — |
| window_start | INT | — |
| window_len | INT | — |
| profile | STRING | — |
| report | STRING | — |