NeuralBooru
Stop hand-writing tag soup — let a local LLM do it, then verify every tag is real
- prompt
- dropped_tags
- tags
If you've ever wanted to describe a scene in plain English and have it come out as proper Danbooru tags for an Illustrious or NoobAI checkpoint, this is the node that finally makes it click. You type "a vampire girl with fangs in a dark classroom at night," and out the other end comes 1girl, vampire, fangs, dark, classroom, night, standing - real tags your anime model was actually trained on, not tag-shaped prose that only sort of works.
The key word is real. Most tag generators are specialized fine-tunes like TIPO or DanTagGen that bake the vocabulary into their weights. NeuralBooru goes the other way: it's a model-agnostic adapter. A general LLM proposes tags, and a whitelist of ~140,000 actual Danbooru tags decides what survives. The LLM proposes, the whitelist disposes.
How it works
NeuralBooru is a prompt converter, not a model. It calls any OpenAI-compatible server you already run - LM Studio, Ollama, llama.cpp, vLLM - asking a chat model to turn your user_prompt into comma-separated tags. The bundled system_prompt (editable) does the steering: lowercase, no quality tags, real Danbooru style, 1girl/1boy for people. The model defaults to qwen/qwen3-1.7b - a good call: small enough to run off the GPU and it understands booru tagging.
Then the fun part. Every candidate tag goes through a validation pipeline against the bundled vocabulary (data/danbooru.csv, ~140k real tags):
- Exact match
- Alias remap (
blonde→blonde hair) - Word-form fix (
smirking→smirk) - Sub-phrase recovery (
black crop topyieldscrop top) - Optional fuzzy remap for near-misses (off by default)
- Drop whatever's left
Dropped tags land on dropped_tags and get reported in the console, so you always see what was filtered. Survivors are reordered Danbooru-style - people counts, character, copyright, artist, general, meta - because booru-trained models respond to that order, then wrapped in a quality-tag template.
That validation layer isn't there by accident. The author posted the node to r/comfyui and got the most useful critique imaginable: "I don't want danbooru-style prompts, I want danbooru tags... dark atmosphere is not a tag." A 1.7B general model can't guarantee a tag exists - it can only make things look tag-shaped. The whitelist closes exactly that gap.
The inputs that matter
user_prompt- your plain-English description. The one thing you actually type.prompt_template/template_preset- the wrapper around your tags, with{prompt}as the placeholder. One-click presets for Illustrious, Pony, Animagine XL, and NovaAnimeXL. Don't reinvent the wrapper for your model family; just pick it.lm_studio_url- server address.http://localhost:1234for LM Studio,http://localhost:11434for Ollama (auto-detected).validate_tagsandstrict_tags- both on by default; this is what makes the output real tags.seed- change it to re-roll a fresh tag variation (there's a randomize control on the widget).on_error- set touse_input_textif you'd rather get an image from your raw description than have the workflow die on a dead server.
The prompt output feeds straight into a CLIP Text Encode (Positive) node - a single STRING, nothing exotic. tags is the validated tags without the template, handy for display or metadata. Wire dropped_tags to a PreviewAny node to see what got filtered.
Installation
It installs like any custom node, and refreshingly there's nothing to pip-install afterward - the whole pack is pure Python stdlib. Zero dependencies is a shipped feature.
Via ComfyUI Manager: search NeuralBooru and install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ChrisJohnson89/ComfyUI-NeuralBooru
Restart ComfyUI and the node appears under the NeuralBooru category. The only "model file" you need is the LLM itself: load Qwen3-1.7B in LM Studio and enable its local server on port 1234. Text gen doesn't touch your image VRAM, so a Mac or a second machine works fine.
Common issues
- Connection refused / dead server - the node fails loudly with a clear message, which is honestly the right behavior. If you don't want a hard stop,
on_error=use_input_textfalls back to your description. - "It's dropping tags!" - that's the design, the precision tradeoff. Someone in the release thread reported long prompts lose tags under strict validation. If it's too aggressive, lower the temperature, enable
fuzzy_cutoffaround 0.9, or turnstrict_tagsoff. - Brand-new tags missing - the vocabulary is a snapshot from the tagcomplete project, so very recent Danbooru tags won't resolve until a refresh script ships.
- Ollama acting different - the node probes
/api/versionand switches to Ollama's native API automatically; just pointlm_studio_urlat the right port.
If you want to peek at the raw LLM output before the filter, or run validation without an LLM at all, that's exactly what the two split nodes in the same pack - NeuralBooru LLM and NeuralBooru Validator - are for.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| user_prompt | STRING | describe your scene here | Plain-English scene description to convert into tags. |
| system_prompt | STRING | You convert a scene description into Danbooru tags for an anime image model. Output ONLY lowercase tags separated by commas. No sentences, no explanations, no numbering, no category words. Write attributes in real Danbooru tag style: 'blue eyes' not 'eye color blue', 'black hair' not 'hair color black'. Use spaces, not underscores. Use 1girl, 1boy, 2girls, etc. for people. Do NOT add quality tags like masterpiece, best quality, absurdres, score_9 - those are added separately. Example input: a cheerful blonde girl in a red dress on a beach at sunset Example output: 1girl, blonde hair, long hair, smile, red dress, beach, sunset, ocean, sky, cloud, standing Example input: a lone samurai in the rain at night Example output: 1boy, solo, samurai, japanese clothes, katana, rain, night, wet, serious, outdoors Now output tags only for the next description. /no_think | Instructions for the LLM. Edit to change tagging behavior. |
| prompt_template | STRING | masterpiece, best quality, amazing quality, 4k, very aesthetic, high resolution, ultra-detailed, absurdres, newest, scenery, {prompt}, BREAK, depth of field, volumetric lighting | Final prompt wrapper; {prompt} is replaced with the validated tags. If {prompt} is missing, tags are appended. |
| model | STRING | qwen/qwen3-1.7b | Model id as the server reports it (see /v1/models). |
| enable_thinking | BOOLEAN | false | Allow reasoning-mode models to think before answering. Slower; output is cleaned either way. |
| temperature | FLOAT | 0.400–2 | — |
| max_tokens | INT | 50050–2000 | — |
| seed | INT | 00–4294967295 | Change to re-roll the LLM call; also sent to the API. |
| lm_studio_url | STRING | http://localhost:1234 | Base URL of any OpenAI-compatible server: LM Studio (:1234), Ollama (:11434), llama.cpp, vLLM. |
| validate_tags | BOOLEAN | true | Check every tag against the real Danbooru vocabulary. |
| strict_tags | BOOLEAN | true | Drop candidates that match no real tag. Off keeps them raw. |
| fuzzy_cutoff | FLOAT | 0.000–1 | Remap near-miss tags by similarity (0.8+ recommended). 0 disables fuzzy matching. |
| min_post_count | INT | 00–1000000 | Drop tags with fewer Danbooru posts than this. 0 keeps all. |
| max_tags | INT | 00–200 | Keep at most this many tags. 0 means no limit. |
| timeoutopt | INT | 12010–600 | Seconds to wait for the LLM response. |
| api_keyopt | STRING | Optional Bearer token for servers that require auth (vLLM, remote endpoints). Leave empty for LM Studio/Ollama. | |
| exclude_categoriesopt | STRING | Tag categories to drop, comma-separated: artist, character, copyright, meta, general. | |
| on_erroropt | COMBO | raise | raise: fail the workflow with a visible error. use_input_text: put your raw description in the template. |
| template_presetopt | COMBO | custom | Quality-tag wrapper for common model families. custom uses the prompt_template field above. |
| sort_tagsopt | BOOLEAN | true | Reorder tags Danbooru-style: people counts, character, copyright, artist, general, meta. Booru-trained models respond to this order. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | Validated tags wrapped in the prompt template, for your CLIP encoder. |
| dropped_tags | STRING | Candidates that failed validation, comma-separated. |
| tags | STRING | The validated tags alone, without the template. |