Face: Detect Lite (YuNet GPU)
Find the Face in 31 ms, With No MediaPipe Installed
- image
- landmarks_json
- bbox_json
- face_count
- face_mask
Detecting a face in ComfyUI is normally a fork in the road: YOLO detectors from the ADetailer lineage, or MediaPipe. YOLO means the Ultralytics dependency and its AGPL licence tail plus one memorably bad supply-chain incident where a poisoned release shipped a cryptominer through a detailing node pack. MediaPipe means Apache-2.0, which is why licence-clean projects keep swapping it in - it's Google's, it's permissive, and it's what the pack's own Face Detect node uses.
Face: Detect Lite (YuNet GPU) (JHPixelProFaceDetectLite) is the third option: YuNet, the tiny face detector that ships inside Kornia. No MediaPipe needed, no Ultralytics, GPU when you have one, CPU when you don't. About 31 ms on an RTX 5090 versus roughly 84 ms for MediaPipe on CPU, per the pack's own changelog.
What it gives you
Four outputs, and the shape of them is the interesting part:
landmarks_json - 5 points, in the same order as the pack's MediaPipe-based Face Detect node, so it drops straight into Facial Aligner.
bbox_json - boxes with the real YuNet confidence per face, not just the threshold you set. That's a real difference from the MediaPipe wrapper, which reports the threshold back at you.
face_count - how many faces.
face_mask - a box mask of the detected face. Convenient, and a box, not an outline.
Inputs
image, then mode: single_largest (biggest box per image) or multi_top_k (up to max_faces, ranked by box area). max_faces is ignored in single mode.
max_faces (1–10) - cap per image.
confidence_threshold (0.1–0.95, default 0.6) - the YuNet score gate. Raise it to kill false positives.
nms_threshold (0.1–0.9, default 0.3) - IoU above which overlapping detections merge.
detect_size (160–1024, default 640, step 32) - long side of the copy used for detection; never upscaled. And here's the counterintuitive bit: bigger is not better. Kornia's YuNet has stride-64 heads and 256 px anchors, so at very large detect sizes big faces can be split or misplaced and close-ups pick up false hits. 640 is right for portraits; raise it only for group shots with small faces.
Which detector should you actually use
The pack ships both, and the honest comparison is on the node's own docs page:
Lite wins on speed, needs no MediaPipe, gives you a face-box mask and a real confidence number. MediaPipe (Face Detect + Face Landmarks) wins when you need the 468-point mesh - i.e. actual warping/reshaping - or when faces are tilted and partly occluded, which is exactly where MediaPipe's landmarker earns its keep and where MediaPipe's own limitations in identity work don't matter, because neither of these nodes does identity.
If you're detecting faces in a batch to limit a later edit, or feeding an aligner, Lite is the better pick and there's no argument. If you're reshaping a nose, you need the mesh, and that's the other node.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt # the Python that runs ComfyUI
ComfyUI Manager: search ComfyUI-JH-PixelPro → Install → restart. Then Add Node → ComfyUI-JH-PixelPro → face. Deps: kornia>=0.7, mediapipe>=0.10.33, opencv-python-headless>=4.8, scipy>=1.10, PyTorch from ComfyUI. Nothing extra to pip install for this node specifically - the YuNet weights (~0.4 MB) come through Kornia's torch-hub cache on first run, so that first run does need network access.
Where people get burned
face_maskis a box. Feather it (Mask Edge Smoother) before using it as an edit mask, or your inpaint will show rectangular seams.- A pure black frame can produce a false detection. Not a bug in your workflow. Use a real image, or raise the threshold.
- Tiny inputs. Under 64 px the detector would crash, so the node pads with the image's mean colour for detection only. It won't error; it also won't be useful.
- Group shots. Raise
detect_sizemodestly andmax_faces; go too far and you start getting split boxes on the big faces. - Eye points differ slightly from the MediaPipe node - eye centres vs outer corners, roughly 10–20% of the eye distance apart. Irrelevant for alignment, relevant if you're doing something surgical with those coordinates.
For someone running a retouching batch, this is the node that makes the rest automatic: face mask for Auto Blemish, focus mask for Depth Lens Blur, box for a crop, landmarks for the aligner. It's the cheap, licence-clean detector that everything downstream in this pack quietly assumes exists.
Pack: Apache-2.0, JH (@jetthuangai), v1.10.0, 64 nodes, EN/VI docs with per-node benchmarks. In the Reddit corpus I could find no community discussion of this pack at all - the name returns one unrelated Chrome extension - which makes the changelog's timing claim ("~31 ms vs ~84 ms on the sample portrait") the only public benchmark you've got. Fine. It's a face detector; run it and watch the console time.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mode | COMBO | single_largest | single_largest returns the face with the largest box per image. multi_top_k returns up to max_faces ranked by box area. |
| max_faces | INT | 11–10 | Cap on faces per image. Ignored when mode = single_largest. |
| confidence_threshold | FLOAT | 0.600.1–0.95 | Minimum YuNet score. Raise to drop false positives. |
| nms_threshold | FLOAT | 0.300.1–0.9 | IoU above which overlapping detections are merged. |
| detect_size | INT | 640160–1024 | Long side of the copy used for detection (never upscaled). 640 is best for portraits; raise only for group shots with small faces (may give false hits on close-ups). |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| landmarks_json | STRING | — |
| bbox_json | STRING | — |
| face_count | INT | — |
| face_mask | MASK | — |