{"id":32458426,"url":"https://github.com/nusu-github/wdtaggerappend","last_synced_at":"2025-10-26T10:57:17.785Z","repository":{"id":318822583,"uuid":"1076532642","full_name":"nusu-github/WDTaggerAppend","owner":"nusu-github","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-22T17:38:34.000Z","size":1756,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-22T18:33:46.798Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nusu-github.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-15T02:04:20.000Z","updated_at":"2025-10-22T17:38:38.000Z","dependencies_parsed_at":"2025-10-16T11:41:23.587Z","dependency_job_id":"0aef80c4-b50d-4bb3-9df1-5dc55df57203","html_url":"https://github.com/nusu-github/WDTaggerAppend","commit_stats":null,"previous_names":["nusu-github/wdtaggerappend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nusu-github/WDTaggerAppend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nusu-github%2FWDTaggerAppend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nusu-github%2FWDTaggerAppend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nusu-github%2FWDTaggerAppend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nusu-github%2FWDTaggerAppend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nusu-github","download_url":"https://codeload.github.com/nusu-github/WDTaggerAppend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nusu-github%2FWDTaggerAppend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281092768,"owners_count":26442440,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-26T10:57:10.074Z","updated_at":"2025-10-26T10:57:17.778Z","avatar_url":"https://github.com/nusu-github.png","language":"Python","readme":"# WD Tagger Append\n\nTools for extending the SmilingWolf WD Tagger models with custom datasets, LoRA fine-tuning, and streamlined inference. The project embraces the Hugging Face ecosystem (datasets, transformers, peft, accelerate, bitsandbytes) to keep the training loop lightweight while matching the tagger family’s preprocessing and label handling.\n\n## Features\n\n- **Dataset preparation** – Scan Danbooru-style folders, deduplicate by MD5, split into train/validation, optionally save locally and push to the Hugging Face Hub.\n- **LoRA fine-tuning** – Train adapters for WD Tagger backbones (SwinV2, ConvNeXt, ViT, EVA02) with automatic classifier-head expansion and optional k-bit quantization.\n- **Inference** – Tag images locally with threshold controls using WD Tagger backbones (extendable to custom adapters).\n\n## Prerequisites\n\n- Python 3.11 or newer\n- [uv](https://github.com/astral-sh/uv) package manager\n- CUDA-capable GPU recommended for training (CPU and 4/8-bit modes are supported for experimentation)\n\n## Installation\n\n```bash\ngit clone https://github.com/nusu-github/WDTaggerAppend.git\ncd WDTaggerAppend\nuv sync\n```\n\n`uv sync` installs the managed virtual environment declared in `pyproject.toml`, including the correct PyTorch build (CUDA on Linux/Windows, CPU elsewhere).\n\nInvoke the CLIs with `uv run wd-tagger-\u003ccommand\u003e …` or `python -m wd_tagger_append.\u003cmodule\u003e …`.\n\n## Quick Start\n\n### 1. Prepare a dataset\n\n```bash\nuv run wd-tagger-prepare datasets/anime_set \\\n  --output-dir datasets/processed/anime_set \\\n  --push-to-hub \\\n  --hub-repo username/anime-set \\\n  --private\n```\n\nKey options:\n\n- `--output-dir`: Save the Arrow dataset to disk (omit to skip).\n- `--push-to-hub`: Upload the resulting `DatasetDict`; needs `--hub-repo`.\n- `--hub-repo`: Target repo such as `username/dataset-name`.\n- `--private`: Create the Hub repo as private.\n\n### 2. Train a LoRA adapter\n\n```bash\nuv run wd-tagger-train \\\n  --dataset-path datasets/processed/anime_set \\\n  --model eva02-large \\\n  --output-dir output/anime_set_eva02_lora \\\n  --train-batch-size 8 \\\n  --gradient-accumulation-steps 2 \\\n  --learning-rate 3e-5 \\\n  --num-epochs 3 \\\n  --lora-rank 16 \\\n  --lora-alpha 32 \\\n  --lora-dropout 0.05 \\\n  --precision bf16\n```\n\nAlternative: `--dataset-name username/anime-set` (optionally with `--dataset-config`) to stream from the Hub.\n\nImportant knobs:\n\n- `--model`: Backbone key from `MODEL_REPO_MAP` (`swinv2`, `convnext`, `vit`, `vit-large`, `eva02-large`).\n- `--train-batch-size`, `--eval-batch-size`, `--gradient-accumulation-steps`: Control memory vs. throughput.\n- `--learning-rate`, `--num-epochs`, `--weight-decay`, `--warmup-ratio`: Optimisation parameters.\n- `--lora-rank`, `--lora-alpha`, `--lora-dropout`: PEFT LoRA hyperparameters.\n- `--mixup-alpha`: Enable torchvision MixUp during batching.\n- `--load-in-4bit` / `--load-in-8bit`: Activate BitsAndBytes quantised loading; works with `--precision` (`fp32`, `bf16`, `fp16`).\n- `--metrics-top-k`: Report Precision@K / Recall@K / nDCG@K for chosen cut-offs (repeat to add values).\n- `--metrics-propensity`: Add propensity-scored nDCG@K using dataset tag frequencies (requires `--metrics-top-k`).\n- `--push-to-hub`, `--hub-model-id`, `--hub-token`: Push adapters automatically after training.\n\nThe trainer writes checkpoints plus a `label_mapping.json` (merged base + dataset tags) to `output-dir`.\n\n### 3. Run inference\n\n```bash\nuv run wd-tagger-infer path/to/sample.jpg \\\n  --model eva02-large \\\n  --gen-threshold 0.35 \\\n  --char-threshold 0.7\n```\n\nUse a fine-tuned adapter (the CLI auto-detects `label_mapping.json` if it exists in the adapter directory):\n\n```bash\nuv run wd-tagger-infer path/to/sample.jpg \\\n  --model eva02-large \\\n  --adapter output/anime_set_eva02_lora \\\n  --gen-threshold 0.35 \\\n  --char-threshold 0.7\n```\n\nOptions:\n\n- `--model`: Backbone key, repo ID, or local base model path.\n- `--repo-id`: Override the base model repo/path when `--model` is only a key.\n- `--adapter`: Load a PEFT adapter from a local directory or Hub repo (e.g. `output/...`).\n- `--labels-path`: Provide a custom `label_mapping.json` or `selected_tags.csv` (defaults to adapter/base assets).\n- `--gen-threshold`, `--char-threshold`: Filter probabilities for general/character tags.\n- `--load-in-4bit/--no-load-in-4bit`: Toggle 4-bit NF4 inference (default: on).\n- `--load-in-8bit/--no-load-in-8bit`: Toggle 8-bit inference.\n- `--token`: Hugging Face token for private repos.\n\n## Dataset format\n\n`wd-tagger-prepare` expects Danbooru-style `{image}.{ext}` + `{image}.{ext}.json` pairs. Minimal JSON structure:\n\n```json\n{\n  \"md5\": \"abc123…\",\n  \"rating\": \"s\",\n  \"score\": 42,\n  \"source\": \"https://danbooru.donmai.us/posts/123\",\n  \"tag_string_general\": \"1girl solo smile long_hair\",\n  \"tag_string_character\": \"hatsune_miku\",\n  \"tag_string_copyright\": \"vocaloid\",\n  \"tag_string_artist\": \"piapro\",\n  \"tag_string_meta\": \"\"\n}\n```\n\nMissing tag strings default to empty lists. Ratings follow Danbooru’s codes (`s`, `q`, `e`, etc.). The tool deduplicates by `md5`, records the `score`/`source`, and produces multi-hot labels for general, character, copyright, artist, and meta categories.\n\n## Example pipeline\n\n1. **Prepare** (machine A):\n\n   ```bash\n   uv run wd-tagger-prepare datasets/anime_characters \\\n     --push-to-hub \\\n     --hub-repo username/anime-characters \\\n     --private\n   ```\n\n2. **Train** (GPU machine B):\n\n   ```bash\n   uv run wd-tagger-train \\\n     --dataset-name username/anime-characters \\\n     --model eva02-large \\\n     --output-dir output/anime_characters_eva02 \\\n     --train-batch-size 8 \\\n     --gradient-accumulation-steps 2 \\\n     --learning-rate 3e-5 \\\n     --num-epochs 3 \\\n     --lora-rank 16 \\\n     --lora-alpha 32 \\\n     --precision bf16 \\\n     --push-to-hub \\\n     --hub-model-id username/anime-characters-eva02-lora\n   ```\n\n3. **Infer** (any machine):\n\n   ```bash\n   uv run wd-tagger-infer path/to/test.jpg \\\n     --model eva02-large \\\n     --adapter output/anime_characters_eva02 \\\n     --gen-threshold 0.4 \\\n     --char-threshold 0.6\n   ```\n\n## Development\n\n```bash\n# Formatting / linting\nuv run ruff format .\nuv run ruff check .\n\n# Type checking\nuv run pyright\n\n# Tests (add selectors as needed)\nuv run pytest\n```\n\n## Supported backbones\n\n- `SmilingWolf/wd-swinv2-tagger-v3`\n- `SmilingWolf/wd-convnext-tagger-v3`\n- `SmilingWolf/wd-vit-tagger-v3`\n- `SmilingWolf/wd-vit-large-tagger-v3`\n- `SmilingWolf/wd-eva02-large-tagger-v3`\n\n## License\n\nDual licensed under the MIT License and the Apache License 2.0. See `LICENSE-MIT` and `LICENSE-APACHE` for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnusu-github%2Fwdtaggerappend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnusu-github%2Fwdtaggerappend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnusu-github%2Fwdtaggerappend/lists"}