H3 Plan Estimate (alpha)
Price a plan before you run it — from your own recorded renders, not a spec sheet
- equivalent_clip_time
- seconds
- work_units
- vram_band
- report
Alpha node from the timeline surface, and one of the more honestly-designed utilities in the pack. The question it answers is "how much is this retiming going to cost me" - before you commit the GPU. The interesting part is how it answers: it refuses to guess from your GPU's spec sheet. Its cost estimates come from your own flight recorder, the JSONL that H3 Record Start / H3 Record Stop write. An uncalibrated guess is worse than no answer - that's not my spin, it's in the node's description.
The three verdicts
equivalent_clip_time(FLOAT) - how many times a plain render of this clip the plan costs. This one is exact from the plan and needs no calibration; the dilated frame count is arithmetic.seconds(FLOAT) - real minutes from YOUR flight recorder. It comes back-1when your box has no recorded runs, and that's deliberate: no runs on record, no estimate. Run a render or two through the recorder pair first, and it calibrates from those.work_units(INT) - how many latent tokens / dilated frames the plan generates, the raw cost driver.vram_band(STRING) - a bracketing verdict from your recorded runs (does this fit your card?), not a peak-bytes prediction.report(STRING) - the human-readable version of all of the above.
Inputs: plan_path (required - a plan.json from the editor, the oracle node, or the CLI), plus optional plan_json (pasted, wins over plan_path), ignore_uncompiled_lanes, port (which instance's /system_stats the VRAM reading comes from, default 8188), and recorder_path (the flight-recorder JSONL, default /root/.cache/mainodes/flight_recorder.jsonl).
Why this design is right
Two nodes in this pack make the same principled choice: H3PlanEstimate and the oracle's cost report both take s_per_step from your measured runs rather than multiplying a generic number. It's the difference between a pricing model and a metronome - a GPU spec doesn't tell you how long your clip's token count takes on your card with your attention patches. If this pack has a house philosophy, that's a piece of it: measure, don't assume.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/matlowai/ComfyUI-MAINodes
or ComfyUI Manager → ComfyUI-MAINodes, restart. Category latent/minimax/timeline.
Common gotchas
seconds at -1 isn't a bug - it's the node being honest that your recorder is empty. And if you point port at the wrong ComfyUI instance, the VRAM band is read from a box that isn't the one running your render. The ignore_uncompiled_lanes default (off) means a plan carrying lanes this backend can't compile gets refused rather than silently mis-estimated - turn it on only if you understand what gets dropped.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| plan_path | STRING | path to a plan.json written by the editor, the oracle node or the CLI | |
| plan_jsonopt | STRING | the plan document itself, pasted; wins over plan_path | |
| ignore_uncompiled_lanesopt | BOOLEAN | false | a plan may carry lanes this backend cannot compile yet (pins, regions). OFF: refuse, so nothing is silently dropped. ON: compile the density lane anyway and name every lane that was skipped |
| portopt | INT | 81888188–8199 | instance whose /system_stats the VRAM reading comes from |
| recorder_pathopt | STRING | /root/.cache/mainodes/flight_recorder.jsonl | flight-recorder jsonl; layer (b) calibrates from YOUR runs only |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| equivalent_clip_time | FLOAT | — |
| seconds | FLOAT | — |
| work_units | INT | — |
| vram_band | STRING | — |
| report | STRING | — |