Nodes/ComfyUI LC Modelbuilder Nodes/LC Face Variety Scorer πŸ§‘β€πŸ€β€πŸ§‘
ComfyUI Node

LC Face Variety Scorer πŸ§‘β€πŸ€β€πŸ§‘

The same-face test your merged checkpoint deserves

By lonecatone23Β·Created 21 days agoΒ·Updated 3 days agoΒ· 3
LC Face Variety Scorer πŸ§‘β€πŸ€β€πŸ§‘
  • images
  • score
  • same_pct
  • crowd_score
  • grade
  • report
  • faces
  • faces_found
β—„same_threshold0.35β–Ί
β—„min_face_px40β–Ί
β—„deviceβ–Ύβ–Ί
β—„face_modelphoto (ArcFace)β–Ί

Merges converge. Ask anyone who's browsed CivitAI's new-models feed and you get some version of "it more and more looks like just a gallery from just one model," or the blunter prediction that we'll end up with "one average looking AI generated face that has converged over hundreds of models" (both quoted in concepts.md). Merging averages existing weights, and averaged weights produce averaged faces. It's the most predictable way a merge fails, and the one thing nobody measures - people eyeball eight outputs, decide the faces look samey, and start guessing at sliders.

LC Face Variety Scorer turns that vibe into a number. Feed it a batch, get back a 0.0–1.0 score where lower means more variety, plus a grid of the exact faces it measured so you can see where the number came from.

How it works

Detection and recognition, no training and no LLM. The node runs SCRFD (det_10g.onnx) to find faces and their five keypoints, aligns each crop the ArcFace way, then embeds it with w600k_r50.onnx - a 512-d vector that encodes facial geometry, not hair, clothes or lighting. It picks the largest face in each image as that image's representative, then takes the mean pairwise cosine similarity across all of those. That average is score.

crowd_score does the same comparison inside each image instead, which is the group-shot test: if a prompt about a crowd gives you eight clones, this catches it.

| Score | Grade | |---|---| | 0.00 – 0.20 | Clearly different people | | 0.20 – 0.35 | Different people who share a few features | | 0.35 – 0.50 | Could be sisters, or the same person in a different photo | | 0.50 – 1.00 | Same person |

For how durable that complaint is: roughly 950 threads in the last two years, still 25–45 a month through 2026. This node is the measurement half of the argument.

The inputs that matter

Four, and you'll only change two of them.

images is a batch - same prompt, different seeds is the correct test, 8 or more images. Randomizing the prompt tests prompt adherence, not model variety. min_face_px (default 40) drops faces narrower than that in pixels, which is what stops a background pedestrian or a face in a reflection from polluting your score. Bump it if your test renders are big and you want only the subject counted. same_threshold (default 0.35) is the cutoff for the same_pct output - "percent of face pairs that could be the same person." device is cpu by default and that's not a downgrade: a normal batch scores in seconds, and CPU works identically on NVIDIA, AMD, Intel and Mac. auto tries CUDA first and falls back quietly.

The outputs

Seven of them, and they're all useful. score is the headline number - wire it into a Show Text, or a numeric gate if you're comparing checkpoint candidates in one graph. same_pct is the percentage of pairs above your threshold, which is often more intuitive than the raw mean ("60% of these pairs read as the same person"). crowd_score (also 0.0–1.0, lower = more variety) reports -1 when no image contained two or more faces, which is a deliberate "not applicable" marker rather than a zero - don't plot it blindly. grade gives you the human-readable band as a string. report is the whole thing formatted as text for a Show Text or Preview Any node. faces is the IMAGE grid - 128 px tiles, ten per row - of every face it used. faces_found is the count of images that contributed a face.

That grid is the part that makes the score trustworthy. If your "samey" model scored 0.22 but the grid shows eight crops of a coffee cup and one real face, you've learned something about your detection, not your model.

Models, and the install that isn't awful

This is the pack's only real dependency, and it's handled better than most face tooling. First run downloads InsightFace buffalo_l (~280 MB) to ComfyUI/models/insightface/models/buffalo_l/, checksum-verified so an interrupted download can't leave a broken file behind. Already have buffalo_l there from IPAdapter FaceID or ReActor (they look in the same folder - it also checks ~/.insightface/models/buffalo_l)? Nothing downloads.

The important bit: no insightface package and no opencv. The detection decode, NMS and alignment were reimplemented in the node itself and the ONNX models run straight through onnxruntime. That kills the single worst install in local generation - the C++ compiler, the numpy and protobuf fights - and the maintainers' own 1.0 release in May 2026 finally dropped the build requirement too (insightface.json has the history).

install.py runs under ComfyUI Manager on install and update. It self-tests whatever onnxruntime you have by executing a tiny embedded model; if everything works it changes nothing, if nothing is installed it installs the plain CPU onnxruntime, and if something is installed but broken it prints repair commands instead of guessing. Only if you cloned by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC_ModelBuilder_nodes
cd ComfyUI_LC_ModelBuilder_nodes && python install.py

It never uninstalls or upgrades anything, and it snapshots pip freeze into install_backups/ first. It installs the CPU build deliberately: onnxruntime-gpu and its CUDA/cuDNN matching is the number one cause of "LoadLibrary failed with error 126."

Where people get burned

The license. buffalo_l is InsightFace's, released for non-commercial research use only. Scoring your own test renders is fine. Building this into a product is not, and that constraint rides on the weights, not the code - the same trap the whole identity-tool ecosystem sits on.

One face per image. The node scores the largest face in each image. A batch of group shots gives you one main face per shot, so score describes those dominant people - use crowd_score for the within-image question.

Small faces. If images come back under min_face_px you'll see them listed as "No face found" in report, and fewer than two usable faces means grade reads "Need at least 2 faces" and the score is meaningless. Shoot bigger, or lower the threshold knowingly.

The example workflow. workflows/LC Face Variety Test.json also uses LC Image Batch From Folder from the separate ComfyUI_LC123_nodes pack (v1.40.0+). If you only installed this pack, ComfyUI will report a missing node - that's the sibling pack, not a broken install.

CategoryLC ModelBuilder/testing

Inputs (5)

NameTypeDefaultDescription
imagesIMAGEA batch of generations to test. Same prompt, different seeds works best. 8 or more images.
same_thresholdFLOAT0.350.1–0.9Two faces scoring above this count as 'could be the same person' for same_pct.
min_face_pxINT408–1024Ignore detected faces narrower than this (background people, reflections).
deviceCOMBOcpu works on every install and takes seconds for a normal test. auto tries CUDA first and falls back to CPU.
face_modeloptCOMBOphoto (ArcFace)photo = ArcFace on the main face, for realistic models. anime = CCIP on each image's main anime face, for anime and illustration models (Anima, Illustrious, Pony): photo face models miss on anime faces. The models download once (about 200 MB).

Outputs (7)

NameTypeDescription
scoreFLOATβ€”
same_pctFLOATβ€”
crowd_scoreFLOATβ€”
gradeSTRINGβ€”
reportSTRINGβ€”
facesIMAGEβ€”
faces_foundINTβ€”