Nodes/ComfyUI_Face_similarity/Face Similarity (InsightFace)
ComfyUI Node

Face Similarity (InsightFace)

Let InsightFace tell you whether the face drifted

By phobod·Created 3 months ago·Updated 6 days ago· 0
Face Similarity (InsightFace)
  • reference_image
  • generated_image
  • image
  • similarity_score
  • verdict
  • is_same_person
modelbuffalo_l
detection_size640
threshold0.60

When you're holding onto a character across generations - an identity LoRA you're testing, a face swap, a persona you need to stay on-model - "looks close enough" stops being a reliable judge somewhere around reroll number forty. FaceSimilarityNode does what your eyes are bad at: it runs your reference photo and your generation through InsightFace, pulls a 512-dimensional ArcFace embedding out of each, and returns a cosine similarity score that tells you whether the person's facial geometry actually survived the trip.

That's the whole pitch of this node from the phobod/ComfyUI_Face_similarity pack. It generates nothing; it's a measuring instrument, and it sits in the same family as the identity tools you already know - IP-Adapter FaceID, InstantID, PuLID, and ReActor all lean on InsightFace embeddings under the hood. This node just exposes the raw comparison instead of conditioning on it. Feed it two IMAGEs, get a FLOAT, and let the number decide.

How it works

InsightFace's FaceAnalysis detects faces, aligns them, and turns each into a normalized ArcFace embedding - a vector that encodes facial geometry rather than appearance, which is why the comparison holds up across poses, styles, and lighting. The node takes the largest face in each image and computes cosine similarity between the two vectors. Two identical faces score 1.0, unrelated faces land near 0, and the scale runs -1 to 1.

Two details matter before you build anything on it. First, it's the largest face only - put two people in the frame and you're comparing the two biggest heads, not every face. Second, if either image has no detectable face, the node doesn't crash: you get a score of 0.0, a verdict string saying which image failed, and is_same_person set to False.

The inputs that matter

  • reference_image / generated_image - the person as they are, and the person as the model produced them. That's the whole input story: two IMAGEs.
  • model - dropdown across buffalo_l, buffalo_m, buffalo_s, buffalo_sc, and antelopev2. buffalo_l is the default and the accuracy pick; buffalo_m/buffalo_s trade accuracy for speed; antelopev2 is the high-end option (it's what InstantID expects).
  • detection_size - 640 by default; drop to 320 or 160 when you want speed and can accept it missing small faces.
  • threshold - a float 0–1, default 0.6, the line between "same person" and "drifted". That 0.6 is a fine starting point; tune it against a handful of known-good and known-bad pairs of your own.

The README's reference: above 0.6 you're confidently the same person, 0.4–0.6 is "worth a look", below 0.4 identity has drifted.

The outputs

Four sockets out: image (your generated image passed straight through), similarity_score (the FLOAT), verdict (a STRING like Same person - score: 0.831 (threshold: 0.6)), and is_same_person (BOOLEAN). The last one is the one you build around. Wire it into a conditional such as Impact Pack's ImpactConditional and you get an automatic reroll loop: generate, score, keep it if it clears the bar, resample if not. Because the image passes through, you can also hang a Save node straight off it - which is exactly what the pack's other node, SaveImageIf, is for.

Installing it

The pack is tiny and single-author - at the time of writing it's one commit, no real community footprint, so treat it as fresh code. Easiest route is ComfyUI Manager: search "Face Similarity" (pack title ComfyUI_Face_similarity) and install. Manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/phobod/ComfyUI_Face_similarity.git
cd ComfyUI_Face_similarity
pip install -r requirements.txt

The dependency that deserves your respect is InsightFace itself. It has one of the worst install reputations in local generation - older versions needed Visual Studio build tools to compile from source. The 1.x releases finally ship prebuilt wheels, so on a recent Python it usually just works now; the pack's floor is insightface>=0.7.3. Note that requirements.txt defaults to onnxruntime-gpu, so CPU-only users should edit it and swap in plain onnxruntime before installing - the README says exactly this. First run then downloads the buffalo_l weights (several hundred MB) into ~/.insightface/models/ automatically.

Gotchas

  • antelopev2 is in the dropdown but InsightFace does not auto-download it. If you select it and hit an error, fetch the pack manually and unzip it under ~/.insightface/models/. This is the most likely "why won't it work" moment with this node, and the README's "all models download automatically" glosses right over it.
  • Every score exactly 0.000? No face was detected - too small at detection_size 160, or genuinely no face. The node is silent about it except for the verdict string.
  • License. This is the one that bites people later. The InsightFace model weights are non-commercial research terms regardless of the MIT-licensed code. Personal, hobby, and portfolio use is exactly what the terms grant; anything you intend to sell needs a commercial license from InsightFace. Same trap that runs through FaceID, InstantID, and ReActor - you're standing in it now.

A workflow that uses it

Load your reference photo, load your generation, feed both in, take is_same_person into an ImpactConditional, route True to a Save node and False back to the sampler for another pass. A self-correcting loop where the machine decides what "close enough" means.

CategoryFace Analysis

Inputs (5)

NameTypeDefaultDescription
reference_imageIMAGE
generated_imageIMAGE
modelCOMBObuffalo_l5 options: buffalo_l, buffalo_m, buffalo_s, buffalo_sc, antelopev2
detection_sizeCOMBO6403 options: 640, 320, 160
thresholdFLOAT0.600–1

Outputs (4)

NameTypeDescription
imageIMAGE
similarity_scoreFLOAT
verdictSTRING
is_same_personBOOLEAN