Tag Normalize and Combine
Merge Two Taggers' Output Into One Sane Prompt
- scores_1
- scores_2
- deduped_tags
- normalized_scores
If you've ever run two captioning models over the same image and gotten two different tag lists, you know the problem this node exists to solve: which one do you trust? UC_TagNormalizeCombine takes two tag strings, normalizes both sets' confidence scores to a common scale, merges them, deduplicates, and returns one prompt sorted by confidence - highest-confidence tags first.
Why you'd reach for it
The use case is two taggers disagreeing. One WD14-style tagger might score 1girl at 0.99 while a second model scores woman at 0.95 - and both are "right." Instead of eyeballing the overlap, you feed both tag strings (plus their score dictionaries if you have them) and get back a single deduplicated list where each tag keeps its best score and everything is ordered by confidence. That's a much better input for an SDXL-lineage anime model that reads comma-separated tags in order of importance than either raw tagger output alone.
It slots into the same niche as the pack's text utilities - caption cleaning, dataset prep, prompt building - and it's genuinely handy for training-data pipelines where consistent tag ordering matters.
How it works
Each tag string is split on commas and stripped. Scores, if provided as dicts (or JSON strings) via scores_1/scores_2, are min-max normalized into the [0.000001, 0.999999] band so the two taggers' confidence scales become comparable - a 0.8 from one model isn't implicitly better than a 0.7 from another; both are rescaled to their own set's range. If no scores are given, it synthesizes an even distribution (highest to lowest by position) so ordering still works.
Then it merges: tags appearing in both sets keep the higher normalized score, tags from either set are added, and the whole thing is sorted by score descending. Outputs:
- deduped_tags - the tags joined with ", ", best score order.
- normalized_scores - a dictionary of tag → normalized score, if you want the scores downstream.
Installing it
It's in ComfyUI-UtilsCollection by silveroxides:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-UtilsCollection
Restart ComfyUI, or install "ComfyUI-UtilsCollection" via Manager. The pack's dependencies are opencv-python and typing-extensions; this node is pure Python string/dict work.
The traps
First, "normalized" is per-set, not global: if one tagger is uniformly confident and the other is uniformly hesitant, min-max scaling can promote a lukewarm tag from the hesitant tagger above a solid tag from the confident one. It's a reasonable heuristic, not a calibrated fusion. Second, it dedupes by exact string match - 1girl and 1 girl won't collide, so you can still get near-duplicate tags that a human would merge. And if your tags come from a model that emits (tag:0.9) syntax, strip the weights first or they'll be treated as literal tag text.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| tags_1 | STRING | — | |
| tags_2 | STRING | — | |
| scores_1opt | * | Dictionary of scores for tags_1 | |
| scores_2opt | * | Dictionary of scores for tags_2 |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| deduped_tags | STRING | — |
| normalized_scores | * | — |