Skip to content

Repository files navigation

Dataset Deviser

Turn a character, style, or concept into a ready-to-train LoRA dataset. For a character, one reference image becomes ~24 consistent shots across camera angles, poses, emotions and settings; for a concept, 18 shots around one object — a turnaround plus framing and context. For a style, bring your own images and get smart, correctly-framed captions. Either way the output is a flat folder that drops straight into any trainer (ai-toolkit / kohya / OneTrainer / …), plus a ready-to-edit training config for ai-toolkit, kohya or musubi.

Generate & curate tab

Why use it

  • One reference → a full dataset. No hunting for 24 angles of the same character (or 18 of the same object) — generate them, consistently, from a single image.
  • Character, style or concept. Pick the Dataset type in the header; the shot plan, captions and defaults retune so the trigger learns an identity, an aesthetic, or an object/idea.
  • Local or cloud, per stage. Every step has a free/private local path and a no-GPU cloud path. Mix and match: generate on the cloud, caption on your GPU, or the reverse.
  • Every stage is standalone. Point any tab (or CLI subcommand) at any folder — preprocess only, caption only, export only. Bring your own images at any step.
  • Curate by clicking the images. Toggle any shot straight from the gallery, with a ✅/⬜ mark on each thumbnail. Your pick follows you: what you keep in ② is what ③ captions, and what ③ captions is what ④ preselects for export — nothing is silently re-added behind you.
  • Trainer-ready output. Flat NN.png + NN.txt (JPEG/WEBP sources keep their own extension), metadata.json/metadata.jsonl, optional .zip and Hugging Face publish, and a generated config for Flux / SDXL / Qwen-Image / Krea / Pony and more.
  • Honest by design. No telemetry, no upsell. Configs are generated and shown — training is never launched for you. Cloud calls bill your key; this tool takes no cut.

The pipeline

① Preprocess → ② Generate & curate → ③ Caption → ④ Export → ⑤ Train config

Run them in order (each step auto-fills the next) or jump straight to the one you need.

Stage Local Cloud
① Restore / upscale ComfyUI models, or basic Lanczos
① Subject isolation Built-in SAM3 (no ComfyUI) or ComfyUI SAM3
② Generate shots (character + concept) ComfyUI: Qwen Image Edit 2511 + Multiple-Angles LoRA Gemini (Nano Banana)
③ Caption Qwen3-VL-8B, JoyCaption, NSFW finetune, WD + e621 taggers, LM Studio / Ollama / any OpenAI endpoint Gemini Flash, Groq free tier
④ Export always local (+ optional .zip and Hugging Face publish)
⑤ Train config ai-toolkit (incl. SDXL) / kohya sd-scripts / musubi-tuner

Dataset types

