GraySoft
Projects Models Compare Cloud benchmarks FAQ Download guIDE →
Model Intelligence Sheet

cooperdk/BooruNL-0.8B-GGUF overview

BooruNL 0.8B A small, fast, uncensored model that converts a plain English description of a character or scene into a clean list of authorized danbooru tags . …

ggufquantizeddanbooruimage-taggingstable-diffusiontext-to-imagellama-cpptext-generationenbase_model:Qwen/Qwen3.5-0.8B-Basebase_model:quantized:Qwen/Qwen3.5-0.8B-Baselicense:apache-2.0endpoints_compatibleregion:usconversational

Runs locally from ~504.8 MB disk (4 GB VRAM class GPUs with llama.cpp / guIDE).

Downloads
0
Likes
0
Pipeline
text-generation
Author

Repository Files & Downloads

3 GGUF files detected
Direct downloads for local inference
FileTypeQuantizationSizeLink
BooruNL-0.8B-Q4_K_M.ggufGGUFQ4_K_M504.8 MBDownload
BooruNL-0.8B-Q6_K.ggufGGUFQ6_K600.6 MBDownload
BooruNL-0.8B-Q8_0.ggufGGUFQ8_0774.2 MBDownload

Model Details

Model IDcooperdk/BooruNL-0.8B-GGUF
Authorcooperdk
Pipelinetext-generation
Licenseapache-2.0
Base modelQwen/Qwen3.5-0.8B-Base
Last modified2026-07-10T04:06:50.000Z

Model README

---

license: apache-2.0

language:

  • en

base_model: Qwen/Qwen3.5-0.8B-Base

pipeline_tag: text-generation

tags:

  • gguf
  • quantized
  • danbooru
  • image-tagging
  • stable-diffusion
  • text-to-image
  • llama-cpp
  • text-generation

---

BooruNL-0.8B

A small, fast, uncensored model that converts a plain English description of a character or scene

into a clean list of authorized danbooru tags. Fine-tuned from

Qwen3.5-0.8B-Base on 124,000 human-labelled

description → tag pairs, covering the full tag vocabulary including explicit content.

Model files

| File | Size | Notes |

|:-----|-----:|:------|

| BooruNL-0.8B-Q6_K.gguf | 600 MB | Recommended. ~15× faster than HF, within 1% quality. |

| BooruNL-0.8B-Q8_0.gguf | 800 MB | Highest fidelity GGUF; negligible quality gain over Q6_K. |

| BooruNL-0.8B-Q4_K_M.gguf | 500 MB | Smallest; slight quality loss on complex prompts. |

| BooruNL-0.8B-mmproj-f16.gguf | 205 MB | Vision encoder (F16), extracted from the base model. Not useful for tag generation — see note below. |

| model.safetensors (HF) | 1.6 GB | Full bfloat16 weights for fine-tuning or research. |

Quick start

GGUF (recommended)

from llama_cpp import Llama

llm = Llama(model_path="BooruNL-0.8B-Q6_K.gguf", n_gpu_layers=-1, n_ctx=2048)

prompt = """### Input:
Tag this prompt: A gothic punk girl with two-tone black and blonde hair in twin buns, yellow eyes, \
spiked choker, frilly black sailor-collar shirt, two-tone cardigan, red plaid skirt, \
torn fishnet thigh-highs, lying on her back on rumpled bed sheets.
### Tags:
"""

result = llm(prompt, max_tokens=256, temperature=0.05, repeat_penalty=1.3, echo=False)
print(result["choices"][0]["text"])

Output:

1girl, solo_focus, goth_fashion, punk, black_hair, blonde_hair, multicolored_hair, twin_buns,
two-tone_hair, yellow_eyes, piercing, ear_piercing, earrings, spiked_choker, choker, cardigan,
frilled_shirt, plaid_clothes, plaid_skirt, red_skirt, fishnets, thighhighs, on_back, lying

HuggingFace transformers

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "cooperdk/BooruNL-0.8B"  # or local path
tok   = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id, torch_dtype=torch.bfloat16, attn_implementation="sdpa"
).to("cuda").eval()

prompt = """### Input:
Tag this prompt: A solo slim red-haired girl with freckles and very small breasts, wearing a maid outfit.
### Tags:
"""

ids = tok(prompt, return_tensors="pt").to("cuda")
with torch.no_grad():
    out = model.generate(**ids, max_new_tokens=256, do_sample=False,
                         repetition_penalty=1.3)
