FaceDetailer
The one-node fix for mangled faces in ComfyUI
- image
- model
- clip
- vae
- positive
- negative
- bbox_detector
- sam_model_opt
- segm_detector_opt
- detailer_hook
- scheduler_func_opt
- image
- cropped_refined
- cropped_enhanced_alpha
- mask
- detailer_pipe
- cnet_images
If a face comes out as a smeared blob because it's tiny in the frame, FaceDetailer is the node that fixes it. It's the famous entry point to ltdrdata's Impact Pack, and it's ComfyUI's answer to A1111's ADetailer: one node that detects a face, re-renders it at a proper resolution, and pastes it back - no manual masking.
The problem it solves is structural, not a checkpoint defect. A face occupying 80×80 pixels of a 1024×1024 render gets 80×80 pixels' worth of the model's attention, so it comes out mush no matter how good your model is. Cranking resolution won't save it. The only real fix is to give that region its own generation pass at full budget, which is exactly what this does: detect, crop, resample, composite back. Same idea as ADetailer; more knobs, more setup. It's fiddlier than A1111's single checkbox, and people say so - but once it's wired, it's the reliable way to fix faces (and hands, and eyes) inside a graph.
How it works
FaceDetailer chains a detector and a detailer into one node. A bbox detector finds faces and boxes them. Each box is cropped out, scaled up toward your guide_size, and run through a fresh sampling pass - a little img2img using the model, clip, vae, and prompts you feed in - then stitched back onto the original. Optionally a SAM model or a segm detector refines the box into a tighter mask first, so the seams follow the face outline instead of a rectangle.
The catch that trips up every beginner: the node does not ship a detector. The bbox_detector input is required, and you have to feed it from a detector-provider node. The usual one is UltralyticsDetectorProvider loading a YOLO face model - and since v8.0 that provider lives in the separately-installed Impact Subpack, not the base pack. No Subpack, no detector, nothing to detect with.
The inputs and outputs that matter
There are a lot of inputs. Most you leave alone. The handful that actually decide your result:
bbox_detector(required) - the detector that finds the faces. Feed it from a provider node (see above). Without it the node can't run.model/clip/vae/positive/negative- same stack you used for the main image. Match them, or the fixed face won't match the body.denoise(default 0.5) - the single most important dial. High values give you a new face that ignores the original; drop it to roughly 0.35–0.45 so you refine rather than replace. This is the number people get wrong.guide_size(default 512) - the size the cropped face is scaled to before re-rendering. 512 suits SD 1.5; bump it up for SDXL/Flux where the model wants ~1024.wildcard- an optional face-only prompt applied to the detail pass, handy for "detailed eyes, sharp skin texture" without touching the main prompt.
Optional inputs let you attach a SAM model (sam_model_opt) or a segm detector (segm_detector_opt) for cleaner masks.
Six outputs. The one you want is image - the full picture with the face fixed. mask shows you where it worked. cropped_refined is a list of the enhanced crops for inspection, and detailer_pipe bundles the whole setup to chain into a second pass (FaceDetailer (pipe)) for a 2-pass fix on a badly damaged face.
How to install it
Install the pack via ComfyUI Manager (search ComfyUI Impact Pack, install, restart), or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ltdrdata/ComfyUI-Impact-Pack comfyui-impact-pack
cd comfyui-impact-pack
python -m pip install -r requirements.txt # ComfyUI's python; python_embeded on portable
then restart. Then install the Subpack too (ComfyUI-Impact-Subpack) so you have UltralyticsDetectorProvider and its YOLO models - the base pack no longer bundles it.
Common issues & troubleshooting
Nothing happens / "bbox_detector" has no input. This is the number-one snag. You need a detector provider (UltralyticsDetectorProvider, from the Subpack) wired into bbox_detector. Install the Subpack, grab a bbox/face_yolov8m.pt-style model, and connect it.
Weird empty widgets like guide_size_for, noise_mask, force_inpaint. These are just booleans on the node - you don't need external nodes for them. If they showed up as dangling inputs, someone converted the widgets to inputs; right-click and convert them back to widgets.
The fixed face doesn't match the body. Denoise is too high, or your VAE/model differs from the main gen. Lower denoise toward 0.35, and confirm the same model/vae feed both.
The face is already big and sharp. Then skip it. A second pass on an adequately-resolved face changes it without improving it - the most-upvoted reaction to a detailing demo was that the two versions looked identical. FaceDetailer is for small faces, not every face.
Inputs (39)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model | MODEL | If the `ImpactDummyInput` is connected to the model, the inference stage is skipped. | |
| clip | CLIP | — | |
| vae | VAE | — | |
| guide_size | FLOAT | 51264–16384 | — |
| guide_size_for | BOOLEAN | true | — |
| max_size | FLOAT | 102464–16384 | — |
| 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 | 17 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +11 | |
| 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 | — |
| 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 | — | |
| tiled_encodeopt | BOOLEAN | false | — |
| tiled_decodeopt | BOOLEAN | false | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| cropped_refined | IMAGE | — |
| cropped_enhanced_alpha | IMAGE | — |
| mask | MASK | — |
| detailer_pipe | DETAILER_PIPE | — |
| cnet_images | IMAGE | — |