Nodes/ComfyUI-MAINodes/H3 Clock Remap (any model, presets)
ComfyUI Node

H3 Clock Remap (any model, presets)

De-rope any model, not just MiniMax H3

By matlowai·Created 17 days ago·Updated about 16 hours ago· 112
H3 Clock Remap (any model, presets)
    • hold_map
    • length
    • report
    • profile_json
    hold_map
    model_profileltx-2.5
    custom_block8
    custom_hold_scale4
    custom_legal_step8
    custom_legal_offset1
    custom_fps25.000
    custom_cap_seconds0.0

    Here's the cleanest idea in this pack's experimental corner: the de-rope pipeline works by holding fast-motion frames to give the model more temporal room, then dropping the holds. That logic shouldn't care which model did the generating - but it does, because every video model has its own latent clock. H3's frames snap to a 17k+5 grid with 5 latent tokens per 17-frame group. LTX-2.5 runs an 8k+1 grid. A hold map built for one is garbage for the other.

    H3 Clock Remap is the adapter: it takes any hold map (from the H3 Jerk Oracle, H3 Manual Hold Map, or H3 Drawn Plan) and retimes it onto another model's clock, so you can run the de-rope trick on a regenerating model that isn't MiniMax H3. This ships on a branch (generic-derope) and it's marked alpha - the LTX-2.5 graphs behind the author's derope demo page are the proof it can work, not the promise that it works everywhere.

    How it works

    The node knows each model's "profile": frames per latent time block, hold scale, legal length grid, fps. For the selected profile it scales holds of 2+ by the profile's hold_scale, quantizes them to whole latent time blocks, and carries the target's legal frame grid through the output map. Holds of 1 stay 1 - a plain single-frame hold is universal. The output feeds the rest of the pipeline unchanged: H3 Time Smear pads to the target's grid (LTX-2.5's 8k+1 instead of H3's 17k+5), and H3 Exact Recover / H3 Audio Recover invert the remapped map without knowing it wasn't native.

    model_profile defaults to ltx-2.5, with minimax-h3 as the identity arm (the map passes through untouched - that's the sanity check). wan-2.2 (unmeasured) is in the dropdown with an honest label: no measurement behind it yet.

    The custom path

    custom exposes the raw fields - custom_block (frames per latent time block), custom_hold_scale (world frames one hold unit buys), custom_legal_step/custom_legal_offset (the legal length formula step*k + offset), custom_fps, and custom_cap_seconds (longest single pass before the retime needs splitting). That last one matters: the report "says when the profile is unmeasured or the retime needs more than one pass," which is the node's way of telling you the price before you pay it.

    If you get a working custom row, you can save it as a preset by adding it to <user dir>/mainodes_models.json - the details are in the pack's DEROPE_ANY_MODEL.md. Outputs: hold_map (retimed), length (target-legal frame count), report (the price tag), and profile_json (the resolved profile for debugging).

    Where people get burned

    The obvious one: pick the wrong profile and the quantization silently shifts where your holds land. The less obvious one: this only fixes the timing grid - the model that regenerates still needs to be capable of the de-rope behavior, and a hold map retimed onto a model that hasn't been validated for it is an experiment, not a recipe. Treat the (unmeasured) label with respect.

    Installing it

    Same pack, pure Python:

    cd ComfyUI/custom_nodes
    git clone https://github.com/matlowai/ComfyUI-MAINodes
    

    Restart, look under image/minimax/motion. Example graphs want ComfyUI-KJNodes; the nodes don't. And note the generic-de-rope arm currently lives on a branch - if the node isn't in your menu after a plain clone, that's why. Check the repo's branch list before assuming you installed wrong.

    Categoryimage/minimax/motion

    Inputs (8)

    NameTypeDefaultDescription
    hold_mapSTRINGper-frame integer holds, oracle format
    model_profileCOMBOltx-2.54 options: minimax-h3, ltx-2.5, wan-2.2 (unmeasured), custom (use the fields below)
    custom_blockoptINT81–64custom: frames per latent time block
    custom_hold_scaleoptINT41–32custom: world frames one oracle hold unit buys
    custom_legal_stepoptINT81–64custom: legal lengths are step*k + offset
    custom_legal_offsetoptINT10–64
    custom_fpsoptFLOAT25.0001–120
    custom_cap_secondsoptFLOAT0.00–600custom: longest single pass in seconds; 0 = no cap

    Outputs (4)

    NameTypeDescription
    hold_mapSTRING
    lengthINT
    reportSTRING
    profile_jsonSTRING