tags = tok.decode(out[0][ids.input_ids.shape[1]:], skip_special_tokens=True).strip()
print(tags)

Output:

1girl, solo, maid, red_hair, breasts, freckles, small_breasts

Prompt format

The model accepts any natural instruction prefix. All of the following work:

Tag this prompt: <description>
Convert this to danbooru tags: <description>
danbooru tags for: <description>
<description>         ← bare description also works

The output is a clean comma-separated tag list with no preamble. Rating tags (rating:safe,

rating:explicit, etc.) are not emitted — the model was trained without them in the target, since

rating is metadata rather than appearance. Add your preferred rating tag separately.

JSON object output

The model can also emit a zone-keyed JSON object that groups tags by semantic category:

llm = Llama(model_path="BooruNL-0.8B-Q6_K.gguf", n_gpu_layers=-1, n_ctx=2048)

prompt = """### Input:
Output as JSON. Convert this to danbooru tags: A solo slim red-haired girl with freckles \
and very small breasts, wearing a maid outfit.
### Tags:
"""

result = llm(prompt, max_tokens=512, temperature=0.05, repeat_penalty=1.3, echo=False)
print(result["choices"][0]["text"])

Output:

{"RATING": ["s"], "SUBJECT": ["1girl", "solo"], "HAIR": ["red_hair"], "BODY": ["breasts", "freckles", "small_breasts"], "ATTIRE_STATE": ["slim"]}

A richer description populates more zones, including STYLE, SCENE, PROP, ACTION, and META:

### Input:
Turn this description into danbooru tags, output as JSON:
A sole female kneeling on a beach under a blue sky with clouds and a mountainous horizon during
the day, with a full body official art second-party source shot at a dutch angle. She has long
light purple hair in low twintails with a white bow, a hair bow, a white flower, a white
headwear, a yellow scrunchie, a purple ribbon, a white ribbon, a wrist scrunchie, and a leg
ribbon. She wears a frilled one-piece swimsuit with frills, a sun hat with a hat ribbon, and a
white bow. Her bare shoulders are exposed, her medium breasts are visible, her navel is covered,
and she is barefoot with a thigh shown. She has blue eyes and an open-mouth smile with a blush,
looking at viewer while doing a hat tug with her hands on hat. The scene includes a beach chair,
a beach umbrella, a bird, flower petals, a sand sculpture, a sandcastle, a ball, a beachball,
a bucket, and flowers.
### Tags:
{"RATING": ["s"], "SUBJECT": ["1girl", "solo"], "STYLE": ["swimsuit"], "HAIR": ["light_purple_hair", "long_hair", "low_twintails", "twintails"], "FACE": ["blue_eyes"], "BODY": ["breasts", "medium_breasts", "thighs"], "ATTIRE": ["bow", "hair_bow", "hat", "hat_ribbon", "purple_ribbon", "ribbon", "scrunchie", "sun_hat", "white_bow", "white_flower", "white_headwear", "yellow_scrunchie", "frilled_one-piece_swimsuit", "frills", "one-piece_swimsuit", "white_ribbon", "wrist_scrunchie", "leg_ribbon"], "ATTIRE_STATE": ["bare_shoulders", "barefoot", "covered_navel"], "STATE": ["hands_on_headwear", "kneeling"], "SCENE": ["beach_chair", "bird", "petals", "sand_sculpture", "sand_castle", "beach_umbrella", "blue_sky", "cloud", "day", "mountainous_horizon", "sky"], "PROP": ["ball", "beachball", "bucket", "flower", "umbrella"], "ACTION": ["hat_tug"], "EXPRESSION": [":d", "blush", "looking_at_viewer", "open_mouth", "smile"], "META": ["dutch_angle", "full_body", "official_art", "second-party_source"]}

The JSON object is generated model-natively — no post-processing or conversion is applied.

The model outputs valid JSON directly.

Tags are sorted into up to 25 named zones covering the full danbooru taxonomy. Which keys

appear depends entirely on the input — only populated zones are emitted. A fully described

explicit scene might produce RATING, SUBJECT, STYLE, HAIR, FACE, BODY, ATTIRE,

ATTIRE_STATE, STATE, SCENE, SEXUAL, and META; a simple character description may

produce only a handful. Note that in JSON mode RATING is emitted as a single letter

(g / s / q / e) — unlike flat mode where rating is omitted and must be appended manually.

This format is useful for downstream processing — filtering by zone, selectively overriding

