Nodes/ImageCLIPSimilarityPure/CLIP Similarity (Fixed Output)
ComfyUI Node

CLIP Similarity (Fixed Output)

The tiny node that answers 'are these two images the same thing?' with one number

By claudia2020shen·Created 6 months ago·Updated 6 months ago· 0
CLIP Similarity (Fixed Output)
  • image_a
  • image_b
  • clip_vision_model
  • similarity_score

The name is a little lie: "pure" doesn't mean fancy, it means self-contained. ImageCLIPSimilarityPure takes two images, runs them through a CLIP Vision model, and returns a single float saying how semantically similar they are. No API, no key, no internet. It's the kind of node you install for one specific afternoon and then forget about - until the day you're staring at a KSampler output asking "is this actually closer to my reference, or did the seed change everything?"

When do you actually reach for it? Whenever you want a number instead of eyeballing. People use it to pick a seed or prompt variant by checking which generation lands closest to a reference image (img2img, style transfer, character consistency), to sanity-check that a workflow change really moved the output, or to gate a batch - wire the FLOAT into a switch or logic node and only save outputs whose similarity to your target clears a threshold. It's an analysis node, category Analysis/Image, so think debugging and quality control rather than generation.

How it works

Under the hood it's roughly 30 lines of real code and a lot of debug prints. It encodes both images with ComfyUI's built-in comfy.clip_vision, then takes the cosine similarity between the two embeddings:

  1. image_a and image_b go through encode_image().
  2. ComfyUI's CLIP vision returns an Output object; the node grabs last_hidden_state and mean-pools over the sequence dimension to get one vector per image.
  3. Cosine similarity of those two vectors is your score. Same direction = more similar; 1.0 means "basically identical to the model", near 0 means unrelated, and negative scores are rare in practice.

One honest caveat: this is not a perceptual-similarity metric like LPIPS or SSIM. CLIP measures semantic closeness - "is it the same kind of thing" - not pixel fidelity. Two images with identical composition but different styles can score lower than you'd expect, and two different photos of the same subject can score high. For "did my pipeline drift" it's fine; for "is this pixel-perfect" it's the wrong tool.

Worth knowing too: it doesn't use the pooled image_embeds that CLIP's projection head produces - it mean-pools last_hidden_state instead. That's a defensible choice, but it means the numbers won't match the canonical CLIP cosine scores you see discussed elsewhere, and they're only comparable when you use the same CLIP vision model across runs.

The inputs that matter

All three are required, and that's the whole schema:

  • image_a / image_b (IMAGE) - wire up anything that outputs an image: LoadImage, a KSampler's IMAGE output, a VHS frame grab. Only the first image in a batch is used, so feed single frames.
  • clip_vision_model (CLIP_VISION) - the output of the built-in CLIPVisionLoader node.

Output: one similarity_score FLOAT. It displays on the node after a run, and the node also echoes it to the console (see gotchas).

Installing it

Two routes, same result:

cd ComfyUI/custom_nodes
git clone https://github.com/claudia2020shen/ImageCLIPSimilarityPure
# then restart ComfyUI

Or skip the terminal: ComfyUI Manager → search "ImageCLIPSimilarityPure" → install. There's no requirements.txt to fight over - the pack's is empty, because it only uses ComfyUI's built-in comfy.clip_vision and torch. Nothing extra gets pip-installed into your environment.

You do need a CLIP vision model file in ComfyUI/models/clip_vision/. The README names two: CLIP-ViT-H-14-laion2B-s32B-b79K.safetensors (the IP-Adapter SD 1.5 image encoder) or the bigger CLIP-ViT-bigG-14-laion2B-39B-b160k (the SDXL one). If you've ever run IP-Adapter you probably already own one of these. Both are downloadable from the laion repos on Hugging Face, or through Manager's model installer.

Gotchas

  • The console is chatty. The node print()s [DEBUG] lines and a big !!! FINAL SCORE !!! banner on every run. Harmless, but expect terminal noise.
  • Batch trap. Feed it two batched image lists and it silently compares only the first frame of each. It's built for single images.
  • Scores are model-relative. Swap clip_vision_model between runs and the numbers aren't comparable - pick one encoder and stick with it.
  • VRAM nitpick. The encode happens outside torch.no_grad(), so it builds a discarded autograd graph. Nothing for a one-shot comparison; irrelevant unless you're looping it thousands of times.

It's a niche tool - single-digit registry impressions means you found it before almost everyone - but when you need a similarity number without calling an API or bolting on a 2 GB dependency, this is the smallest thing that does the job.

CategoryAnalysis/Image

Inputs (3)

NameTypeDefaultDescription
image_aIMAGE
image_bIMAGE
clip_vision_modelCLIP_VISION

Outputs (1)

NameTypeDescription
similarity_scoreFLOAT