CMK Face Select
Two Faces in the Frame? CMK Face Select Decides Who Gets Swapped
- image
- image
- selected_face
- diagnostic
The most frustrating face-swap failure isn't a bad blend or a seam. It's a technically perfect swap of the wrong person. CMK Face Select exists to make that decision explicit and visible instead of leaving it to a dropdown buried two nodes downstream.
What it actually does
It runs an InsightFace detector over the image, keeps the whole face set, then picks one face by a rule you choose. That pick gets packaged as a CMK_SELECTED_FACE - a dictionary carrying the bounding box, the five landmarks, the detection score and the ArcFace embedding, not just a crop. That's the important part: the downstream swap doesn't have to re-detect anything, it inherits your decision.
The selection rules are all bounding-box arithmetic, which is why they behave predictably:
- Largest wins on box area. This is the right default for a portrait.
- Leftmost / Rightmost / Topmost / Bottommost compare the box centre on that axis.
- Center picks whichever face is nearest the middle of the frame.
No magic, no "the important one". If you have four people in frame and you want the second from the left, this node cannot know that - for that case you want a detector-plus-index workflow, or you accept Largest and check the preview before you commit.
One thing worth knowing before you build around it: only the first frame of a batch is examined. Feed it a 40-frame tensor and it makes one decision from frame 0. That's normally what you want for a video (pick the target once, track it after), but it's not doing per-frame selection.
The inputs that matter
detector_model is a dropdown built from the folders under ComfyUI/models/insightface/models. If only buffalo_l is there, that's your list - the buffer models (buffalo_l is the standard one) are what the resource checker installs.
detector_size defaults to 640 and ranges 128–1280 in steps of 64. This is the resolution the detector runs at, not the resolution of your image. Crank it up when faces are small in frame and getting missed; drop it when you're doing a hundred of these and care about speed.
selection is the rule above. image is the picture to look at.
Outputs and where they go
selected_face is the one that matters - wire it into opt_selected_target_face or opt_selected_source_face on CMK FaceSwap Image. When you connect it, the swap node skips its own detection entirely and reports the source of the decision as "Input" in its log, so you can confirm the hand-off happened.
image comes back as your input frame with the chosen box and landmarks drawn on it. Cheap sanity check; drop a preview on it for the first run and you'll never guess again. diagnostic is the CMK diagnostic payload - summary text plus the marked preview - for the pack's visualizer.
Zero faces does not crash the node. You get a payload with selected_index of -1 and a "no face detected" warning, plus the count in the diagnostic. Treat that as your cue to raise detector_size or fix the input rather than pushing ahead.
Installing it
Via ComfyUI Manager: search CMK Flow, install the CMKFlow entry, restart. Manually, from your ComfyUI root:
git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
That helper finds your actual ComfyUI Python environment (Desktop installs often have several) and finishes with CMK dependency check: OK. Then pull the weights - they are deliberately not part of the Python package:
python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/ComfyUI-Shared"
buffalo_l is one of the resources that script can install for you, and it unpacks into the InsightFace model folder where this node's dropdown expects it. Note the one hard requirement people miss: this pack needs ComfyUI's Nodes 2.0 / Vue setting on, or dynamic nodes fall back to the old renderer.
Where people get burned
InsightFace is the classic pain point of this whole corner of the ecosystem - it spent years needing a C++ toolchain, and its 1.0 PyPI release only landed in May 2026. If install_cmk_requirements.py fails, it's almost always that, not CMK.
Second: this pack's swap and detection inference defaults to ONNX Runtime's CPU provider. Detection on one image is fine. Detection on a video is not, so don't design a 3000-frame pipeline around per-frame detection. For a hard problem, detect once here and let the video node track the result.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| detector_model | COMBO | 1 options: buffalo_l | |
| detector_size | INT | 640128–1280 | — |
| selection | COMBO | Largest | 6 options: Largest, Leftmost, Rightmost, Topmost, Bottommost, Center |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| selected_face | CMK_SELECTED_FACE | — |
| diagnostic | CMK_DIAGNOSTIC | — |