Face Detailer (Max Faces)
The crowd-of-clones fix
- image
- model
- clip
- vae
- positive
- negative
- bbox_detector
- sam_model_opt
- segm_detector_opt
- detailer_hook
- scheduler_func_opt
- edit_model
- face_reference
- face_reference_b
- nag_negative
- nag_ref_boost_mask
- image
- cropped_refined
- cropped_enhanced_alpha
- mask
- detailer_pipe
- cnet_images
Every face detailer does the same four things: detect, crop, re-render at a sane resolution, paste back. The whole category is automatic inpainting, and it exists because a face occupying 70 pixels of a 1024 frame has no latent budget and comes out as a smear no matter how good the checkpoint is.
Impact Pack's FaceDetailer owns this loop in ComfyUI, and it works. It also has two long-standing annoyances: two dozen inputs, and the clone problem - every detected region re-renders on the same seed, so a crowd of twelve people comes back as a room of the same person. Donut's DonutFaceDetailer is a fork that keeps the Impact machinery and changes the parts people complain about. Crucially, it still is Impact Pack underneath - it imports impact.core and friends at execution time, and raises a clear error if the pack is missing rather than quietly disappearing from the node list.
What's different
Three things, and they're the reason to pick it over stock FaceDetailer:
max_faces. Detection returns everything the YOLO found, including the blurry strangers in the background. This node filters to segments with a non-empty mask, sorts them by bounding-box area, and keeps only the top max_faces - largest first, default 2. max_faces: 1 is the single-portrait case; raise it when you actually have a group shot and know how many faces are in it.
Megapixel sizing. resolution is an equivalent square target, not an edge length: the crop is scaled to hit that total pixel count with its aspect preserved, then the canvas is snapped to 64-pixel multiples. max_resolution caps the long edge (0 = no cap). This is more predictable VRAM-wise than edge-based guide sizing, which is what the docstring says it's for.
Edit mode and NAG. With edit_mode on, each detected face gets Krea 2 identity-edit conditioning instead of a plain img2img pass; face_reference supplies the identity, face_reference_b swaps to extracting from a second subject image, and vary_seed_per_face gives each face its own seed offset. NAG - a ComfyUI extension that restores negative prompting on guidance-distilled models by intervening in attention - is available through the nag_* inputs and needs the separate krea2-nag pack installed.
Inputs that matter
Wire image, model, clip, vae, positive, negative, and bbox_detector (an UltralyticsDetectorProvider from Impact Subpack). Then:
resolution- 1024 default. For a face crop, that's generous; 768 is fine for most work.denoise- 0.5 default. This is the dial that decides "sharpen" versus "new face." 0.3–0.4 if the face was already decent.max_faces- as above.bbox_threshold- 0.5. Raise it if the detector is chasing faces in clouds.bbox_crop_factor- 3.0, how much context around the box goes into the crop. More context means a more coherent re-render and a more visible seam.feather(5) and, in the optional group,noise_mask_feather(20) - the seam dials.guide_size_for,cycle,drop_size,sampler_name/scheduler/steps/cfg/seed- inherited Impact semantics;cycleruns multiple refinement rounds, and the implementation keeps intermediate rounds in latent space, decoding once at the end.
Optional extras worth knowing: sam_model_opt and segm_detector_opt refine the bbox into a polygon (fewer rectangular seams), detailer_hook, inpaint_model, scheduler_func_opt, wildcard, turbo_mode, and the nag_* family.
Outputs
image is the recomposited full frame - that's the one you chain onward. cropped_refined and cropped_enhanced_alpha are lists of the individual processed crops (the alpha version has the paste mask baked in), mask is the combined detection mask, detailer_pipe feeds other Impact nodes, and cnet_images is Impact's ControlNet-compatible crop list. Most workflows only use image.
Install
ComfyUI Manager, search DonutNodes, or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
You also need ComfyUI Impact Pack and Impact Subpack, and the detector weights: face_yolov8m.pt into models/ultralytics/bbox/, plus sam_vit_b_01ec64.pth in models/sams/ if you use the SAM path. Those are the same Bingsu/adetailer YOLO weights A1111's ADetailer uses - nothing exotic, but nothing bundled either.
Troubleshooting
"DonutFaceDetailer requires a working ComfyUI Impact Pack." That's the execution-time import check firing. Repair Impact Pack through Manager and restart.
"DonutFaceDetailer found no face in face_reference." Edit mode is on and the detector couldn't find a face in your identity image. Use a clear, front-facing shot; bbox_threshold down if it's a hard one.
Clones. If you have more than one face in frame and they're converging, turn on vary_seed_per_face, or prompt for distinct faces before the pass.
Rectangular seams. Swap the bbox path for a segmentation detector and raise noise_mask_feather.
Order of operations. Detail at native resolution, then upscale. Doing it the other way bakes the mangled face into more pixels and then costs you more to fix.
One last thing, straight from the Impact Pack's history: the Ultralytics package that powers every YOLO detector in this pipeline is AGPL-3.0 and had a poisoned release in December 2024 that shipped a cryptominer to ComfyUI users through exactly this style of node. Pin your version.
Inputs (58)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model | MODEL | — | |
| clip | CLIP | — | |
| vae | VAE | — | |
| resolution | INT | 1024256–4096 | Equivalent square target size. Sampling canvases are snapped to 64-pixel multiples. |
| max_resolution | INT | 00–4096 | Maximum edge length (0 = no limit). |
| guide_size_for | BOOLEAN | true | — |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 201–10000 | — |
| cfg | FLOAT | 8.000–100 | — |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| denoise | FLOAT | 0.500.0001–1 | — |
| feather | INT | 50–100 | — |
| noise_mask | BOOLEAN | true | — |
| force_inpaint | BOOLEAN | true | — |
| bbox_threshold | FLOAT | 0.500–1 | — |
| bbox_dilation | INT | 10-512–512 | — |
| bbox_crop_factor | FLOAT | 3.01–10 | — |
| sam_detection_hint | COMBO | 9 options: center-1, horizontal-2, vertical-2, rect-4, diamond-4, mask-area, +3 | |
| sam_dilation | INT | 0-512–512 | — |
| sam_threshold | FLOAT | 0.930–1 | — |
| sam_bbox_expansion | INT | 00–1000 | — |
| sam_mask_hint_threshold | FLOAT | 0.700–1 | — |
| sam_mask_hint_use_negative | COMBO | 3 options: False, Small, Outter | |
| drop_size | INT | 101–16384 | — |
| bbox_detector | BBOX_DETECTOR | — | |
| wildcard | STRING | — | |
| cycle | INT | 11–10 | — |
| max_faces | INT | 21–20 | Maximum number of faces to process (largest by area) |
| sam_model_optopt | SAM_MODEL | — | |
| segm_detector_optopt | SEGM_DETECTOR | — | |
| detailer_hookopt | DETAILER_HOOK | — | |
| inpaint_modelopt | BOOLEAN | false | — |
| noise_mask_featheropt | INT | 200–100 | — |
| scheduler_func_optopt | SCHEDULER_FUNC | — | |
| edit_modeopt | BOOLEAN | false | Use Krea2 identity edit conditioning for each detected face. |
| edit_promptopt | STRING | — | |
| edit_modelopt | MODEL | Optional Krea2 model with the Identity Edit LoRA already applied. Falls back to model. | |
| face_referenceopt | IMAGE | Required in edit mode. The bbox detector extracts the identity face from this image. | |
| edit_negative_promptopt | STRING | — | |
| grounding_pxopt | INT | 7680–4096 | — |
| vary_seed_per_faceopt | BOOLEAN | false | Use a unique seed offset for each detected face. |
| turbo_modeopt | BOOLEAN | false | Snap denoise to a valid Turbo scheduler point. |
| face_reference_bopt | IMAGE | Optional subject/identity image for two-reference edits. When connected, faces are extracted from this image instead of the scene in face_reference. | |
| nag_enabledopt | BOOLEAN | false | Apply Krea2 NAG inside sampling (requires krea2-nag). Uses CFG 1; Turbo negative conditioning stays zeroed. |
| nag_negativeopt | CONDITIONING | Unzeroed negative prompt for NAG. Defaults to edit_negative_prompt in edit mode, otherwise negative. | |
| nag_phiopt | FLOAT | 4.00–20 | — |
| nag_tauopt | FLOAT | 2.500.01–20 | — |
| nag_alphaopt | FLOAT | 0.250–1 | — |
| nag_sigma_startopt | FLOAT | 1000.00–1000 | — |
| nag_sigma_endopt | FLOAT | 0.00–1000 | — |
| nag_ref_boostopt | FLOAT | 1.000–1000 | — |
| nag_ref_boost_aopt | FLOAT | 1.000–1000 | — |
| nag_fit_modeopt | COMBO | fit | 2 options: fit, crop (legacy) |
| nag_ref_boost_maskopt | MASK | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| cropped_refined | IMAGE | — |
| cropped_enhanced_alpha | IMAGE | — |
| mask | MASK | — |
| detailer_pipe | DETAILER_PIPE | — |
| cnet_images | IMAGE | — |