Sentence Similarity
Score how close two texts are — the node that can gate your workflow
- similarity_score
Sentence embeddings are the quiet workhorse of a lot of prompt automation. This node takes two strings, embeds both with a sentence-transformer model, and returns a single FLOAT - the cosine similarity between them. That number is shockingly useful as a control signal in a ComfyUI graph: is this generated caption close to what I asked for? Is prompt A more like the reference than prompt B? Feed the score into a threshold/switch node and you've built a poor-man's quality gate without any API calls or extra pipelines.
It's part of kadirnar/ComfyUI-Transformers, the pack that wraps Hugging Face's transformers.pipeline() as nodes. The whole pack shares the same install and the same quirks; this is one of the handful of nodes in it that's actually worth slotting into a real workflow.
How it works
Under the hood it calls pipeline("feature-extraction", model=model_name), takes the token embeddings for each sentence, mean-pools them over the sequence length, and computes cosine similarity. The default model is sentence-transformers/all-MiniLM-L6-v2 - small (~90 MB), fast, and the community default for exactly this job.
Here's the honest caveat: mean-pooling is the naive way to build a sentence embedding. The proper sentence-transformers library applies learned pooling that makes those embeddings actually comparable, and this node doesn't use it. In practice the scores still rank correctly for "same topic vs. different topic" - just don't treat the absolute number as gospel. Two paraphrases might land at 0.8 while a question and its answer sit at 0.5. It's a routing signal, not a meter.
The inputs and outputs
text1/text2- both multiline STRINGs. That's the whole game.model_name- free text, so you can swap in any feature-extraction model on the Hub. Stick with MiniLM unless you have a reason; bigger models give marginal gains for real speed/memory costs.- Output:
similarity_score, a single FLOAT.
The output being a plain float is what makes it composable. You can feed it to a compare/range node and branch the graph, or use it to sort a batch of candidate prompts before they hit the CLIP encoder. There are no list helpers here - it's strictly one pair at a time.
Installing it
Same as the rest of the pack - ComfyUI Manager (search "ComfyUI-Transformers"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/kadirnar/ComfyUI-Transformers
cd ComfyUI-Transformers
pip install -r requirements.txt
Restart, and the node appears under Transformers/NLP/SentenceSimilarity. The README's install snippet has a typo (cd custom/nodes) - ignore it. The requirements.txt drags in transformers>=4.42 plus the usual suspects; since transformers lives in the shared ComfyUI Python environment, installing this pack can occasionally step on other custom nodes. If something else breaks afterward, that's the first thing to check.
Common issues
- Similarity score looks "too high" or "too low." Blame the naive mean-pooling, not a bug. If you need calibrated scores, use the
sentence-transformerslibrary in a custom node instead - this one is a directional indicator. - Model download stalls on first run. Normal; it's pulling MiniLM from the Hub to
~/.cache/huggingface. Watch the console. - Every run re-loads the model. The pack has a cached pipeline loader that these nodes don't actually call, so expect a few seconds of load per execution. Minor, but it's why repeated runs feel laggy.
It's not the deepest node in the pack, but it's one of the few whose output you can actually act on. If you've ever wanted your graph to decide things for itself, this is a good starting block.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| text1 | STRING | — | |
| text2 | STRING | — | |
| model_name | STRING | sentence-transformers/all-MiniLM-L6-v2 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| similarity_score | FLOAT | — |