categories, or feeding structured data into other pipelines.

The flat comma-separated format remains the default; instruct the model to use JSON by

including "Output as JSON." (or similar) in the instruction prefix.

Recommended settings

| Setting | Value | Reason |

|:--------|------:|:-------|

| temperature | 0.05 | Best validity (90.5% HF / 89.6% Q6_K). Greedy (0.0) is nearly identical. |

| repetition_penalty / repeat_penalty | 1.3 | Suppresses rare looping on edge-case prompts. |

| max_tokens / max_new_tokens | 256 | Sufficient for all but the most elaborate scene descriptions. |

Prompt quality affects both output quality and speed

More detailed descriptions produce better tags and generate faster.

When the input is specific — named clothing items, exact colors, clear actions — the model resolves

its first token with high confidence and proceeds quickly. A vague or underspecified prompt spreads

probability mass across many plausible continuations, which slows down every generation step even

when the final output is shorter.

Measured on the HF model (bfloat16):

| Prompt | TTFT | Total | Tags emitted |

|:-------|-----:|------:|-------------:|

| "A girl with blue hair." | 1,196ms | 1,196ms | 1 (blue_hair only — missing 1girl, solo) |

| "A solo slim red-haired girl with freckles and very small breasts, wearing a maid outfit." | 830ms | 4,751ms | 7 |

| "A gothic punk girl…" (full 60-word description) | 747ms | 57,708ms | 61 |

The two-word prompt is not only incomplete — it is also the slowest to first token because

the model is uncertain what to commit to. The 60-word gothic punk description generates its first

tag 37% faster despite the far longer output, because every detail narrows the search space

immediately.

Practical tip: Always include subject count (a solo girl, two women), key physical traits

(hair color/length, eye color, body type), clothing, and setting. The more you specify, the faster

and more complete the result.

Benchmarks

Quality — HF (bfloat16) vs Q6_K GGUF

Measured on 10 prompts (2 short, 2 medium, 2 long, 4 explicit). Validity = percentage of

emitted tags that exist in the authorized 137k-tag danbooru vocabulary. Repetition penalty 1.3,

max 256 tokens, 2 samples per prompt at temp > 0.

| Temp | HF valid% | Q6_K valid% | HF TTFT | Q6_K TTFT | HF total | Q6_K total |

|-----:|----------:|------------:|--------:|----------:|---------:|-----------:|

| 0.00 | 89.6% | 88.1% | 909ms | 165ms | 13,668ms | 920ms |

| 0.05 | 90.5% | 89.6% | 901ms | 155ms | 13,696ms | 895ms |

| 0.10 | 87.2% | 88.9% | 878ms | 157ms | 14,265ms | 940ms |

| 0.15 | 87.5% | 88.3% | 915ms | 156ms | 13,108ms | 914ms |

The Q6_K GGUF is within 1% of the full bfloat16 model at every temperature while being

~15× faster end-to-end and ~5–6× faster to first token. At temp ≥ 0.10 Q6_K slightly

edges ahead. The HF model is slower because the base Qwen3.5-0.8B architecture includes a

vision encoder (~200MB) that loads into VRAM even for text-only inference; the main GGUF

strips it, keeping only the language model weights.

CPU vs GPU — Q6_K

Measured on a single representative long prompt, 5 runs each.

| Backend | TTFT | Total | Tags | Valid% |

|:-----------|------:|--------:|-----:|-------:|

| CPU | 381ms | 3,708ms | 40.0 | 80.0% |

| GPU (CUDA) | 396ms | 3,753ms | 40.0 | 80.0% |

CPU and GPU are essentially identical. In this run the GPU was marginally slower on

time-to-first-token.

At 0.8B parameters and Q6_K quantization (600MB), the model fits in CPU cache on modern

hardware. PCIe transfer overhead between host memory and GPU offsets the GPU's compute

advantage, leaving no measurable benefit to GPU offload. This is consistent with Qwen3.5-0.8B's

design target of edge and mobile deployment.

If you have no GPU, or want to keep your VRAM free for image generation, run the Q6_K on

CPU — you pay no speed penalty.

Output examples

All examples: Q6_K, temp=0.05, rep_penalty=1.3.

Medium — maid outfit

Input:  A solo slim red-haired girl with freckles and very small breasts, wearing a maid outfit.
Output: 1girl, solo, maid, red_hair, breasts, freckles, small_breasts

Long — futuristic scene

Input:  A tall, athletic dark-skinned woman with short white hair and red eyes stands confidently
        in a futuristic city at night. She wears a sleeveless black bodysuit with gold trim,
        knee-high boots, and a long white coat draped over her shoulders. Neon lights reflect
        off the wet street behind her.

Output: 1girl, dark-skinned_female, solo_focus, short_hair, white_hair, red_eyes, black_bodysuit,
        bodysuit, coat, gold_trim, long_coat, sleeveless, boots, knee_boots, coat_on_shoulders,
        confident, standing, city, neon_lights, night, reflection, street, wet

Explicit — solo

Input:  A solo nude woman lying on her back, legs spread, fingering herself. A large dildo is
        inserted in her pussy, vibrator pressed against her clit.

Output: 1girl, solo_focus, pussy, spread_legs, fingering

Explicit — two characters

Input:  A man fucking a woman from behind in doggy style, gripping her hips. She gasps, breasts
        swinging. Vaginal penetration, creampie visible.

Output: 1boy, 1girl, breasts, pussy, penis, doggystyle, vaginal, from_behind, sex

Known limitations

  • No character or artist tags. The model was trained on visual appearance descriptions only.

Tags like hatsune_miku or melkor_mancin are not emitted. A character/artist LoRA is planned.

  • Very short prompts are incomplete. Two-word inputs like "a girl with blue hair" may return

only blue_hair, omitting 1girl and solo. Training data required a minimum of 10 tags per

row, so single-feature inputs are outside the training distribution. Always include the subject

count and at least a few additional details.

  • Image input does not work. The base model has a vision encoder and an mmproj can be

extracted, but the fine-tuning was text-only. Feeding an image produces hallucinated garbage.

Image→tags would require a separate training run on image+tag pairs.

  • Rating tags are not emitted. Add rating:safe, rating:questionable, or rating:explicit

yourself based on your use case.

  • Complex or ambiguous clothing can hallucinate. The model occasionally invents tag names for

garment combinations it has not seen (e.g. sailor-collar_shirt instead of sailor_collar).

A constrained-decoding fence (trie of 137k authorized tags) eliminates this class of error

entirely at inference time; see the TagForge integration below.

  • Style zone misclassification. Frilly or sailor-collar garments reliably trigger "maid" in

the JSON STYLE zone even when the described style is clearly something else (e.g. gothic punk).

This is a training bias; the flat output is unaffected.

  • Image input does not work as a pipeline shortcut. The intended workflow for image→tags is:

run a vision LLM (e.g. an abliterated Gemma or JoyCaption) to generate a natural-language

description, then pipe that description into BooruNL with the standard instruction prefix.

Feeding an image directly via the mmproj produces hallucinated output — the vision encoder was

never trained to map visual features to danbooru tags.

Training details

| Detail | Value |

|:-------|:------|

| Base model | Qwen/Qwen3.5-0.8B-Base |

| Fine-tune method | Full fine-tune (Unsloth + SFTTrainer) |

| Dataset | 124,252 description → tag pairs (Gemma-4-26B-A4B labelled) |

| Epochs | 2 |

| Best checkpoint | Step 5800 |

| Final F1 | 85.2% (P 94.2%, R 77.9%) |

| Invalid tag rate | 2.0% (without fence) |

| Hardware | NVIDIA RTX 5060 Ti 16GB |

The training set covers the full danbooru tag vocabulary including explicit content. Gender-mismatch

rows (Gemini labeller hallucinating male tags on female subjects) were detected and removed before

training, which was the main quality improvement over the previous dataset version.

TagForge integration

BooruNL-0.8B ships as a node in TagForgeSuite. The node

auto-downloads BooruNL-0.8B-Q6_K.gguf to models/BooruNL/ on first use and applies a

constrained-decoding fence at inference time, guaranteeing that every emitted tag is a real,

authorized danbooru tag — the 2% invalid rate above drops to 0%.

The JSON zone output from BooruNL is natively compatible with TagForge's structured_tags

input — no conversion needed. Both systems were built by the same author and share the same zone

vocabulary. The TagForge sampler accepts BooruNL JSON directly alongside its own native string

format and handles the zone mapping automatically.

TagForge is not yet publicly released, but a release is planned soon.

Run cooperdk/BooruNL-0.8B-GGUF with guIDE

Download guIDE — the AI-native code editor with local LLM inference and 69 built-in tools.

Download guIDE → · Browse 524k+ models · Compare models

Source: Hugging Face · Compare models