Nodes/ComfyUI_RS_MultiCharacter_Sampler/RS MultiCharacter Detailer
ComfyUI Node

RS MultiCharacter Detailer

Fixing the face that came out 60 pixels wide

By raspie10032·Created 3 days ago·Updated 2 days ago· 1
RS MultiCharacter Detailer
  • image
  • model
  • clip
  • vae
  • character_pipe
  • detectors
  • tagger
  • image
  • edited_mask
  • character_pipe
  • region_report
◄denoise0.25►
◄seed0►
◄autosavetrue►
◄show_advancedfalse►
◄steps20►
◄cfg4.0►
◄sampler_nameeuler_ancestral►
◄schedulersgm_uniform►
◄guide_size768►
◄max_size1024►
◄max_regions10►
◄bbox_threshold0.30►
◄crop_factor3.0►
◄dilation8►
◄fill_holestrue►
◄closingtrue►
◄mask_feather8►
◄match_min_score0.25►
◄match_min_margin0.08►
◄match_crop_factor2.0►
◄save_formatPNG►
◄webp_quality90►

Two people in a 1536×768 frame means each face gets a few dozen pixels of latent budget. No checkpoint survives that. The standard fix is the detect-crop-rerender-paste loop that ADetailer turned into a checkbox and Impact Pack turned into FaceDetailer, and it works for the same reason every time: give the face its own pass at proper resolution.

RS MultiCharacter Detailer is that loop with a twist the generic detailers don't have. It knows which character it's looking at, so each crop gets re-rendered with that character's original prompt and, if you set one, that character's LoRA.

The twist: matching instead of guessing

A normal detailer hands every detected face the same prompt. In a two-character scene that's how you get the wrong hair colour re-baked in, or a shared prompt smeared over both. This node runs RS Character Tagger Loader over each crop, gets WD-tagger scores, and compares them against the tags in your character prompts. The strongest discriminating tag wins, with a margin requirement: if two characters score too close together, the region is left alone rather than being confidently mislabelled.

The part I like: inferred tags never enter the prompt. The tagger only chooses which of your prompts applies. Your own text is what gets sampled, so a tagger hallucinating blonde hair can't add blonde hair to your brunette.

What it actually does

Detection comes from the detectors bundle (RS Detection Combine Loader) - SEGM masks by default, or BBOX refined by SAM. Regions are sorted left-to-right, capped by max_regions, then each one is cropped with crop_factor context, resized so its short side hits guide_size with the long side capped by max_size, matched to a character, and re-rendered as a masked img2img pass. Masks get dilation, optional fill_holes and closing, and mask_feather softens the seam from the inside of the mask.

Then it composites back onto the original image. Pixels outside the applied mask are untouched in PNG or lossless WebP output; lossy WebP can move them, which is worth remembering if you're comparing before/after.

Inputs that matter

Required: image, model, clip, vae, character_pipe, detectors, denoise (default 0.25), seed, autosave. Wire the same MODEL/CLIP/VAE the sampler used - including any global LoRA you applied, since the detailer doesn't inherit node state from elsewhere.

Start at denoise 0.25. That's the author's default and it's the right ballpark for "clean up and add detail" rather than "redraw the face". Push it up and you get a different person.

Optional: tagger - required the moment you have more than one character, and the node errors if you skip it. Then show_advanced reveals the tuning block: steps (20 default, separate from your generation steps), cfg, sampler_name, scheduler, guide_size, max_size, max_regions, bbox_threshold, crop_factor, dilation, fill_holes, closing, mask_feather, match_min_score, match_min_margin, match_crop_factor, save_format, webp_quality.

The two matching thresholds are where craft lives. Lower match_min_score and you accept weaker evidence; lower match_min_margin and you let near-ties be resolved instead of skipped. With two characters who look similar, the safe answer is to leave them and let the report tell you why.

Outputs: image, edited_mask (see exactly what got touched), character_pipe (pass it on, it carries the character data forward) and region_report - a string listing each region, its assigned character and the score/margin. Read it. The author warns that high-confidence misidentification is still possible, especially with similar-looking characters.

Install, and the dependency that bites

The core pack installs from ComfyUI Manager (search RS MultiCharacter Sampler) or by cloning into custom_nodes. The detailer is the part with real dependencies:

cd ComfyUI/custom_nodes
git clone https://github.com/raspie10032/ComfyUI_RS_MultiCharacter_Sampler.git
cd ComfyUI_RS_MultiCharacter_Sampler
# use YOUR ComfyUI python, not system python
/path/to/ComfyUI/venv/bin/python -m pip install -r requirements-detailer.txt

That pulls opencv-python, scipy, plus timm, huggingface-hub and safetensors for the tagger. You also need ComfyUI-Impact-Pack and ComfyUI-Impact-Subpack installed via Manager, because that's where the ultralytics detector machinery and model folders come from. SAM is optional but must already be installed for it to appear in the dropdown. Then restart.

Where people get burned

Installing the detailer requirements into the wrong Python is the number one cause of "module not found" - check the interpreter your ComfyUI actually launches with. Multiple characters without a tagger node is an instant validation error, not a silent degradation. Detailing text regions does nothing, since text slots aren't face-matching candidates. And more max_regions does not mean more quality; the author says so twice, once in each language.

One more from experience: detail before you upscale. Upscaling first bakes the mangled face into more pixels and then costs you more compute to repair.

CategoryRS MultiCharacter

Inputs (29)

NameTypeDefaultDescription
imageIMAGE—
modelMODEL—
clipCLIP—
vaeVAE—
character_pipeRS_MC_CHARACTER_PIPE—
detectorsRS_MC_DETECTION_BUNDLE—
denoiseFLOAT0.250.01–1—
seedINT00–18446744073709550000—
autosaveBOOLEANtrue—
taggeroptRS_MC_TAGGERRequired for multiple characters. Scores only select your original prompt; ambiguous regions are preserved.
show_advancedoptBOOLEANfalse—
stepsoptINT201–100—
cfgoptFLOAT4.00–30—
sampler_nameoptCOMBOeuler_ancestral44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
scheduleroptCOMBOsgm_uniform9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
guide_sizeoptINT768128–2048Target crop short side. max_size caps the long side. More resolution requires more VRAM.
max_sizeoptINT1024128–4096—
max_regionsoptINT101–64Maximum regions to edit, not character count. More processed regions do not guarantee quality.
bbox_thresholdoptFLOAT0.300.01–1—
crop_factoroptFLOAT3.01–8—
dilationoptINT80–128—
fill_holesoptBOOLEANtrue—
closingoptBOOLEANtrue—
mask_featheroptINT80–64—
match_min_scoreoptFLOAT0.250–1—
match_min_marginoptFLOAT0.080–1—
match_crop_factoroptFLOAT2.01–4—
save_formatoptCOMBOPNG3 options: PNG, WebP lossless, WebP lossy
webp_qualityoptINT901–100—

Outputs (4)

NameTypeDescription
imageIMAGE—
edited_maskMASK—
character_pipeRS_MC_CHARACTER_PIPE—
region_reportSTRING—