Temporal Flow Average
Motion-compensated temporal averaging for AI video
- images
- clean
- weight_map
You've seen it a hundred times: a Seedance or Kling clip that's gorgeous for 95% of its runtime, then a single frame pops with a color spike, or the whole thing shimmers with chroma flicker. Topaz and upscalers won't touch it, because the noise is temporal - it lives in the differences between frames, not inside any one frame. Temporal Flow Average is the heart of the FlowDenoise pack: it turns a noisy AI clip into a clean reference for everything downstream.
What it actually does
It builds a "clean" version of your clip with the classic compositor's trick: frame blending with motion compensation. Instead of naively averaging neighbors (which turns motion into smears), it estimates the optical flow - which pixel moved where - warps each neighbor to match the current frame, then averages only the matching pixels. Frames further back weigh less, so the current frame stays dominant.
Three mechanisms keep the average from destroying your image:
- Outlier rejection - after warping, a per-pixel color-similarity check (
color_threshold) down-weights pixels that don't match the reference. This is the anti-ghosting mechanism. - Occlusion detection - a forward-backward consistency check keeps pixels revealed or covered by motion from polluting the average.
- Scene detection - a vectorized per-pair MSE scan finds cut boundaries and refuses to average across them.
The flow comes from MEMFOF (the default - a strong 2025 optical-flow model) or RAFT (raft_small / raft_large, both inside torchvision, no download needed). MEMFOF's weights auto-download from HuggingFace on first use.
The inputs that matter
You can tune all ten; these are the ones a beginner actually sets:
window_size- how many frames to average on each side (total window = 2n+1). Default 2 means five frames; 2–3 is the sweet spot for AI video.weight_decay- exponential falloff per frame distance; lower = more aggressive averaging. 0.7–0.8 for flicker, toward 0.6 for heavy grain removal.flow_model+flow_iterations- keepmemfof(8 iterations is right); if you switch to RAFT, bump iterations to ~20.color_threshold- lower = stricter outlier rejection; this is your ghosting dial. The default 0.04 is fine, but see troubleshooting.batch_size- MEMFOF processes frames in chunks on the GPU. Higher = faster but more VRAM (the README suggests 8–16 on a 32GB RTX 5090 at 720p).precision/flow_scale- the speed knobs.bf16is 1.5–2× faster on RTX 30/40/50 with negligible quality cost;flow_scale 0.5computes flow at half res (~3× faster) while warping stays full-res. If it's slow, these are the time-savers.output_weight_map- leave it off - it allocates a full-size per-pixel tensor, tens of gigabytes of CPU RAM on long clips. The pack gated it off by default after exactly that OOM regression.
Outputs
clean- the temporally averaged frames. The money output.weight_map- the per-pixel confidence map, or a 1×1×1×3 placeholder whenoutput_weight_mapis off, so downstream connections stay valid.
You rarely use clean directly. The standard pipeline is VHS_LoadVideo → TemporalFlowAverage → SelectiveDenoise: clean frames feed Selective Denoise's clean input while the original video stays as original - that's how you keep detail. Wire a copy of clean into Extract Noise to see what's being removed.
Installing it
Via ComfyUI Manager, search "ComfyUI-FlowDenoise" and install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/AIMZ-GFX/ComfyUI-FlowDenoise.git
then restart. One dependency gotcha: memfof is not on PyPI, so pip install memfof fails with "Could not find a version" - the author has had to answer exactly this in his release thread. Use the GitHub URL:
pip install git+https://github.com/msu-video-group/memfof.git
Portable installs need the embedded Python: python_embeded\python.exe -m pip install git+.... Manager's requirements.txt / install.py handle it automatically. You'll also want Video Helper Suite, since the shipped workflow uses VHS_LoadVideo / VHS_VideoCombine.
Troubleshooting
pip install memfoffails - you need thegit+URL above; plainpip install memfofnever works.- Ghosting on moving subjects - the most-reported complaint on the pack's launch thread; lowering
color_thresholdhelps but doesn't fully eliminate it, and the author is working on it. A smallerwindow_sizeand lowerweight_decayreduce the smearing meanwhile. - Flicker still visible after one pass - real users report needing two passes to fully kill visible flicker. The noise visualization still shows residue after it looks clean to the eye.
- Long clips eating RAM - that's what
output_weight_mapgating and vectorized scene detection fixed. ADefaultCPUAllocatorOOM on long clips means you're on an old version; update. - BF16 issues on older GPUs -
bf16assumes an RTX 30/40/50-class card. If yours predates that, switchprecisiontofp32.
The name undersells it: this isn't just a denoiser, it's the reference-frame generator that makes the rest of the pack controllable. Get it right here and Selective Denoise becomes a simple dial.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| window_size | INT | 21–15 | Number of neighboring frames in each direction to average |
| weight_decay | FLOAT | 0.800–1 | Exponential decay per frame distance (1.0 = equal weight) |
| flow_model | COMBO | memfof | Optical flow model (memfof=SOTA 2025, most accurate) |
| flow_iterations | INT | 81–32 | Refinement iterations (memfof: 8 is good, raft: 20 recommended) |
| color_threshold | FLOAT | 0.0400.005–0.5 | Color similarity threshold (lower=stricter, rejects ghosting artifacts) |
| scene_threshold | FLOAT | 0.0600.001–0.5 | Scene change detection threshold (frame MSE above this = cut boundary, skip averaging) |
| batch_size | INT | 11–64 | MEMFOF batch size (higher=faster but more VRAM. RTX 5090 32GB 720p: 8~16 recommended) |
| precision | COMBO | bf16 | Inference precision. bf16 is ~1.5-2x faster on RTX 30/40/50 series with negligible quality difference. Use fp32 for strict reproducibility. |
| flow_scale | FLOAT | 1.00.3–1 | Compute optical flow at reduced resolution for speed. 1.0=full resolution (best quality), 0.5~3x faster. Warping still uses full resolution. |
| output_weight_mapopt | BOOLEAN | false | Return a per-pixel weight visualization as the second output. Costs a full-size (B×H×W×3) tensor of extra RAM at the end of the run — keep off unless a downstream node actually consumes it. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| clean | IMAGE | — |
| weight_map | IMAGE | — |