WildAi bae74a47e8 Round 19: the paste's last whole-clip transients are gone (measured attribution)
The owner's live profile on the 30 s clip (17 -> 32 -> ~52 GB) is now
attributed by measurement (a per-stage RAM sampler outside the tree:
psutil RSS/commit + StageBar marks, 128-frame CPU fixture, x6.07):

- the paste stage's gradual per-tick growth is the round-18 output
  buffer's lazy page commit (16 x 19.44 MB per 16-frame group) - the
  contract floor being paid, not a leak;
- the first stage's +15 GB is the caller-owned input IMAGE materializing
  into the working set as the detection loop reads it (dRSS +2.3 GB,
  dCommit +0 B on the raw-input run) - not pack-owned;
- the static audit found no whole-clip float32 copy of the input in the
  pack (the only advanced-indexing gather of the input is the
  max_clip_length-bounded :1132).

Two pack-owned O(N) items remained and are removed:

- FIX 1: the mixed-case faces np.stack gather (~611 MB owner-scale) is
  replaced by LazyFaceSource - the caller's face stack served per group
  (a view when contiguous, a group-sized copy when scattered) through a
  faces_provider seam mirroring frame_provider; the all-eligible
  pass-through gate keeps handing the raw stack.
- FIX 2: the fallback tail converts per gray group (_flush_fallback_group,
  the indexed write) - one group's stack + transient (<= 20 x 4.86 MB),
  independent of the fallback count, instead of a whole-fallback stack
  plus its ~10x conversion transient; the device-canvas and host tails
  keep their whole-stack form.

Gate: 6 failed, 580 passed, 16 skipped, 7 deselected - the 6 are the
owner's own asset/example edits, unchanged; 11 new pins (byte identity,
no-copy censuses, the cross-group boundary, the one-whole-clip-buffer
count).
2026-11-07 21:21:31 +03:00
2025-05-21 23:40:55 +03:00

ComfyUI-KEEP

ComfyUI-KEEP workflow preview

ComfyUI custom node pack for video face super-resolution — the KEEP algorithm (Kalman-Inspired Feature Propagation) on single images and on frame sequences.

Report Bug Request Feature

Stargazers Issues Forks


▷ About

KEEP (Kalman-Inspired FEaturE Propagation for Video Face Super-Resolution, ECCV 2024) restores faces in video frames with a Kalman-style propagation of the features along the time axis: the identity of a face stays stable over the whole sequence instead of being detected and synthesized again in every single frame.

This pack ports the algorithm to ComfyUI as three pure V3 nodes — load the model, restore an image, restore a sequence.

ComfyUI-KEEP example workflow

The shipped example workflow: a single image and a video sequence, both restored with KEEP.

❖ Highlights

  • Video-aware — the sequence node propagates the features over the frames (optical flow), so the faces stay consistent.
  • Any upscaler — connect any ComfyUI UPSCALE_MODEL for the background and a second one for the restored face patch.
  • Four detectors — RetinaFace (ResNet50 / MobileNet 0.25) and YOLOv5 (n / l).
  • Automatic weights — the checkpoints are downloaded on the first run and verified against their sha256.
  • Clean V3 — comfy_api.latest nodes only, no legacy mappings, no import-time installs, no sys.path hacks.

⟔ ▲ ⟓

▓ Nodes

Node What it does
❖ Load KEEP Models Loads the KEEP checkpoint, the face detector / parser and the optional upscalers into one model pack.
❖ KEEP Single Image Restores the faces of a single image.
❖ KEEP Image Sequence Restores the faces of a frame sequence with the optical-flow propagation.

❖ Load KEEP Models

Loads the KEEP checkpoint, the face detection / parsing models and the two optional upscale models. The result is the model pack that the other two nodes consume.

Node id: KEEP_ModelLoader · Output: keep_model_pack (KEEP_MODEL_PACK)

Inputs & Parameters
Parameter Default Description
model KEEP The checkpoint: KEEP (the general model) or Asian. The Asian checkpoint is not published upstream — see the weights section.
detection_model retinaface_resnet50 The face detector: retinaface_resnet50, retinaface_mobile0.25, YOLOv5l, YOLOv5n.
bg_upscale_model (optional) A UPSCALE_MODEL (from the core Load Upscale Model node) for the background of the image.
face_upscale_model (optional) A UPSCALE_MODEL for the restored face patch.

Note

The pack is loaded once and reused by every node of the workflow. It is moved to the GPU only while a node runs and released afterwards.

❖ KEEP Single Image

Restores and enhances the faces of a single image.

Node id: KEEP_FaceUpscaleImage · Input: image (IMAGE) · Output: IMAGE

Inputs & Parameters
Parameter Default Description
final_upscale_factor 1.0 (0.5 – 4.0, step 0.1) The final scale of the output image. If your background upscaler is 4× but you want a 2× result, set this to 2.0; for the original size set it to 1.0.
has_aligned_face false Check it when the input is an already aligned 512×512 face crop.
only_center_face true If several faces are detected, restore only the one closest to the center of the image.
draw_bounding_box false Draw a box around the detected face on the output image.

❖ KEEP Image Sequence

Restores the faces of a sequence of frames (the frames of a video, for example) — the path that uses the optical flow of KEEP.

Node id: KEEP_ProcessImageSequence · Input: images (IMAGE) · Output: processed_images (IMAGE)

Inputs & Parameters
Parameter Default Description
final_upscale_factor 1.0 (0.5 – 4.0, step 0.1) The final scale of the output frames.
has_aligned_frames false Check it when the input frames are already aligned 512×512 face crops.
only_center_face true If several faces are detected per frame, restore only the one closest to the center.
draw_bounding_box false Draw a box around the detected face on the output frames.
max_clip_length 20 (1 – 100) The number of frames the KEEP network processes in one batch — the knob for the VRAM usage of long sequences.

Tip

The optical flow is only needed for more than one frame — a single-frame run never touches the flow weights.

⟔ ▲ ⟓

▓ Node Reference

All nodes registered by this pack (V3 schema ids):

Node id Display name Category Purpose
KEEP_ModelLoader Load KEEP Models ComfyUI-KEEP Loads the KEEP checkpoint, the face helper and the optional upscalers into a model pack.
KEEP_FaceUpscaleImage KEEP Single Image ComfyUI-KEEP Restores the faces of a single image.
KEEP_ProcessImageSequence KEEP Image Sequence ComfyUI-KEEP Restores the faces of a frame sequence with the optical-flow propagation.

The node ids, the display names, the category, the socket types (IMAGE, KEEP_MODEL_PACK, UPSCALE_MODEL) and every widget (name, default, range and order) are compatibility guarantees: workflows saved with the V1 nodes keep working unchanged.

⟔ ▲ ⟓

▓ Weights

The pack downloads its checkpoints on the first run and verifies every file against the sha256 of the manifest (src/keep_model_configs.py). The provenance of every hash is recorded by tools/fetch_weight_hashes.py, which downloads each published checkpoint once and hashes it.

File Size SHA-256 Destination Notes
KEEP-b76feb75.pth 604.7 MiB b76feb75f3ed782f4e91eda85c03018241827bba8693532dc10351bab5052c1a models/keep_models/KEEP/KEEP-b76feb75.pth required
KEEP_Asian-4765ebe0.pth — — models/keep_models/KEEP/KEEP_Asian-4765ebe0.pth not published upstream (HTTP 404) — the file has to be placed manually
detection_Resnet50_Final.pth 104.4 MiB 6d1de9c2944f2ccddca5f5e010ea5ae64a39845a86311af6fdf30841b0a5a16d models/facedetection/detection_Resnet50_Final.pth required
detection_mobilenet0.25_Final.pth 1.7 MiB 2979b33ffafda5d74b6948cd7a5b9a7a62f62b949cef24e95fd15d2883a65220 models/facedetection/detection_mobilenet0.25_Final.pth required
yolov5n-face.pth 6.8 MiB d2bbfbe9f36cf1ec345dc69658d7209e5448a676d946f1bf7818ac50d4489357 models/facedetection/yolov5n-face.pth required
yolov5l-face.pth 178.3 MiB 1ba9d2125fda4d823df5152b9fc2903c59aa76c0d3771e02bcf13a56a282cf96 models/facedetection/yolov5l-face.pth required
parsing_parsenet.pth 81.4 MiB 3d558d8d0e42c20224f13cf5a29c79eba2d59913419f945545d8cf7b72920de2 models/facedetection/parsing_parsenet.pth required
gmflow_sintel-0c07dcb3.pth 17.9 MiB 0c07dcb35770464f38a5ff4de18c04177b242dc5de8cd2068adf46f3d4fe193a models/gmflow/gmflow_sintel-0c07dcb3.pth optional (defensive) — only used when the checkpoint has no flow weights

The on-disk layout is the one of the original pack: the KEEP checkpoints live in models/keep_models/KEEP/, the face detection / parsing weights in models/facedetection/, the optional GMFlow checkpoint in models/gmflow/. The upscaler models are not part of the pack — they come from the ComfyUI core Load Upscale Model node (models/upscale_models/).

Warning

The Asian checkpoint is not published upstream (the release URL answers HTTP 404), so it cannot be downloaded and has no verifiable hash. The Asian option of the model widget stays (it is part of the node contract), but selecting it raises an actionable error until the file is placed manually in models/keep_models/KEEP/KEEP_Asian-4765ebe0.pth. The default KEEP model is unaffected.

Note

The GMFlow checkpoint is defensive. The shipped KEEP checkpoint carries its own trained flow weights; the GMFlow file is only resolved when a loaded checkpoint provides no flownet.* weights at all.

⟔ ▲ ⟓

▓ Getting Started

Via ComfyUI Manager: Search ComfyUI-KEEP → Install.

Manual install:

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

Restart ComfyUI. The weights are downloaded automatically on the first run — no manual download step is needed.

Example workflows

