String Similarity Node
Text similarity inside ComfyUI
- STRING
Nearly every ComfyUI node makes images. This one makes a judgment call about text. If your workflow does any OCR, captioning, or validation - checking that a VLM actually read the right thing off the screen - you eventually need to know how wrong the machine was. StringSimilarity gives you a number for that, without you eyeballing output after output.
It's one node, eight algorithms, two text inputs, one answer. You feed the reference text into actual_text, the text you're grading into ocr_text, pick an algorithm, and it returns a formatted report. That's the whole shape of it, and it slots into a text pipeline the same way a LoRA slots into a checkpoint.
How it works
Half of this is cheap and runs on CPU. Levenshtein and SequenceMatcher (from Python's stdlib) are pure edit-distance math. Jaccard and Cosine tokenize with scikit-learn's CountVectorizer and compare word sets. WER and CER are the same Levenshtein dynamic-programming table, but run over words and characters instead of the whole string - that's the classic speech/OCR quality metric, normalized by reference length.
The two SentenceTransformer options are the heavyweight. They load a real embedding model on first use - all-mpnet-base-v2 (roughly 420 MB) for accuracy, all-MiniLM-L6-v2 (roughly 90 MB) for speed - then embed both texts and return cosine similarity of the vectors. The model gets downloaded once from HuggingFace, then cached and kept in memory for the session.
The inputs and output that matter
- actual_text - your reference or ground truth.
forceInputis on, so you can't type here; wire in a string. - ocr_text - the text you're comparing, e.g. the OCR output or a caption to validate.
- algorithm - the 8-way dropdown: Levenshtein, SequenceMatcher, Jaccard, Cosine, WER, CER, SentenceTransformer-MPNET, SentenceTransformer-MiniLM.
The single STRING output is a formatted, human-readable block that echoes both texts and prints the score (e.g. Levenshtein Distance: 1\nLevenshtein Similarity: 0.91). Note the shape of that: it's a report string, not a numeric port. Wire it into a text display or log; don't expect to branch on the score directly without parsing it first.
Installing it
Easiest path is ComfyUI Manager - search "ComfyUI-String-Similarity" and let it pull the deps. Or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/gabe-init/ComfyUI-String-Similarity
pip install -r requirements.txt
Then restart ComfyUI. The requirements are Levenshtein, scikit-learn, numpy, and sentence-transformers.
Where people get burned
- Both inputs are
forceInput. You cannot type text into the node. Grab a string-output node or a primitive and wire text in - a beginner's first run usually fails right here. - The semantic options need a one-time model download. If
all-mpnet-base-v2download fails on first use, check your internet, then retry; it caches after that. MiniLM is the sensible default unless you genuinely need paraphrase-level comparison. - The dependency is heavy whether you want it or not.
sentence-transformersis imported at module load, so it pulls torch in even if you only ever use Levenshtein. Annoying, but it's the price of the two semantic options being in one node. - Empty input returns an error string, not a crash -
Error: Both actual_text and ocr_text must be provided and non-empty.Handy, but easy to miss if you're scripting around it.
For pure OCR QA, WER and CER are what you'd reach for. For typo-level checks, Levenshtein. And the embedding options? Only when you actually need "did the machine understand the same idea" rather than "did it spell it right."
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| actual_text | STRING | — | |
| ocr_text | STRING | — | |
| algorithm | COMBO | 8 options: Levenshtein, SequenceMatcher, Jaccard, Cosine, WER, CER, +2 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |