From 0d278faab23245edaa785a4dc521e12526e4306a Mon Sep 17 00:00:00 2001 From: Adam Ladachowski Date: Thu, 12 Feb 2026 16:40:49 +0000 Subject: [PATCH] Update --- PLAN.md | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ TODO.md | 27 +++++++--- models.md | 77 ++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 PLAN.md create mode 100644 models.md diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..1a226ac --- /dev/null +++ b/PLAN.md @@ -0,0 +1,147 @@ +# Plan: SD Image Generation (CLI + Web Gallery) + +Add `tsr gen` CLI command and `tsr gallery` web UI for generating images using diffusers + PyTorch (ROCm) directly from local safetensor checkpoints. Gallery is mobile-first, generation-only — no search, no model library. + +## Stack + +- **diffusers** — load safetensor checkpoints via `from_single_file()`, LoRA via `load_lora_weights()`, all schedulers built-in +- **torch** (ROCm) — assumed pre-installed with ROCm support (`torch.device("cuda")` works on ROCm via HIP) +- **transformers** — CLIP text encoders (diffusers dependency) +- **accelerate** — device placement +- **safetensors** — already a project dependency + +## Phase 1: Generation Engine Module + +### Description +New `tensors/generate.py` module — wraps diffusers pipeline for txt2img from local safetensor files. Handles checkpoint loading, LoRA application, scheduler selection, and generation. + +### Steps + +#### Step 1.1: Create generate.py with pipeline management +- **Objective**: Load safetensor checkpoints into diffusers pipeline, generate images +- **Files**: `tensors/generate.py` +- **Dependencies**: None +- **Implementation**: + - `ImageGenerator` class + - `load_checkpoint(path)` — `StableDiffusionPipeline.from_single_file()` or `StableDiffusionXLPipeline.from_single_file()` for SDXL safetensors. Auto-detect SD1.5 vs SDXL from metadata. Move to ROCm device. + - `load_lora(path, strength)` — `pipe.load_lora_weights()`, support multiple LoRAs with `pipe.fuse_lora(lora_scale=strength)` + - `set_scheduler(name)` — map name strings to diffusers schedulers: EulerDiscreteScheduler, EulerAncestralDiscreteScheduler, DPMSolverMultistepScheduler, DDIMScheduler, LMSDiscreteScheduler, PNDMScheduler, etc. + - `generate()` — accepts prompt, negative_prompt, steps, cfg_scale, width, height, seed, batch_size. Returns list of PIL Images. + - Keep pipeline loaded between calls (model stays in VRAM) + - `unload()` — free VRAM + +#### Step 1.2: Add config entries for generation defaults +- **Objective**: Configurable default generation params and model paths in config.toml +- **Files**: `tensors/config.py` +- **Dependencies**: Step 1.1 +- **Implementation**: + - Add `[generate]` section: `models_dir` (default `~/models`), `lora_dir`, `output_dir` (default `~/.local/share/tensors/gallery/`), `default_steps`, `default_cfg`, `default_sampler`, `default_scheduler`, `default_width`, `default_height` + - Enum or list of available schedulers with friendly names + +## Phase 2: CLI Generate Command + +### Description +`tsr gen` command that loads a checkpoint, generates images, saves to gallery directory with metadata sidecar JSON. + +### Steps + +#### Step 2.1: Implement `tsr gen` command +- **Objective**: CLI command with all generation parameters as options +- **Files**: `tensors/cli.py` +- **Dependencies**: Phase 1 +- **Implementation**: + - `tsr gen "prompt text"` — positional prompt argument + - Options: `--model/-m` (path or name in models_dir), `--negative/-n`, `--steps/-s`, `--cfg/-c`, `--width/-W`, `--height/-H`, `--sampler`, `--scheduler`, `--seed`, `--lora` (repeatable, format `name:strength`), `--batch/-b`, `--output/-o` (override output dir) + - Rich progress: model loading spinner, then generation progress (diffusers callback for step progress) + - Save output as `{timestamp}_{seed}.png` in gallery dir + - Save sidecar `{timestamp}_{seed}.json` with all generation params + model name + time elapsed + - Display: filename, resolution, seed, time elapsed + - `--json` flag for machine-readable output + +#### Step 2.2: Add `tsr gen-ls` subcommand +- **Objective**: List available models, LoRAs, and schedulers +- **Files**: `tensors/cli.py` +- **Dependencies**: Phase 1 +- **Implementation**: + - Scan models_dir for `.safetensors` files + - Scan lora_dir for LoRA files + - List available schedulers + - Rich table output, `--json` flag + +## Phase 3: Web Gallery UI + +### Description +`tsr gallery` serves a mobile-first web app for generating images and browsing results. Single HTML file, no build tools. Dark theme. + +### Steps + +#### Step 3.1: Create gallery API server +- **Objective**: FastAPI app that runs generation and serves the gallery +- **Files**: `tensors/gallery.py` +- **Dependencies**: Phase 1, Phase 2 +- **Implementation**: + - Holds a single `ImageGenerator` instance (lazy-loaded on first generate) + - `POST /api/generate` — accepts generation params JSON, runs pipeline, saves to gallery dir, returns image URL + metadata. Checkpoint loaded/swapped as needed. + - `GET /api/images` — list gallery images (paginated, newest first), reads sidecar JSONs for metadata + - `GET /api/images/{filename}` — serve image file + - `DELETE /api/images/{filename}` — delete image + sidecar + - `GET /api/models` — list available checkpoints in models_dir + - `GET /api/loras` — list available LoRAs + - `GET /api/schedulers` — list available scheduler names + - `GET /api/config` — current default generation params + - `GET /api/status` — is model loaded, which one, VRAM usage + - Static file serving for the frontend + - Add `fastapi`, `uvicorn` as optional dependencies (`[project.optional-dependencies] gallery = [...]`) + +#### Step 3.2: Build mobile-first gallery frontend +- **Objective**: Single-page responsive UI for generation + browsing +- **Files**: `tensors/static/index.html` +- **Dependencies**: Step 3.1 +- **Implementation**: + - **Generate panel** (top on mobile, sidebar on desktop): + - Model selector dropdown (populated from `/api/models`) + - Prompt textarea, negative prompt textarea + - Collapsible "Advanced" section: steps, cfg, sampler dropdown, scheduler dropdown, width, height, seed, LoRA selector with strength slider + - Generate button with loading state + step progress + - Dropdowns populated from API on load + - **Gallery grid** (below/main area): + - Masonry or uniform grid of generated images, newest first + - Tap/click to view full size with metadata overlay (prompt, params, seed) + - Swipe between images on mobile + - Delete button on detail view + - Infinite scroll / load more + - **Design**: + - Dark theme + - CSS grid/flexbox, no framework + - Touch-friendly (large tap targets, no hover-dependent UI) + - `` for mobile + - Single HTML file with inline CSS/JS (no build step) + +#### Step 3.3: Add `tsr gallery` CLI command +- **Objective**: Launch the gallery web server from CLI +- **Files**: `tensors/cli.py` +- **Dependencies**: Step 3.1, Step 3.2 +- **Implementation**: + - `tsr gallery` — starts uvicorn on `0.0.0.0:7860` + - Options: `--port/-p`, `--host`, `--model/-m` (pre-load a checkpoint) + - Auto-open browser with `--open` flag + +## Phase 4: Tests + +### Steps + +#### Step 4.1: Test generate.py +- **Files**: `tests/test_generate.py` +- **Dependencies**: Phase 1 +- **Implementation**: + - Mock torch/diffusers (don't require GPU in CI) + - Test scheduler mapping, parameter validation, config loading + - Test checkpoint type detection (SD1.5 vs SDXL) + +#### Step 4.2: Test gallery API +- **Files**: `tests/test_gallery.py` +- **Dependencies**: Phase 3 +- **Implementation**: + - Use FastAPI TestClient + - Mock ImageGenerator + - Test image listing, deletion, model/lora listing diff --git a/TODO.md b/TODO.md index fd6b515..0295e24 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,25 @@ # TODO -## Web UI +## SD Image Generation -Add a web interface started from the CLI (`tsr serve` or `tsr ui`) to: +### Phase 1: Generation Engine +- [ ] Step 1.1: Create `tensors/generate.py` — ImageGenerator class (diffusers pipeline, checkpoint loading, LoRA, schedulers) +- [ ] Step 1.2: Add `[generate]` config section (models_dir, lora_dir, output_dir, defaults) + +### Phase 2: CLI Generate Command +- [ ] Step 2.1: `tsr gen` command (prompt, model, negative, steps, cfg, sampler, scheduler, seed, lora, resolution) +- [ ] Step 2.2: `tsr gen-ls` command (list models, LoRAs, schedulers) + +### Phase 3: Web Gallery +- [ ] Step 3.1: `tensors/gallery.py` — FastAPI server (generate, images, models, loras, schedulers endpoints) +- [ ] Step 3.2: `tensors/static/index.html` — mobile-first dark gallery UI (generate panel + image grid) +- [ ] Step 3.3: `tsr gallery` CLI command (launch server) + +### Phase 4: Tests +- [ ] Step 4.1: `tests/test_generate.py` (mocked diffusers, scheduler mapping, config) +- [ ] Step 4.2: `tests/test_gallery.py` (FastAPI TestClient, mocked generator) + +## Web UI (Future) ### Model Library - [ ] Browse downloaded models in `~/.local/share/tensors/models/` @@ -19,9 +36,3 @@ Add a web interface started from the CLI (`tsr serve` or `tsr ui`) to: - [ ] View model details and versions - [ ] One-click download to appropriate directory - [ ] Show download progress - -### Technical -- [ ] Use FastAPI + htmx or similar lightweight stack -- [ ] SQLite for local model index/cache -- [ ] Watch filesystem for new models -- [ ] Configurable port (`tsr serve --port 8080`) diff --git a/models.md b/models.md new file mode 100644 index 0000000..fee3acd --- /dev/null +++ b/models.md @@ -0,0 +1,77 @@ +# Model Inventory + +Location: `/models/` + +## Checkpoints + +### SD 1.5 (512x512) + +| Model | Size | GGUF | Tensors | Notes | +|-------|------|------|---------|-------| +| dreamshaper_8 | 2.0G | 1.7G | 1,131 | | +| epicrealism_naturalSinRC1VAE | 2.0G | 1.7G | 1,133 | Includes VAE | +| hassakuSD15_v13 | 2.0G | 1.7G | 1,131 | | + +### SDXL / Pony / Illustrious (1024x1024) + +| Model | Size | GGUF | Tensors | Notes | +|-------|------|------|---------|-------| +| cyberrealisticPony_v160 | 6.5G | 3.9G | 2,515 | Author: Cyberdelia | +| juggernautXL_ragnarokBy | 6.6G | 4.0G | 2,516 | | +| obsessiveCompulsive_v20 | 6.5G | 3.9G | 2,515 | | +| ponyDiffusionV6XL_v6StartWithThisOne | 6.5G | 3.9G | 2,515 | arch: `stable-diffusion-xl-v1-base` | +| ponyRealism_V22 | 6.6G | 4.0G | 2,515 | Merge: PonyRealism v2.1 + Volendir Cinematic v1.1R | +| realismIllustriousBy_v50FP16 | 6.5G | 3.9G | 2,515 | | +| spicyRealismNSFWMix_v30 | 6.5G | 3.9G | 2,515 | Triple merge | +| waiIllustriousSDXL_v160 | 6.5G | 3.9G | 2,515 | | + +**Total checkpoints:** 11 models, ~95G (safetensors + GGUF) + +## LoRAs + +### SDXL / Illustrious + +| LoRA | Size | GGUF | Dim | Alpha | Clip Skip | Title | +|------|------|------|-----|-------|-----------|-------| +| 70s_VPMS_V1-E20 | 218M | - | 32 | 32 | 2 | 70s Vintage Porn Magazine Style | +| Bimbo_Bomb_Girls_Pit_Style | 218M | 116M | 32 | 16 | 1 | Bimbo Bomb Girls Pit Style | +| Candy_Jab_Comix | 218M | 116M | 32 | 16 | 1 | Candy Jab Comix | +| Nellie_Jab_Comix-000009 | 218M | - | 32 | 16 | 1 | Nellie Jab Comix | +| RealisticAnimeIXL_v2 | 218M | 116M | 32 | 16 | 1 | RealisticAnimeIXL | +| Western_art_style (Melkor Mancin / Rizdraws) | 218M | - | 32 | 16 | 1 | Combined western art style | +| spumcostyle | 218M | 116M | 32 | 16 | 1 | spumcostyle | +| vitpitillust | 218M | 116M | 32 | 16 | - | vitpitillust | + +### SD 1.5 + +| LoRA | Size | GGUF | Dim | Alpha | Clip Skip | Title | +|------|------|------|-----|-------|-----------|-------| +| BimboOne | 144M | 82M | 128 | 128 | 2 | BimboOne | +| Calm [MockAI - v1.0] | 37M | - | - | - | - | - | +| bimbo-fc-1.6a | 144M | - | - | - | - | - | +| bimbostyleTwo | 144M | 82M | 128 | 128 | 2 | bimbostyleTwo | + +**Total LoRAs:** 12 models, ~3.4G (safetensors + GGUF) + +## Character Presets + +YAML files in `/models/characters/` with trigger words, positive/negative prompts per LoRA. + +| LoRA | Presets | +|------|---------| +| 70s_VPMS | generic | +| BimboOne | candy_charms | +| Bimbo_Bomb_Girls_Pit_Style | blossom, bubbles, butter, generic | +| Calm_MockAI | generic | +| Candy_Jab_Comix | candy | +| Nellie_Jab_Comix | nellie | +| RealisticAnimeIXL | generic | +| Western_Melkor_Mancin | generic | +| bimbo-fc | generic | +| bimbostyleTwo | generic | +| spumcostyle | generic | +| vitpitillust | bimbo | + +## Outputs + +`/models/outputs/` — 167 generated images, 141M total