Forbidden Vision 🎯 Fixer
The one-node fix for ruined faces in ComfyUI
- model
- vae
- positive
- negative
- image
- latent
- clip
- final_image
- processed_face
- side_by_side_comparison
- final_mask
The Fixer is the flagship of the Forbidden Vision pack, and it exists because a face that takes up 60×60 pixels of a 1024×1024 render is doomed. That tiny region has almost no latent budget, so it comes out melted no matter how good your checkpoint is. The fix has never been "generate better" - it's "give that region its own pass." ADetailer did this in A1111 with a checkbox; Impact Pack's FaceDetailer does it in ComfyUI with two dozen inputs you're expected to configure yourself. Forbidden Vision's Fixer is the "modern replacement" for both, and it's the closest ComfyUI has come to ADetailer's one-tap ergonomics.
How it works
Two custom models trained from scratch by the pack author do the heavy lifting: a YOLO11 detector finds faces, and a Unet++-style segmentation model traces each one as a mask that includes eyebrows, eyelashes, facial hair, even sunglasses - the details that make the inpaint look natural rather than a skin-colored oval slapped on. On import the pack downloads those from HuggingFace into ComfyUI/models/forbidden_vision automatically. The node then crops each detected face, upscales small ones, runs a fresh inpainting pass at processing_resolution (default 1024), and composites the result back with differential diffusion, color correction, and feathered blending so the patched region matches the original image's lighting and style.
The inputs that matter
You feed it the usual model, vae, positive, and negative conditioning, plus an image or latent. clip is optional - but it's required the moment you use the face prompt fields. The three you'll actually touch:
denoise_strength(default 0.4) - the whole personality of the pass. 0.2–0.4 gently tidies a face; 0.7–0.9 reshapes it entirely. At high denoise you'll usually want to change the prompts too, and the README suggests switching to thebetascheduler.face_selection- 0 processes every face; 1 targets the first detected, 2 the second, and so on.detection_confidence(default 0.75) - YOLO's threshold. Most strong detections land at 0.86–0.90; drop it only for extreme stylization or tiny faces.
face_positive_prompt / face_negative_prompt prepend tags to your main conditioning for the face pass only, and exclusions strips tags like "smile" or "glasses" from it. The per-face wildcard syntax is worth knowing: [SEP] assigns different prompts to each detected face, [SKIP] leaves one untouched, and [ASC]/[DSC]/[ASC-SIZE]/[DSC-SIZE] control ordering. It's inherited from Impact Pack, so if you've used that syntax before, it migrates cleanly.
The outputs are generous: final_image (the composite), processed_face, a side_by_side_comparison, and final_mask. Most people just want final_image wired to a Save node.
Install and the gotchas
Install via ComfyUI Manager (search "Forbidden Vision") or:
cd ComfyUI/custom_nodes
git clone https://github.com/luxdelux7/ComfyUI-Forbidden-Vision.git
cd ComfyUI-Forbidden-Vision
pip install -r requirements.txt
Then restart. The dependency list is heavier than most: ultralytics (which is AGPL - same licensing corner ADetailer and Impact Pack live in), timm, segmentation-models-pytorch, kornia, opencv-python-headless. First run downloads the models and can take a minute.
Where people get burned: if the segmentation model fails to load - typically timm missing or a dependency conflict - the node silently falls back to a plain oval mask based on the YOLO bounding box, and users report "why is my mask just an oval?" on the release thread. If you see that, check your install rather than your settings. Also know that the pack monkeypatches CLIPTextEncode to stash the original prompt text in conditioning, which is how exclusions can strip tags from a prompt you wrote in a plain text-encode node. It's a small hack, but it's worth knowing it's there.
Detection failures on heavy stylization or occlusion happen - the author is upfront about it and asks for reports via GitHub issues. And it's AGPL-3.0 licensed, so read that before you ship anything commercial around it.
Inputs (35)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| vae | VAE | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| steps | INT | 101–100 | — |
| cfg_scale | FLOAT | 3.00–30 | — |
| sampler | COMBO | euler_ancestral | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | sgm_uniform | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| denoise_strength | FLOAT | 0.400–1 | — |
| seed | INT | 00–18446744073709550000 | — |
| face_selection | INT | 00–20 | 0=All faces, 1=1st face, etc. |
| detection_confidence | FLOAT | 0.750.1–1 | Face detection confidence threshold. |
| manual_rotation | COMBO | None | Manually rotate face crop before processing |
| processing_resolution | INT | 1024512–2048 | The resolution for processing. |
| enable_pre_upscale | BOOLEAN | true | Enable to upscale small faces with an AI model before processing. |
| upscaler_model | COMBO | Fast 4x (Lanczos) | The model used for pre-upscaling small faces. |
| crop_padding | FLOAT | 1.61–3 | Padding added to the face region before inpaint. |
| face_positive_prompt | STRING | — | |
| replace_positive_prompt | BOOLEAN | false | — |
| face_negative_prompt | STRING | — | |
| replace_negative_prompt | BOOLEAN | false | — |
| exclusions | STRING | Words/tags to remove from the main prompt specifically for the face processing step. | |
| blend_softness | INT | 80–200 | — |
| mask_expansion | INT | 20–100 | — |
| sampling_mask_blur_size | INT | 211–101 | — |
| sampling_mask_blur_strength | FLOAT | 1.00.1–6 | — |
| enable_color_correction | BOOLEAN | true | — |
| enable_segmentation | BOOLEAN | true | Use AI segmentation. If disabled, creates oval masks. |
| enable_differential_diffusion | BOOLEAN | true | Better blending. At high noise, the mask allows structure changes; at low noise, it locks the background. |
| enable_lightness_rescue | BOOLEAN | true | If the generated face is darker than original, brighten it. |
| enable_final_refinement | BOOLEAN | true | Runs a quick 0.05 denoise pass at the end. Cleans artifacts and improves skin texture with sensitive models and higher denoise. Highly recommended. |
| offload_models_to_cpu | BOOLEAN | true | Move face detection/segmentation/corrector models from VRAM to RAM after processing. Frees GPU memory for other nodes (e.g. checkpoint swaps in queued workflows). Disable if you're chaining many face passes and want to skip the small reload overhead. |
| imageopt | IMAGE | Optional image input. If latent is also provided, latent will be used. | |
| latentopt | LATENT | Optional latent input. Will be decoded for processing. | |
| clipopt | CLIP | Optional: Required only if using face prompts. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| final_image | IMAGE | — |
| processed_face | IMAGE | — |
| side_by_side_comparison | IMAGE | — |
| final_mask | MASK | — |