MoMo Video Frame Interpolation
The frame interpolator that doesn't guess, it diffuses
- images
- images
- fps
The diffusion kid on the interpolation block
Most frame interpolation in ComfyUI is optical flow: RIFE and friends estimate where every pixel moved between two frames and warp the middle frame into existence. Fast, cheap, and it smears when things move a lot or disappear behind each other. MoMo is the other camp. It's a diffusion model - "Disentangled Motion Modeling for Video Frame Interpolation," AAAI 2025, by Jaihyun Lew - and this node is a minimal ComfyUI port by chameleon-ai. You feed it a sequence of images and it does one thing: 2x interpolation, N frames in, 2N−1 out.
When do you reach for it? Your video is 12fps and you want it smooth, or you generated a clip with AnimateDiff or LTX at a low frame count and want to double it before encoding - frame interpolation is a standard companion to video upscaling and video-gen workflows. If the motion in your clip is gentle, RIFE is faster and honestly fine. MoMo earns its keep on the hard cases: big motion, occlusions, flickery hand-drawn animation where a warp alone leaves ghosting. It's the "give it a minute, get a cleaner middle frame" option.
How it actually works
For each consecutive pair of frames, MoMo estimates motion between them, warps both frames toward the midpoint, then runs a diffusion U-Net - starting from noise and denoising over a handful of steps - to synthesize the in-between frame conditioned on those warps. That's why it's slow but robust: it's not blending pixels, it's generating the missing frame. The "disentangled" part is the paper's core idea, modeling the motion as separate components instead of one monolithic flow field.
A couple of implications fall out of this. seed matters because the middle frame is a generation - same pair, same seed, same in-between. And steps (default 8, range 1–100) is the denoising budget. Fewer steps is faster and a bit rougher; more is smoother but the cost multiplies per pair of frames.
The inputs that actually matter
- images - your frame sequence as an IMAGE batch (feed from a Load Video / frame-sequence node). Required.
- steps - denoising steps, default 8. This is your quality/speed dial.
- seed - reproducibility.
- mp - mixed precision:
no,fp16, orbf16. If VRAM is tight,fp16/bf16helps; the README's dev setup was AMD/Linux, wherebf16is often the friendlier choice. - resize_to_fit (default on) - fits your frames to the model's training resolution and resizes back afterward. Leave it on unless you hit trouble.
- pad_to_fit_unet (default off) - the author's escape hatch for "resolution mismatch after a sequence of downsamplings and upsamplings in the U-Net." If you get resolution errors, flip this instead of resizing.
- num_workers - DataLoader workers, default 2.
The one input to enjoy, not obsess over: fps (optional, default 24). The tooltip says it plainly - it is not used in processing. The node just doubles whatever number you give it and hands it back. It's a label on the output, so don't expect it to do anything to the pixels.
Outputs: images (the full interpolated sequence) and fps (your input fps × 2). Wire the images into a video save node with the doubled fps.
Install
Via ComfyUI Manager (search the pack title "comfyui_momo"), or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/chameleon-ai/comfyui_momo
pip install -r custom_nodes/comfyui_momo/requirements.txt
Dependencies are torch, accelerate, diffusers, einops - nothing exotic, and note it uses HuggingFace Accelerate under the hood. On first run the node downloads momo_full.pth (~295MB, Apache-2.0) to models/diffusers/ automatically, so no manual model fetch. Tested on Python 3.13 (Linux+AMD); the original code was 3.10, so the range between should be safe.
Where people get burned
Two things, mostly. First: it only does 2x, and it doesn't chain. Want 4x? Feed the output back through the node yourself - it won't do it for you. Second: the speed. Diffusion interpolation is not RIFE. Every pair of frames costs you steps denoising passes, and a 100-frame clip is 99 pairs. A long clip through this node is a "go make coffee" operation, not a "tweak the slider" one. That's the honest trade for cleaner results on hard motion - pick your clips accordingly, and lean on RIFE when the motion is simple enough that a warp will do.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| model_name | COMBO | momo_full.pth | MoMo model to use for interpolation |
| seed | INT | 11–4294967295 | Random seed |
| steps | INT | 81–100 | Number of inference steps |
| num_workers | INT | 21–64 | Number of parallel workers |
| resize_to_fit | BOOLEAN | true | Fit to training resolution and resize back to input resolution for inference. |
| pad_to_fit_unet | BOOLEAN | false | Avoid errors in resolution mismatch after a sequence of downsamplings and upsamplings in the U-Net by padding vs resizing. |
| mp | COMBO | no | Use mixed precision |
| fpsopt | FLOAT | 24 | Input video fps. Not used in processing, the number is simply doubled and provided as output. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| fps | FLOAT | — |