Nodes/comfyui-fvmtools/Person Detailer
ComfyUI Node

Person Detailer

Detail each face in a crowd with its own LoRA — without burning out your workflow

By ping1979ping·Created 5 months ago·Updated about a month ago· 0
Person Detailer
  • images
  • person_data
  • model
  • clip
  • vae
  • positive_base
  • negative
  • dd_options
  • inpaint_options
  • images
  • refined
  • refined_references
  • refined_generic
seed0
steps4
denoise0.52
sampler_name
scheduler
detail_daemon_enabledtrue
detail_amount0.20
dd_smoothtrue
mask_blend_pixels32
mask_expand_pixels0
target_width800
target_height1200
reference_1_enabledtrue
reference_1_lora
reference_1_lora_strength1.00
reference_1_prompt
reference_2_enabledfalse
reference_2_lora
reference_2_lora_strength1.00
reference_2_prompt
reference_3_enabledfalse
reference_3_lora
reference_3_lora_strength1.00
reference_3_prompt
reference_4_enabledfalse
reference_4_lora
reference_4_lora_strength1.00
reference_4_prompt
reference_5_enabledfalse
reference_5_lora
reference_5_lora_strength1.00
reference_5_prompt
generic_enabledfalse
generic_catch_unprocessedtrue
generic_lora
generic_lora_strength1.00
generic_prompt

If you've ever tried to put two or three different characters in one image and watched the model blend them into one mush-faced average, you know the pain this node exists for. Person Detailer is the workhorse of the FVMtools pack: it takes an image, a set of detected faces, and - here's the part FaceDetailer from Impact Pack can't do - applies a different LoRA and prompt to each person. Person one gets your character LoRA and a "short brown hair" prompt; person two gets the other LoRA and "long black hair"; everyone else can be swept up by a generic slot. It's the multi-character problem from character-consistency land, solved with a bunch of per-slot inpaint passes instead of hoping regional prompting cooperates.

What it actually does

The mechanism is the old detect-crop-refine loop - the same idea Impact Pack's FaceDetailer popularized in ComfyUI - but re-engineered for multiple identities. Feed it images plus person_data from Person Selector Multi (the node that matched each face to a reference and generated its masks), and it iterates over your reference slots one at a time. For each enabled slot it crops the matched region, applies that slot's LoRA as a temporary clone on your base model, encodes the slot's prompt, and runs a masked inpaint pass at target_width × target_height - 800×1200 by default, which is the whole point: a face that's 80×80 in the full frame gets a proper resolution budget. Then it feathers the edges (mask_blend_pixels, default 32) and stitches it back. Slots process sequentially, each inpainting into the result of the previous one, so the image builds up progressively.

There's real engineering under the hood. LoRA files live in a 6-slot LRU cache so the same LoRA isn't re-read from disk for every face. And before the batch loop it pre-computes every unique (LoRA, strength, prompt) combination once - five people sharing one LoRA means one load and one conditioning encode, not five. If you're running Z-Image Turbo (Lumina2), it auto-detects it and converts diffusers-style LoRAs to the fused QKV format on the fly. That last bit is why the defaults look weird: steps defaults to 4 and denoise to 0.52, tuned for distilled turbo models. On a regular SDXL or Flux checkpoint, raise steps before you conclude it's broken.

The inputs that matter

  • reference_1_enabled / reference_1_lora / reference_1_prompt - slot 1 is on by default; slots 2–5 start disabled. Each slot's prompt, if empty, falls back to the positive_base conditioning. This is where you wire per-character identity.
  • denoise - 0.52 default. Lower keeps more original detail; too high and you're re-drawing the face, not refining it.
  • generic_enabled + generic_prompt - the catch-all. It starts off; flip it on and, with generic_catch_unprocessed (on by default) doing the sweeping, it details any face no reference slot claimed, so nobody gets left looking mushy.

Outputs: images (the final stitched result), plus refined, refined_references, and refined_generic - grids of the inpainted crops, handy for checking what each slot actually did. Wire images straight to a SaveImage or into an upscaler.

Installing it

Grab the whole pack once - every node in this family ships together. Via ComfyUI Manager, search comfyui-fvmtools, or:

cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
pip install insightface>=0.7.3 onnxruntime-gpu>=1.17.0 opencv-python>=4.8.0 numpy>=1.24.0

Restart ComfyUI. InsightFace's buffalo_l models auto-download on first use, but the BiSeNet segmentation model does not - drop parsing_bisenet.pth (53 MB, from xinntao/facexlib releases) into ComfyUI/models/gfpgan/ or face/head masks silently won't exist.