Workflow What it shows
example_workflows/keep-workflow.json The shipped example: a single image (with two upscalers) and a video sequence.

Important

The shipped example needs the VideoHelperSuite pack. It uses the node types VHS_LoadVideo (reads the video) and VHS_VideoCombine (writes the restored video). VideoHelperSuite is an optional dependency of the example only — the pack itself does not import it, and the two other example nodes (and every node of this pack) work without it.

⟔ ▲ ⟓

▓ Tips & Best Practices

  • max_clip_length is the VRAM knob. Long sequences are processed in clips of max_clip_length frames; lower it (e.g. 8) on a small GPU, raise it (e.g. 50) when you have headroom.
  • final_upscale_factor is the final size. The upscaler models define their own factor (4×, 2×, …); this value scales the result afterwards — 1.0 keeps the upscaled size.
  • Aligned crops are faster and sharper. For an already aligned 512×512 face, set has_aligned_face / has_aligned_frames — the detection step is skipped.
  • only_center_face keeps the subject. With several faces in the frame, the one closest to the center is restored.
  • A failed node fails loudly. A missing weight or a broken dependency raises an error that names the file and the path — the pack never returns a silently empty image.

▓ Future work

  • A video node — a node that takes a video file, restores the faces of every frame with KEEP and writes the result back as a video. The pack deliberately ships no video code path (the vendored ffmpeg shim was removed — it installed ffmpeg-python at import time). Until such a node exists, feed the frames of a video into the KEEP Image Sequence node (e.g. with the Video Helper Suite nodes) and write them back there.

⟔ ▲ ⟓

▓ License

The node code of this pack is licensed under the Apache License 2.0 — see LICENSE.

Warning

The KEEP weights and the vendored KEEP code are non-commercial. The algorithm, its checkpoints and the vendored basicsr / facelib tree come from the KEEP project and are distributed under the S-Lab License 1.0, which permits redistribution and use for non-commercial purposes only. For a commercial use, contact the copyright holders (S-Lab). The node code of this pack carries no such restriction.

The full attribution — the S-Lab License 1.0, the Apache-2.0 diffusers compatibility classes and the Apache-2.0 GMFlow package — is in LICENSE-THIRD-PARTY.md.

⟔ ▲ ⟓

▓ Changelog

v2.0.0 — 2026-10-22

  • Migrated to the pure V3 API. All three nodes are comfy_api.latest nodes now; the legacy NODE_CLASS_MAPPINGS are gone. The node ids, the display names, the category, the socket types and every widget (name, default, range and order) are unchanged — old workflows keep working.
  • The vendored dependencies were repaired. The import-time pip install of the ffmpeg shim is gone, the broken stubs that silently disabled the KEEP architecture were deleted (a broken dependency now fails loudly instead of producing garbage), and the tree was pruned to the modules the pack really uses.
  • The weights are downloaded from a manifest and verified. Every checkpoint has a URL, a sha256 and a destination in src/keep_model_configs.py; the downloader verifies the hash, re-downloads a corrupted file once and never leaves a partial file behind. The Asian checkpoint (not published upstream) is reported as such instead of failing with a download error.
  • The optical flow of the sequence path is wired. The flownet is restored from the checkpoint when it carries flownet.* weights, and resolved from the optional GMFlow checkpoint when it does not.
  • The failures are actionable. A missing weight names the file, the path and the URL; a foreign model pack is refused with a message; a failed processing raises instead of returning an empty image.
  • The documentation and the examples were rewritten. This README (node table, weights table, license notice, changelog), the third-party license file and two validated example workflows.

Before v2.0.0

  • 2025-07-03 — Standard ComfyUI Upscale Model inputs instead of a hardcoded Real-ESRGAN; added final_upscale_factor for precise output scaling.
  • 2025-05-20 — Initial commit.

⟔ ▲ ⟓

▓ Acknowledgments

  • Ruicheng Feng, Chongyi Li and Chen Change Loy — KEEP (paper) — the algorithm and the checkpoints
  • S-Lab — the S-Lab License 1.0 of the KEEP lineage
  • The HuggingFace team — diffusers (Apache-2.0), the two compatibility classes the pack vendors
  • Haofei Xu et al. — GMFlow (paper) (Apache-2.0), the optical flow
  • The VideoHelperSuite team — ComfyUI-VideoHelperSuite, the video nodes of the shipped example
  • The ComfyUI team — for the platform

Citation for the original KEEP

If you use the core KEEP algorithm or models in your research, please cite the original paper:

@InProceedings{feng2024keep,
      title     = {Kalman-Inspired FEaturE Propagation for Video Face Super-Resolution},
      author    = {Feng, Ruicheng and Li, Chongyi and Loy, Chen Change},
      booktitle = {European Conference on Computer Vision (ECCV)},
      year      = {2024}
}

⟔ ▲ ⟓

══════════════════════════════════

S
Description
No description provided
Readme Apache-2.0
45 MiB
Languages
Python 95.4%
Cuda 2.8%
C++ 1.8%