Nodes/CMK Flow/CMK FaceProcess
ComfyUI Node

CMK FaceProcess

The standalone face pass, full of ReActor DNA and one very confusing number

By CMKFlow·Created 3 months ago·Updated 2 days ago· 6
CMK FaceProcess
  • image
  • face_pipe
  • image
  • image_proceed
  • segs_detected
  • segs_processed
  • log_pipe
  • enabled
  • diagnostic
◄boolean_faceprocess_enabletrue►
◄enabletrue►
◄process_modeRestore►
◄refine_modeOff►
◄detect_model▾►
◄detect_bbox_threshold0.50►
◄detect_bbox_dilation0►
◄detect_crop_factor3.0►
◄detect_drop_size10►
◄restore_model▾►
◄restore_facedetection▾►
◄restore_visibility1.00►
◄restore_codeformer_weight0.50►
◄select_face_selectionall►
◄select_sort_byarea►
◄select_reverse_orderfalse►
◄select_take_start0►
◄select_take_count1►
◄detail_guide_size512►
◄detail_guide_size_fortrue►
◄detail_max_size768►
◄detail_denoise80►
◄detail_noise_masktrue►
◄detail_force_inpainttrue►
◄detail_paste_feather20►

CMK FaceProcess is the toolbox version of the pack's face module: one node, everything on it, no pipes. It does two jobs - restore faces with a learned network, or re-detail them with a diffusion pass - and it inherits a set of controls from ReActor, the face-swap extension, which is how you can tell where the code came from.

What it does

face_pipe is an optional * input (the pack's own pipe type is accepted, but so is anything); image is what gets processed. There's a global enable and a local enable, both AND-ed before anything runs, and a process_mode of Off, Restore or Detailer.

Alongside those sit three families of controls.

Detection - detect_model from models/ultralytics/bbox and segm, pre-sorted so face-ish names float to the top, with a default preference for bbox/face/face_yolov8n.pt. Then detect_bbox_threshold (0.5), detect_bbox_dilation (0, and it can go negative), detect_crop_factor (3.0, how much surrounding context the crop keeps) and detect_drop_size (10, regions smaller than this are ignored).

Select - the ReActor block: select_face_selection (all / filter / largest), select_sort_by (area, x_position, y_position, detection_confidence), select_reverse_order, select_take_start, select_take_count. This is how you say "the second-largest face, from the right."

Restore - restore_model from models/facerestore_models (none plus whatever you have; the backend is picked by filename - gfpgan in the name gets you GFPGAN, codeformer gets CodeFormer, otherwise GPEN), restore_visibility (1.0, a straight blend between original and restored), and two knobs that came with the ReActor code and don't do anything here: restore_facedetection and restore_codeformer_weight. The adapter deletes both before use - face sets always come from InsightFace, and the CodeFormer weight never reaches the network.

Detail - detail_guide_size (512), detail_guide_size_for (on: measure against the detected box), detail_max_size (768), detail_noise_mask, detail_force_inpaint, detail_paste_feather (20) and detail_denoise.

The one number that will trip you up

detail_denoise defaults to 80 and ranges 50–100, and it is an entry percentage, not a denoise value. The code converts it: anything above 1.0 becomes (100 - value) / 100. So 80 means denoise 0.20 - a light touch that preserves most of the original face - and 50 means denoise 0.50. The tooltip spells this out ("Later entry preserves the original face; earlier entry rebuilds it more strongly"), and it's still the thing people get wrong, because every other detailer in ComfyUI uses 0–1 the other way round.

The mechanism, both modes

Restore runs InsightFace's analyser to find faces, aligns each one with face_align.norm_crop2, runs the enhancer on the aligned crop, pastes it back with a feather of 8, and blends by restore_visibility. It's the standard detect-align-enhance-paste loop.

Detailer is the re-render loop: each detected region gets cropped, resized so the guide basis reaches detail_guide_size (capped by detail_max_size), VAE-encoded, sampled with a noise mask at your denoise, decoded, resized back and pasted with detail_paste_feather. Seeds are your seed plus the region index, so it's reproducible.

refine_mode is a third, separate stage: Detail, Sharpen or Smooth at a fixed strength of 0.65, applied to the whole frame through the detected masks at 0.75 alpha. It's a native pixel pass, not a model pass - cheap, and it can absolutely hide the improvements you were trying to evaluate if you leave it on.

Outputs are image, image_proceed, segs_detected, segs_processed, log_pipe, enabled and diagnostic. image_proceed and enabled are the ones to wire if you want the rest of your workflow to know whether a face pass actually happened.

Install

Manager: search CMK Flow, install the CMKFlow entry, restart. Manually, from the directory with main.py:

git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py

CMK dependency check: OK means the Python side is done - and unlike most detailer packs, you don't need the Impact Pack, because CMK ships its own SEGS, detector wrapper and SAM loader. You do need the heavy shared dependencies: ultralytics, insightface, onnxruntime, segment-anything, opencv-python, imageio-ffmpeg, nudenet==3.4.2. Restore mode adds a hard requirement on insightface plus its buffalo_l pack, and restore networks under models/facerestore_models. The resource checker audits the filenames the bundled workflows want:

python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/shared/models"

CMK Flow is a single-author GPL-3.0 project by Carsten Kirschner, open-sourced in July 2026 with a very small community footprint, so the source is your best documentation. Turn on Vue Nodes / Nodes 2.0; CMK's dynamic nodes need it.

Issues worth knowing

Disabled is a true pass-through: with the enables off, the node doesn't even load the guard or the detectors, and returns the image unchanged. That's good for speed and slightly bad for debugging - nothing fails, nothing happens.

If restore mode throws, it's insightface or its weights, nearly every time. And remember the licensing shape of that dependency: the library is MIT, the pretrained models aren't.

CategoryCMK/Toolbox/Face

Inputs (27)

NameTypeDefaultDescription
imageoptIMAGE—
face_pipeopt*—
boolean_faceprocess_enableoptBOOLEANtrue—
enableoptBOOLEANtrue—
process_modeoptCOMBORestore3 options: Off, Restore, Detailer
refine_modeoptCOMBOOff4 options: Off, Detail, Sharpen, Smooth
detect_modeloptCOMBO1 options: none
detect_bbox_thresholdoptFLOAT0.500–1—
detect_bbox_dilationoptINT0-512–512—
detect_crop_factoroptFLOAT3.01–100—
detect_drop_sizeoptINT101–8192—
restore_modeloptCOMBO1 options: none
restore_facedetectionoptCOMBO4 options: retinaface_resnet50, retinaface_mobile0.25, YOLOv5l, YOLOv5n
restore_visibilityoptFLOAT1.000–1—
restore_codeformer_weightoptFLOAT0.500–1—
select_face_selectionoptCOMBOall3 options: all, filter, largest
select_sort_byoptCOMBOarea4 options: area, x_position, y_position, detection_confidence
select_reverse_orderoptBOOLEANfalse—
select_take_startoptINT00–100—
select_take_countoptINT11–100—
detail_guide_sizeoptFLOAT51264–8192—
detail_guide_size_foroptBOOLEANtrue—
detail_max_sizeoptFLOAT76864–8192—
detail_denoiseoptFLOAT8050–100Sampling entry in percent. Later entry preserves the original face; earlier entry rebuilds it more strongly.
detail_noise_maskoptBOOLEANtrue—
detail_force_inpaintoptBOOLEANtrue—
detail_paste_featheroptINT200–200—

Outputs (7)

NameTypeDescription
imageIMAGE—
image_proceedIMAGE—
segs_detectedSEGS—
segs_processedSEGS—
log_pipeSTRING—
enabledBOOLEAN—
diagnosticCMK_DIAGNOSTIC—