Skip to content

Commit 8ae660c

Browse files
committed
feat: Concept generation in ② + Style/Concept UX gaps (0.11.0)
Style & Concept Phase 2 — the last piece of the dataset-type work. ② Concept generation (the feature): - shotplan.concept_plan(): 18-shot object set — a 10-shot turnaround reusing the ATTESTED <sks> Multiple-Angles grammar, 4 framing/scale shots, 4 context shots. Same Shot model as the character plan with emotion/outfit empty, so the ② table, YAML plans, apply_wardrobe and generate_shots need no branch. - plan_for_type()/plan_subject() are one selection seam shared by UI and CLI. Style returns an EMPTY plan: a look can't be synthesized from a reference, so ②'s buttons are disabled and the table isn't filled with shots you can't make. Phase-1 gaps found while reviewing: - ② was fully live for Style — one click billed Gemini for a 24-shot character turnaround. Same in `cli.py build --dataset-type style`, which now skips the generation stage outright (regression-tested; it's the money path). - Isolation defaulted ON for Concept while the SAM3 subject stayed "character". Subject now follows the type (concept → "object") in ①, ② and the tooltips. - Character-only ② controls (wardrobe randomizer — OUTFIT_SHOT_KINDS includes "angle", so it WOULD dress an object's turnaround — and the character-worded prop-exclusion clause) are hidden/off for Concept; CLI `_dress` no-ops with a note and --exclude-props/--isolate became per-type tri-state options. - ③/④/② "Character name" labels + tooltips now follow the type (the name is a documented no-op for Style/Concept captions). - ⑤ Inspect reconciles the dataset's recorded metadata.json dataset_type with the header and warns on a mismatch (the type drives the sample prompt). - The header type is remembered in .cache/user_settings.json and re-applied on load, so Style/Concept users stop re-picking every launch. Prompt bugs fixed while in shotplan.py (they affected the character path too): - pose/emotion LOCAL prompts emitted a literal "{subject}" — nothing downstream ever formatted them, so ComfyUI got the braces verbatim in 15 of 24 shots. - "in {setting}" double-prefixed settings that already carry a preposition ("in in a warmly lit interior room", "in against a plain … background"). - "the same the object/the character" — a leading article is now stripped. CLI: --dataset-type on `generate` (concept plan; style refused with a clear message), `build` honours it end to end. Docs: ARCHITECTURE 0.11.0 — module map, data flow, dataset-type section, five new gotchas, feature history; Style generation moved to Deferred (permanent, not pending). README: dataset-type table, CLI examples, intro. Tests: +49 (270 pass, ruff clean) across tests/test_concept_plan.py, tests/test_dataset_type_ui.py and tests/test_cli_build_types.py, including a handler-arity guard against the outputs list drifting. Verified: ruff + pytest green; Gradio app launched headlessly (config renders, both change/load handlers wired, 17 outputs each); per-type handler output checked; CLI help + style refusal exercised. Generation itself is NOT verified — it needs ComfyUI or a billed key, per the project's no-live-run testing rule. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AwnSoX1Z56tyuSgVhvRANJ
1 parent 5393a41 commit 8ae660c

10 files changed

Lines changed: 1161 additions & 143 deletions

File tree

README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

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

1011
![Generate & curate tab](docs/images/ui-generate.png)
1112

1213
## Why use it
1314

14-
- **One reference → a full dataset.** No hunting for 24 angles of the same character — generate
15-
them, consistently, from a single image.
16-
- **Character, style *or* concept.** Pick the **Dataset type** in the header; captions and
17-
defaults retune so the trigger learns an identity, an aesthetic, or an object/idea.
15+
- **One reference → a full dataset.** No hunting for 24 angles of the same character (or 18 of
16+
the same object) — generate them, consistently, from a single image.
17+
- **Character, style *or* concept.** Pick the **Dataset type** in the header; the shot plan,
18+
captions and defaults retune so the trigger learns an identity, an aesthetic, or an object/idea.
1819
- **Local *or* cloud, per stage.** Every step has a free/private local path **and** a no-GPU
1920
cloud path. Mix and match: generate on the cloud, caption on your GPU, or the reverse.
2021
- **Every stage is standalone.** Point any tab (or CLI subcommand) at any folder — preprocess
@@ -35,25 +36,28 @@ Run them in order (each step auto-fills the next) or jump straight to the one yo
3536
|---|---|---|
3637
| ① Restore / upscale | ComfyUI models, or basic Lanczos ||
3738
| ① Subject isolation | **Built-in SAM3** (no ComfyUI) or ComfyUI SAM3 ||
38-
| ② Generate shots | ComfyUI: Qwen Image Edit 2511 + Multiple-Angles LoRA | Gemini (Nano Banana) |
39+
| ② Generate shots *(character + concept)* | ComfyUI: Qwen Image Edit 2511 + Multiple-Angles LoRA | Gemini (Nano Banana) |
3940
| ③ Caption | Qwen3-VL-8B, JoyCaption, NSFW finetune, **WD + e621 taggers**, LM Studio / Ollama / any OpenAI endpoint | Gemini Flash, Groq free tier |
4041
| ④ Export | always local (+ optional **.zip** and **Hugging Face** publish) ||
4142
| ⑤ Train config | ai-toolkit (incl. SDXL) / **kohya sd-scripts** / musubi-tuner ||
4243

4344
## Dataset types
4445

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

4850
| Type | Trigger learns | Captions describe | ② Generate |
4951
|---|---|---|---|
50-
| **Character** *(default)* | an identity | what *varies* (pose, angle, setting) | ✅ 24-shot set from one image |
51-
| **Style** | an aesthetic / look | the image **content**, not the style/medium | bring your own images |
52-
| **Concept** | an object, action or idea | the **context**, not the concept's fixed form | bring your own images |
52+
| **Character** *(default)* | an identity | what *varies* (pose, angle, setting) | ✅ 24 shots: angles, poses, expressions |
53+
| **Style** | an aesthetic / look | the image **content**, not the style/medium | bring your own images |
54+
| **Concept** | an object, action or idea | the **context**, not the concept's fixed form | ✅ 18 shots: turnaround, framing, context |
5355

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

5862
> 💡 **Need source images?** My separate **[YouTube Screenshot Extractor](https://github.com/EnragedAntelope/youtube-screenshot-extractor)**
5963
> pulls high-quality frames from YouTube **and 1000+ other sites (and local video files)** — with
@@ -137,13 +141,15 @@ Every stage is a standalone subcommand; `--help` shows all options.
137141
```bash
138142
python cli.py preprocess ./sources --out ./prepped
139143
python cli.py generate ./prepped --name "Sy Snootles" --engine comfyui --randomize-outfits
144+
python cli.py generate ./prepped --name "brass compass" --dataset-type concept # 18-shot object set
140145
python cli.py caption ./folder --trigger sysnootles # prose sidecars
141146
python cli.py caption ./folder --trigger sysnootles --caption-style tags # Danbooru tags
142147
python cli.py caption ./folder --trigger mystyle --dataset-type style # style-framed
143148
python cli.py caption ./folder --captioner wd-eva02 --drop-tags "watermark, signature"
144149
python cli.py lint ./folder --trigger sysnootles # caption health report
145150
python cli.py export ./prepped ./generated --name "Sy Snootles" --trigger sysnootles --zip
146151
python cli.py build source.png --name "Sy Snootles" --trigger sysnootles # all four stages
152+
python cli.py build ./my-style-shots --trigger mystyle --dataset-type style # skips ② entirely
147153
```
148154

149155
## API keys (cloud options only)

0 commit comments

Comments
 (0)