Pick one in the header (it's remembered next launch) — it retunes the ② shot plan, caption framing, the ① isolation default, and the ⑤ sample prompt. The trigger word is what the LoRA learns; captions describe everything except it.

Type Trigger learns Captions describe ② Generate
Character (default) an identity what varies (pose, angle, setting) ✅ 24 shots: angles, poses, expressions
Style an aesthetic / look the image content, not the style/medium ✋ bring your own images
Concept an object, action or idea the context, not the concept's fixed form ✅ 18 shots: turnaround, framing, context

Style adds an optional sparse captions toggle (trigger + a few words) for a stronger style at the risk of the trigger absorbing content. Style never generates — a look can't be copied off a reference the way an identity or an object can, so collect images that share it and start at ③ Caption. Concept generation suits a solid object you have a clean reference of; for an action or an abstract idea, bring your own images too.

💡 Need source images? My separate YouTube Screenshot Extractor pulls high-quality frames from YouTube and 1000+ other sites (and local video files) — with automatic quality/blur filtering, scene detection and black-bar removal. It's a great way to gather a consistent style or concept set (or extra character references) to feed in here.

Quick start

# Windows                    # Linux / macOS
setup.bat                    ./setup.sh
start.bat                    ./start.sh

Needs Python 3.10–3.13. setup.bat asks whether to install the NVIDIA-GPU (CUDA) or CPU-only build — pick CPU if you have no NVIDIA card and lean on the cloud options. Then open http://127.0.0.1:7861.

Setup then offers to store API keys in a gitignored .env. Every key is optional — skip them all and stay fully local. You can add or change one at any time, without re-running the installer:

python cli.py keys                      # what's configured (masked)
python cli.py keys --set GEMINI_API_KEY # set or replace one (input is hidden)
python cli.py doctor                    # check the whole install

Updating

git pull
setup.bat            # or ./setup.sh — installs anything the new version added

Re-running setup is safe and is also how you switch between the GPU and CPU builds. Skipping it after a git pull is the usual reason a new version won't start.

Troubleshooting

  • The window closed instantly / nothing happened. Open a terminal in the project folder and run start.bat (or .venv\Scripts\python.exe app.py) from there so the error stays on screen.
  • It won't start after a git pull. Re-run setup.bat — the new version almost certainly needs a dependency you don't have yet.
  • A cloud captioner failed part-way through a batch. Nothing is lost — every caption written before the failure is already on disk. Tick Skip images that already have a caption in Tag options and click ③ again to finish the rest, or switch captioner first. Overload (503) and rate-limit (429) errors are retried automatically before you ever see them.
  • Anything else. python cli.py doctor checks your Python version, dependencies, API keys and ComfyUI, and names what each missing piece blocks.

⚠️ Costs & responsibility

Local options are free. Cloud options are billed directly to the API key you provide (Gemini by Google; custom endpoints by whoever runs them; Groq's free tier is rate-limited). This project never charges you and takes no cut. In-app prices are build-time estimates — check current Google pricing.

You are solely responsible for the images you supply and everything you generate, caption, export or transmit. Use only images you have the rights to and follow each provider's policy. MIT licensed, no warranty.

Captioning

Point ③ Caption at any folder, pick a captioner, get .txt sidecars. Every caption is {trigger}, {description} — the description covers what varies (pose, angle, setting, lighting), because identity is what the trigger learns.

Caption style — match your target base model:

  • Prose (default) — natural language. Right for Flux, Krea, Qwen-Image, SDXL 3 and most modern text-encoders.
  • Danbooru tags — a comma-separated tag list for SDXL, Illustrious, NoobAI and other Danbooru-trained checkpoints, which learn poorly from prose.
  • e621 tags — the furry/anthro vocabulary for Pony Diffusion and furry checkpoints.

For canonical tags, pick a dedicated tagger (WD for Danbooru, Z3D for e621) — it reads tags straight from the image rather than instructing a VLM (needs onnxruntime, installed by setup). Tag options let you add a fixed prefix/suffix (e.g. Pony score_9, score_8_up), drop noisy tags (watermark, signature…), append a rating tag, keep raw underscores, tune tagger thresholds, and skip already-captioned images.

Pick which images to caption by clicking the thumbnails — each carries a ✅/⬜ mark, and Select all / none / only already-captioned handle the bulk cases (tick 🔍 Zoom on click when you'd rather enlarge an image than pick it). Whatever you leave selected is what gets captioned, stays selected afterwards, and is what ④ Export preselects.

If a cloud captioner dies mid-batch, every caption written so far is already saved — retry the rest with Skip images that already have a caption, no double billing.

After captioning, a one-click health check flags empty, too-short, trigger-missing or identical captions (the tell-tale of a captioner that returned junk) — and, for tag datasets, the tags that appear on nearly every image so you know exactly what to feed the drop-list. It's advisory: nothing is blocked or rewritten.

Captioner Runs on Notes
Qwen3-VL-8B Instruct (default) your GPU, ~17 GB best instruction-following, NSFW-capable
JoyCaption Beta One your GPU, ~17 GB purpose-built diffusion captioner
Qwen3-VL-8B NSFW-Caption your GPU, ~17 GB explicit-dataset specialist
WD EVA02 / ViT v3 (tagger) GPU or CPU, ONNX canonical Danbooru tags
Z3D e621 ConvNeXt (tagger) GPU or CPU, ONNX canonical e621/furry tags
Gemini Flash Google API SFW, ~$0.0007/img est., billed to your key
Groq Qwen3.6 27B Groq API SFW, free tier, rate-limited
LM Studio / Ollama / custom your choice any OpenAI-compatible endpoint

Two things that ruin a character LoRA

Both have a switch in ②, because both bit us:

  • Same clothes in every image → the LoRA learns the outfit as the character. Hit 🎲 Randomize outfits to dress each angle/pose shot differently.
  • Props copied into every shot (a backpack in the reference → the LoRA thinks the backpack is the character). Best fix: isolate the source in ① — SAM3 keeps bags and held objects out of the subject mask. The "Exclude props" toggle in ② helps too, especially on Gemini.

CLI

Every stage is a standalone subcommand; --help shows all options.

python cli.py preprocess ./sources --out ./prepped
python cli.py generate ./prepped --name "Sy Snootles" --engine comfyui --randomize-outfits
python cli.py generate ./prepped --name "brass compass" --dataset-type concept  # 18-shot object set
python cli.py caption ./folder --trigger sysnootles                       # prose sidecars
python cli.py caption ./folder --trigger sysnootles --caption-style tags  # Danbooru tags
python cli.py caption ./folder --trigger mystyle --dataset-type style     # style-framed
python cli.py caption ./folder --captioner wd-eva02 --drop-tags "watermark, signature"
python cli.py lint ./folder --trigger sysnootles                          # caption health report
python cli.py export ./prepped ./generated --name "Sy Snootles" --trigger sysnootles --zip
python cli.py build source.png --name "Sy Snootles" --trigger sysnootles  # all four stages
python cli.py build ./my-style-shots --trigger mystyle --dataset-type style  # skips ② entirely
python cli.py doctor                                                      # check this install
python cli.py keys --set GROQ_API_KEY                                     # set/replace a key
python cli.py custom-endpoint --base-url https://openrouter.ai/api/v1 \
    --model qwen/qwen2.5-vl-72b-instruct --key-env OPENROUTER_API_KEY     # configure --captioner custom

API keys (cloud options only)

Set or change any of them with python cli.py keys — they live only in a gitignored .env, and python cli.py doctor shows which are configured.

  • Gemini — image generation and/or captioning: https://aistudio.google.com/apikey
  • Groq — free-tier captioning: https://console.groq.com/keys
  • Hugging Face (HF_TOKEN) — two uses:
    • Built-in SAM3 isolation. facebook/sam3 is gated: accept the licence on the model page, wait for approval, then add a read token. Weights (~3.4 GB) download once.
    • Publishing datasets to the Hub (④, optional). Needs a write token; datasets are private by default.

Good to know

  • No GPU? Choose CPU-only in setup and use cloud generation + cloud captioning. The local 8B captioners aren't practical on CPU (taggers are).
  • ComfyUI is optional — only for local generation / model-based restoration. Cloud generation, built-in SAM3, local captioning and export all work without it. No custom nodes required. See docs/comfyui-setup.md.
  • Sources are never modified; every stage writes copies.
  • Alpha cutout, on request. ① Preprocess can export the isolated subject on a transparent background instead of white (builtin SAM3 backend only) — for your own compositing workflows. Leave it off (default) if you're continuing to ② Generate, which expects a white reference.
  • The UI binds to 127.0.0.1 with no authentication — don't expose it. So galleries can preview images from any folder you point a tab at, the local file server can read any file the app process can while it's running; that's safe only behind the localhost bind, so never forward the port or add share=True.
  • Training configs are generated, never test-trained. Verify against your trainer's docs.
  • Update check: one anonymous request to GitHub's public releases API on launch (cached 24h); no data about you is sent. Disable with LDS_UPDATE_CHECK_ENABLED=false.

More detail: docs/ARCHITECTURE.md.

License

MIT

About

Turn a character, style, or concept into a ready-to-train LoRA dataset - consistent multi-angle shots, smart captions (prose / Danbooru / e621 / dedicated taggers), and trainer-ready configs for Flux, SDXL, Krea, Pony & more. Local or cloud, per stage. No training launched, no telemetry.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages