ComfyUI Node

Tag Frequency Weighter

Let Danbooru's tag counts set your prompt weights

By L33chKing·Created about a year ago·Updated about a year ago· 0
Tag Frequency Weighter
    • output_prompt
    input_prompt2girls, megumin, from above
    min_value1.0
    max_value1.5
    calculate_averagefalse
    preserve_underscores_in_outputfalse
    pivotlog10(avg)
    ignore_below_tag_count0
    ignore_above_tag_count2000
    debugfalse

    If you generate anime with an Illustrious or NoobAI checkpoint, you know the drill: hand-wrap the niche tag in (tag:1.4) because the model barely registers it at plain weight, while 1girl sits at 1.0 doing all the heavy lifting. Tag Frequency Weighter is the "stop hand-tuning that" node. It looks up every tag in your prompt in a real Danbooru post-count table - 719,000 tags, shipped right in the repo - and rewrites the prompt so rare tags get a boost and absurdly common ones get dialed down. Single prompt string out, no API, no key.

    Why the idea works: Danbooru-trained models learned 1girl from 6.8 million images; it doesn't need your help. A tag that only shows up a few thousand times has a weaker grip on cross-attention, and a couple tenths of emphasis is often the difference between it appearing and getting ignored. Weighting by rarity is as old as tag prompting itself; this node just makes it automatic instead of a per-prompt judgment call.

    How it works

    The pack ships a ~13 MB CSV (danbooru_tags_post_count.csv) mapping each tag to its post count. On first use, the node loads it into memory and computes global stats - average count, min/max, and the mean of log10 counts - then writes them to tag_stats_cache.json next to the node so later runs are cheap. For each plain tag it:

    • looks up the post count and takes log10 (so the 1girl-scale giants don't flatten the whole range),
    • finds the rarest and most common tag in your current prompt and scales against those,
    • maps each tag onto your min_valuemax_value range around a pivot: common tags trend toward min_value, rare tags toward max_value,
    • and if the result rounds to 1.00, leaves the tag completely alone.

    Output is standard weighted-paren syntax - (tag:1.3), or the weight-after-comma (tag, :1.3) form inside a comma list - so it plugs straight into a CLIPTextEncode positive. Existing (...) groups and any tag not in the table pass through untouched.

    The inputs that matter

    • input_prompt - the tags to reweight, comma-separated.
    • min_value / max_value - the low and high end of the output range. Defaults of 1.0 / 1.5 are a sane starting point.
    • ignore_below_tag_count / ignore_above_tag_count - count thresholds; tags outside the band are left unchanged.
    • pivot - log10(avg) (default) or x_avg; the "neutral" point everything is measured against.
    • debug - prints each tag's count to the console when you're wondering why one didn't move.

    The gotcha most people hit first: the default ignore_above_tag_count is 2000, and min_value defaults to 1.0. That means the shipped demo prompt - 2girls, megumin, from above - comes back byte-for-byte, because all three tags clear 2000 posts (megumin alone has 9,174). Out of the box this is really a "boost the rare stuff" node: tags above ~2000 posts get skipped, and between the pivot and min_value, only tags rarer than roughly 500 posts actually get pushed past 1.25. To get the full behavior - common tags actively downweighted - set ignore_above_tag_count to 0 and drop min_value below 1.0 (0.8-ish is a reasonable floor).

    Install

    ComfyUI Manager (search "Tag Frequency Weighter") or the one-liner:

    cd ComfyUI/custom_nodes
    git clone https://github.com/L33chKing/comfyui-tag-frequency-weighter
    

    Then restart ComfyUI. No model download, no Python dependencies - the CSV is committed to the repo, which is exactly why install is painless. The node shows up under the "prompt" category.

    Troubleshooting & when to skip it

    • It only makes sense on Danbooru-tag models - Illustrious, NoobAI, WAI, Pony. On Flux or any LLM-encoded model, (tag:1.3) gets discarded by the text encoder, so this node is busywork. Check what your checkpoint is actually built on first.
    • The table is Danbooru, not e621, so Pony's furry and score_ vocabulary won't resolve - those tags just pass through unchanged, which is harmless.
    • The default preserve_underscores_in_output is off, so long_hair becomes long hair - and that's the right call, since Danbooru-trained models are prompted with spaces, not underscores.
    • If the node dir is read-only, the cache write fails silently and it just recomputes; the only cost is startup time.
    • Flip calculate_average on once (or run print_csv_stats.py in the node folder) to regenerate or eyeball the stats. First load of a session parses the whole CSV - a second or two, then it's cached in memory.
    Categoryprompt

    Inputs (9)

    NameTypeDefaultDescription
    input_promptSTRING2girls, megumin, from abovePrompt to reweight; commas/spacing preserved.
    min_valueFLOAT1.00–5Lower bound for output weights; popular tags trend toward this.
    max_valueFLOAT1.50–5Upper bound for output weights; rare tags trend toward this.
    calculate_averageBOOLEANfalseRecompute averages from CSV now and update cache.
    preserve_underscores_in_outputBOOLEANfalseKeep underscores in wrapped tags (do not replace with spaces).
    pivotCOMBOlog10(avg)Neutral pivot (1.0): log10(avg) or mean of log10 counts (x_avg).
    ignore_below_tag_countINT00–7000000Leave tags with counts below this unchanged.
    ignore_above_tag_countINT20000–7000000Leave tags with counts above this unchanged.
    debugBOOLEANfalsePrint per-tag counts while processing (verbose).

    Outputs (1)

    NameTypeDescription
    output_promptSTRING