ComfyUI Node

Predict PhyFPS

A node that reads how fast your video 'really' moves

By akashzeno·Created 5 months ago·Updated 5 months ago· 2
Predict PhyFPS
  • model
  • images
  • phyfps
  • report
clip_length30
stride4

Here's the thing about video frame rates: the number on the file is a lie half the time. A 24 fps container can hold footage that was generated at 40 fps of real motion, or interpolated from 8. Predict PhyFPS is the workhorse node from the Pulse of Motion pack that measures the physical frame rate - the temporal resolution implied by the motion itself - instead of trusting the container. Feed it a stack of sequential frames and a loaded Visual Chronometer model, and it hands you a float plus a text report.

Why reach for it? Three genuine uses: detecting AI-generated or frame-interpolated footage (synthetic video tends to move at its model's native FPS, not whatever it was saved as), evaluating video quality, and - the one people in the community actually run it for - figuring out what playback FPS makes a generated clip look natural. The person behind the "All in Wan" workflow uses it exactly that way: predict the FPS before combining the video, feed the number into the video-combine node, and you get natural-looking motion without regenerating.

How it works

It's a sliding window over your frames. Each overlapping clip (default 30 frames, which is what the model trained on) gets resized to 216×216, normalized to [-1, 1], and pushed through the Visual Chronometer: a video VAE encoder compresses the clip, a cross-attention layer pools the latents against a learned probe token, and a small MLP head regresses the log FPS, which the node exponentiates back to a real number. Average across all clips, and that's your phyfps. The whole thing runs under torch.no_grad() with a progress bar in the queue, and it uses PyTorch's SDPA attention, so it's faster and lighter than the original manual attention implementation.

The inputs that matter

  • model (VC_MODEL) - from Load Visual Chronometer. Wire it once, forget it.
  • images (IMAGE) - a batch of sequential video frames. Load these with Load Video (Upload) from VideoHelperSuite and connect the IMAGE output. Frames are auto-resized internally, so source resolution doesn't matter much.
  • clip_length (default 30) - frames per clip. The model was trained on 30-frame clips; lower is faster but less accurate. Max 120.
  • stride (default 4) - step between clips. Lower = more overlapping clips = smoother average but slower. Higher = fewer clips = faster but coarser.

Outputs

  • phyfps (FLOAT) - the average predicted FPS across all clips.
  • report (STRING) - a formatted per-segment table: each clip's start/end/mid frame and its FPS, plus the average. Wire both to a Preview as Text (or PreviewAny) node. The report is genuinely useful - it shows you whether FPS is stable across the clip or jumping around.

The stock workflow is four nodes: video loader → Load Visual Chronometer → this → a couple of text previews. Queue it and you get your number.

Install

Search "Pulse of Motion" in ComfyUI-Manager, or do it manually:

cd ComfyUI/custom_nodes
git clone https://github.com/akashzeno/ComfyUI-PulseOfMotion.git
cd ComfyUI-PulseOfMotion
pip install -r requirements.txt

Restart ComfyUI. The checkpoint downloads itself to ComfyUI/models/pulse_of_motion/ on first run. Note that Manager doesn't always list this pack, so if search comes up empty, clone it - that's the known failure mode.

Where people get burned

  • "Not enough frames (X) for clip_length=30" - you need at least clip_length frames in the batch. Feed a short clip and it refuses, which is correct behavior. Shorten clip_length or load more frames.
  • The overestimate problem. Real community feedback: this thing tends to over-predict. People report that feeding the suggested PhyFPS into the video combine makes clips play ridiculously fast. The workflow author admits "it tends to do that, but it really depends on the kind of video/motion." Treat the number as a strong hint, not gospel - verify by eye, and if motion looks sped up, drop the playback FPS manually. This is the main reason the pack hasn't taken off.
  • Frames must be sequential. It's averaging motion dynamics across a sliding window; a shuffled or random batch gives you garbage. Keep whatever order the video loader produced.

One more thing: the batch variant of this node is identical except it also returns the per-segment FPS list. If you only want one number, this is the node you want.

CategoryPulse of Motion

Inputs (4)

NameTypeDefaultDescription
modelVC_MODELVisual Chronometer model from the loader node.
imagesIMAGESequential video frames as an IMAGE batch. Frames are auto-resized to 216x216 internally.
clip_lengthINT302–120Number of frames per analysis clip. The model was trained on 30-frame clips. Lower values are faster but less accurate.
strideINT41–30Step size between clips. Lower = more overlapping clips = smoother average but slower. Higher = fewer clips = faster but coarser.

Outputs (2)

NameTypeDescription
phyfpsFLOAT
reportSTRING