WD14 Tagger
Read the booru tags back out of a picture
- image
- tags
The prompt is already in the image, roughly
If you generate on Illustrious, NoobAI or Pony, your prompt was a list of Danbooru tags - 1girl, solo, long_hair, looking_at_viewer. Those models were trained on tagged booru images, which is why exact tags beat sentences on them. A WD14 tagger runs that mapping backwards: it looks at a picture and hands you the tags that most likely produced it.
Three jobs, all real. Reverse-engineering a prompt from a reference image you want to riff on. Building a LoRA dataset: WD14 tags are the caption format for the Illustrious/Pony/NoobAI lineage, the same tags kohya and ai-toolkit read out of the sidecar .txt next to each image. And seeding img2img when you have no idea where to start.
Be clear about what it is not. WD14 is a classifier over a fixed vocabulary of ~9,000 booru tags; it does not write descriptions. For that the community answer is to run a describer and a tagger - Florence-2 for the sentence, WD14 for the tags, concatenated - because Florence cannot emit hair_between_eyes and WD14 cannot emit a scene.
What it's actually doing
The download is two files: an ONNX classifier and selected_tags.csv, which is just the model's output layer written out in order (tag name, category). The node resizes your image so its longest side is 448, pads it to a 448×448 white square, swaps RGB to BGR, and runs it. One forward pass, ~9,000 probabilities.
Then it reads that CSV to know what each row means. Only three categories ship in the v2 models: 0 general, 4 character, 9 rating. The code starts sweeping at the first general row, which means the four rating tags (general, sensitive, questionable, explicit) are skipped - it will not tell you the rating of an image.
Two thresholds, and characters are emitted before general tags. That ordering is a small gift: earlier tags get stronger attention in a prompt, so the named character lands first. Underscores become spaces on the way out, so the output is paste-ready.
The inputs that matter
image - the IMAGE batch to tag.
model - a dropdown built by scanning ComfyUI/models/wd14 at load time. Nothing ships with the pack, so on a fresh install this list may only show the fallback name and then fail with a missing-file error. More on that below.
threshold (0.35 default) - the general tag cutoff. Lower means more tags and more junk (absurdres, a stray barefoot); higher trims back toward the handful you'd have written yourself. 0.25–0.35 is where most people live.
character_threshold (0.85 default) - deliberately higher and separate, because character predictions are spiky: a wrong name is worse than a missing one. If a character comes out unnamed, this is the dial.
exclude_tags - comma-separated, and here's the trap: it matches the raw CSV name, which uses underscores. long hair won't match; long_hair will. Lowercase, whitespace-trimmed.
The single output is tags, a STRING - and it's a list, one entry per image in the batch. That's the good news: wire it into a CLIP Text Encode (right-click the text widget → Convert to input) and the graph runs once per image, instead of handing every image the concatenated tags of the whole batch, which is the standard complaint about batch tagging. Results are cached per image-plus-settings, so re-queues are instant.
Installing it, and the model nobody downloads for you
ComfyUI Manager → search Practical-Tools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/wenchengxiang/ComfyUI-Practical-Tools
Restart. The only dependency is onnxruntime. What the pack does not do is fetch a tagger - you supply it, and the two files must share a basename:
mkdir -p ComfyUI/models/wd14
cd ComfyUI/models/wd14
curl -LO https://huggingface.co/SmilingWolf/wd-v1-4-moat-tagger-v2/resolve/main/model.onnx
curl -LO https://huggingface.co/SmilingWolf/wd-v1-4-moat-tagger-v2/resolve/main/selected_tags.csv
mv model.onnx wd-v1-4-moat-tagger-v2.onnx
mv selected_tags.csv wd-v1-4-moat-tagger-v2.csv
Any base name works - the dropdown lists every .onnx with a matching .csv beside it - so a wd-v1-4-convnext-tagger-v2 or wd-swinv2-tagger-v3 installs the same way.
Where people get burned
Blank dropdown, then FileNotFoundError: .../models/wd14/wd-v1-4-moat-tagger-v2.onnx. You downloaded the stock model.onnx/selected_tags.csv names and skipped the rename, so nothing matched and the node fell back to the default name. Both files, same stem.
It's running on CPU. requirements.txt installs plain onnxruntime, which has no CUDA execution provider, so the provider ladder falls through to CPU. For one image you won't notice; for a 2,000-image dataset you will. Swapping in onnxruntime-gpu gets you the GPU path, but it needs CUDA/cuDNN built for your torch, and if both packages end up installed the CPU one can win - check ort.get_available_providers() before assuming you got the speedup.
Threshold 0.35 looks broken. It isn't; it's just chatty. Tag spam at the top of your prompt is the most common reason people decide WD14 "doesn't work" and go back to typing prompts by hand.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model | COMBO | wd-v1-4-moat-tagger-v2 | 1 options: wd-v1-4-moat-tagger-v2 |
| threshold | FLOAT | 0.350–1 | — |
| character_threshold | FLOAT | 0.850–1 | — |
| exclude_tags | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| tags | STRING | — |