Where people get burned

The classic gotcha: an empty output. If you see a 64×64 black placeholder image come out, that's not a crash - it means no face matched any enabled slot, so nothing got detailed. Check your reference images, the threshold on Person Selector Multi, and whether the right slots are enabled. Also worth knowing: this node is LOUD - it loads a face detector, a face parser, potentially SAM, and runs a full inpaint per person. First run on a big batch can feel like it hung while models initialize. It's not hung, it's downloading buffalo_l.

CategoryFVM Tools/Face

Inputs (46)

NameTypeDefaultDescription
imagesIMAGEInput image batch [B, H, W, C]
person_dataPERSON_DATAPerson data from Person Selector Multi node
modelMODELBase model (LoRAs are applied as temporary clones per slot)
clipCLIPCLIP model for prompt encoding
vaeVAEVAE for encode/decode in the inpaint pipeline
seedINT00–18446744073709550000Global seed, fixed across all slots and batch items
stepsINT41–100Number of sampling steps per inpaint
denoiseFLOAT0.520–1Denoise strength for inpainting (lower = more original detail preserved)
sampler_nameCOMBOSampler algorithm
schedulerCOMBONoise schedule
detail_daemon_enabledBOOLEANtrueEnable Detail Daemon sigma manipulation for enhanced detail preservation
detail_amountFLOAT0.20-5–5Detail Daemon strength. Positive = more detail, negative = smoother. 0 = off.
dd_smoothBOOLEANtrueSmooth the Detail Daemon sigma curve to avoid artifacts
mask_blend_pixelsINT320–128Gaussian feather radius at mask edges for seamless blending
mask_expand_pixelsINT00–64Dilate/expand mask by this many pixels before inpainting
target_widthINT80064–4096Width to resize face crops to before sampling
target_heightINT120064–4096Height to resize face crops to before sampling
reference_1_enabledBOOLEANtrueEnable reference slot 1 for detailing
reference_1_loraCOMBOLoRA to apply when detailing reference 1
reference_1_lora_strengthFLOAT1.000–2LoRA strength for reference 1
reference_1_promptSTRINGPositive prompt for reference 1. If empty, uses base conditioning.
reference_2_enabledBOOLEANfalseEnable reference slot 2 for detailing
reference_2_loraCOMBOLoRA to apply when detailing reference 2
reference_2_lora_strengthFLOAT1.000–2LoRA strength for reference 2
reference_2_promptSTRINGPositive prompt for reference 2. If empty, uses base conditioning.
reference_3_enabledBOOLEANfalseEnable reference slot 3 for detailing
reference_3_loraCOMBOLoRA to apply when detailing reference 3
reference_3_lora_strengthFLOAT1.000–2LoRA strength for reference 3
reference_3_promptSTRINGPositive prompt for reference 3. If empty, uses base conditioning.
reference_4_enabledBOOLEANfalseEnable reference slot 4 for detailing
reference_4_loraCOMBOLoRA to apply when detailing reference 4
reference_4_lora_strengthFLOAT1.000–2LoRA strength for reference 4
reference_4_promptSTRINGPositive prompt for reference 4. If empty, uses base conditioning.
reference_5_enabledBOOLEANfalseEnable reference slot 5 for detailing
reference_5_loraCOMBOLoRA to apply when detailing reference 5
reference_5_lora_strengthFLOAT1.000–2LoRA strength for reference 5
reference_5_promptSTRINGPositive prompt for reference 5. If empty, uses base conditioning.
generic_enabledBOOLEANfalseEnable detailing for unmatched faces (not assigned to any reference)
generic_catch_unprocessedBOOLEANtrueON: detail all faces not processed by active slots (including matched but disabled slots). OFF: only truly unmatched faces from Person Selector Multi.
generic_loraCOMBOLoRA to apply for unmatched faces
generic_lora_strengthFLOAT1.000–2LoRA strength for unmatched faces
generic_promptSTRINGPositive prompt for unmatched faces. If empty, uses base conditioning.
positive_baseoptCONDITIONINGBase positive conditioning, used as fallback when a slot's prompt is empty
negativeoptCONDITIONINGNegative conditioning. If not connected, an empty negative is used.
dd_optionsoptDD_OPTIONSAdvanced Detail Daemon parameters from Detail Daemon Options node
inpaint_optionsoptINPAINT_OPTIONSAdvanced inpaint settings and per-slot overrides from Inpaint Options node

Outputs (4)

NameTypeDescription
imagesIMAGE
refinedIMAGE
refined_referencesIMAGE
refined_genericIMAGE