Auto-tagger: GPU and models
last updated
The auto-tagger guide covers installing and running taggers. This page is about making them faster with a GPU, bringing your own models, and the settings that only live in files.
Running on a GPU#
Tagging runs on the CPU by default. To use a GPU, pick an execution
provider under Settings -> Auto-Tagger (or set
tagger.execution_provider):
| Provider | For |
|---|---|
cuda |
NVIDIA |
tensorrt |
NVIDIA, with TensorRT |
directml |
any Direct3D 12 GPU on Windows |
openvino |
Intel GPUs |
coreml, coremlv2 |
Apple hardware |
monbooru checks the provider when you save and refuses it, with an error saying why, when the library or the device isn’t there.
The Windows downloads already carry a runtime built with DirectML, so
directml works with nothing else to install. Every other provider
needs an ONNX Runtime built for it: take one from the
ONNX Runtime releases
(1.21 or newer) and either put it next to the program in place of the
onnxruntime.dll or libonnxruntime.so that came with it, or point
ORT_LIB_PATH at it. The libraries the provider itself needs go in
the same folder. CUDA also wants CUDA 12 and cuDNN 9 installed.
On Docker, the default image is CPU-only. Use the -cuda image tag
for NVIDIA or -openvino for Intel, and pass the GPU into the
container the usual way; the compose file has a commented example for
each. An Intel GPU also needs /dev/dri passed in and the container
added to the host’s render group. Both tags are amd64 only.
The first GPU run on a new machine spends a few minutes compiling. The
result is cached under the data folder (.nv-cache/ for CUDA,
.openvino-cache/ for OpenVINO), so keep that folder on a persistent
volume and later starts are quick.
Settings -> Auto-Tagger -> Parallel workers (tagger.parallel,
default 4) is how many images are prepared and tagged at once. On a
GPU, raise it if the GPU sits idle waiting for images. DirectML tags
one image at a time whatever you set.
More models#
The monbooru-plugins
registry lists every tagger monbooru supports in TAGGERS.md, each
one a folder under taggers/. To add one, copy its folder into the
models folder: it shows up in Settings -> Auto-Tagger with an
Install button to download the weights, which the folder does not hold.
A registry folder holds a model.json (the description, the default
thresholds and the files to download), and when the model needs them
a profile_default.json and a dispatch_default.json. Those two are
the stock settings: a newer copy of the folder can replace them, while
your own changes go in tagger.json and dispatch.json beside them.
Your own models#
Other ONNX tagging models may work too. Give each one its own
subfolder in the models folder, holding the .onnx weights (and the
.onnx.data file next to them, when the model ships one) and one
label file:
tags.csv: a header row, thenindex,name,categoryper row. The category is a WD14 category number (0general,4character, …) or a category name.tags.txt: one label per line, allgeneral.- a
.jsonlabel file, described by thetagger.jsonbelow.
The new tagger shows up in Settings -> Auto-Tagger on the next page load.
monbooru works out how to feed .csv (WD14-style) and .txt
(JoyTag-style) models on its own. For anything else, add a
tagger.json next to the model saying how its authors feed it. Every
field is optional and only restates what differs from that guess:
| Field | Values |
|---|---|
input_size |
the square side in pixels; leave it out to read it from the model |
layout |
nhwc or nchw |
channels |
rgb or bgr |
normalize |
none, div255, imagenet, clip, or mean_std with norm_scale, norm_mean and norm_std: each pixel becomes (value / norm_scale - norm_mean) / norm_std |
pad |
white_square, mean_color_aspect or fill with fill_color as [r, g, b] |
activation |
logits when the model’s scores still need a sigmoid, sigmoid_in_model when they don’t |
label_format |
csv, txt or json |
label_json |
where a .json label file keeps its labels: shape is index_map ({"0": "tag", ...}), list (["tag", ...]) or blocks ([{"name": category, "offset": n, "tags": [...]}]), path the dotted way to it, and category_path the dotted way to a tag-to-category object |
category_scheme |
wd14_numeric, name_string (the label file names the categories) or single_general |
category_map |
renames the label file’s categories, {"style": "artist"} |
output_index |
which of the model’s outputs holds the scores, when it has several |
Here’s an example with PixAI’s tagger. Its runner pads to a black square,
maps pixels to -1..1, applies a sigmoid, and keeps its labels in
tags.json as one block per category, the style block being
artists:
{
"version": 1,
"profile": {
"layout": "nchw", "channels": "rgb",
"normalize": "mean_std", "norm_scale": 255,
"norm_mean": [0.5, 0.5, 0.5], "norm_std": [0.5, 0.5, 0.5],
"pad": "fill", "fill_color": [0, 0, 0],
"activation": "logits",
"label_format": "json",
"label_json": {"shape": "blocks", "path": "categories"},
"category_scheme": "name_string",
"category_map": {"style": "artist"}
}
}
Its ratings are labelled rating:g and so on, so it also needs the
four dispatch.json rules below that rename them. The
profile_default.json files in the registry’s folders are more
examples.
Label rules (dispatch.json)#
The mappings tab of a tagger’s Configure dialog is the easy way to
change where a label goes. It saves your rules as dispatch.json next
to the model, and you can also write or share that file by hand:
{
"version": 1,
"rules": [
{ "source": "monochrome", "category": "medium" },
{ "source": "ugly_label", "category": "" },
{ "source": "twitter_username", "category": "meta", "name": "twitter" }
]
}
sourceis the label the model emits.categoryis where it goes. An empty string drops the label.name, if set, renames the tag. A rule intoratinghas to end on one of the four ratings.
monbooru ships rules of its own for the suggested taggers, taken from
their registry folders, and any other model from the registry brings
its own as dispatch_default.json. Your file
goes on top: a rule for the same label replaces the shipped one, a new
label is added. Reset removes your file and keeps the shipped
rules. The Export tab of the Configure dialog shows the
merged result, ready to copy over the folder’s dispatch_default.json
in a pull request to the registry or to drop next to model.onnx on
another install.
Memory#
A model stays loaded for 15 minutes after its last run, then unloads
to free RAM and VRAM. Settings -> Auto-Tagger has the delay
(tagger.idle_release_after_minutes); 0 unloads right after each
run. Settings -> Maintenance -> Free memory unloads it on the
spot.
Tagging runs in a separate tagger-worker process, so unloading gives
everything back to the system, GPU libraries included. If that
process gives you trouble, MONBOORU_TAGGER_BACKEND=inproc runs
tagging inside monbooru itself instead.
Videos and archives#
A video is tagged from five frames and an archive from its pages, and
a label has to show up on several of them to stick.
tagger.aggregation.min_hit_fraction (default 0.05) sets what share
of the frames that is, never fewer than 2 or more than 10 frames. Set
it to 0 and one frame is enough.
Environment variables#
| Variable | What it does |
|---|---|
MONBOORU_TAGGER_EXECUTION_PROVIDER |
Overrides tagger.execution_provider. |
MONBOORU_TAGGER_BACKEND |
inproc runs tagging inside monbooru instead of a separate process. |
MONBOORU_TAGGER_WORKER_LOG |
Log level (warn / info / debug) for the tagger process only. Unset, it follows monbooru’s own level. |
MONBOORU_TAGGER_DIRECTML_DEVICE_ID |
Which GPU DirectML uses, by adapter number. Defaults to 0, which on a laptop is often the integrated GPU rather than the fast one. |
ORT_LIB_PATH |
Full path to the ONNX Runtime library, when it isn’t next to the program or on the system library path. |
CUDA_CACHE_PATH |
Where CUDA keeps its compiled cache. Defaults to .nv-cache/ in the data folder. |
