aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-07-08 16:41:10 +0200
committerDanilo M. <danix@danix.xyz>2026-07-08 16:41:10 +0200
commit7346b22f1858e8b11aea3a2b0fe2066cf70192d9 (patch)
treea32c55da927154d4d1c4ceb50358383632167bdc /README.md
parent2a80aea10ce31c9081692c4d516044a29e39a0c5 (diff)
downloadimggen-7346b22f1858e8b11aea3a2b0fe2066cf70192d9.tar.gz
imggen-7346b22f1858e8b11aea3a2b0fe2066cf70192d9.zip
Document model menu, daemon lifecycle, and compose setup
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'README.md')
-rw-r--r--README.md102
1 files changed, 92 insertions, 10 deletions
diff --git a/README.md b/README.md
index d52dbeb..3be40f6 100644
--- a/README.md
+++ b/README.md
@@ -53,30 +53,104 @@ If the base image tag `intel/oneapi-basekit:2025.3.2-0-devel-ubuntu24.04` is
not available on Docker Hub, substitute the closest 2025.3.x tag and record
what you used. Do not fall back to `:latest`.
+## Models
+
+Three model keys, all SDXL-architecture, all sharing the fp16-fix VAE, all
+fitting the 12GB card. The registry in `generate.py` (`MODELS`) is the source
+of truth; swapping the default is a one-line key change.
+
+| key | repo | notes |
+|-----------|------------------------------------------|--------------------------------|
+| `sdxl` | stabilityai/stable-diffusion-xl-base-1.0 | general purpose, default |
+| `realvis` | SG161222/RealVisXL_V5.0 | photoreal, permissive license |
+| `pony` | kitty7779/ponyDiffusionV6XL | unrestricted, versatile (ungated diffusers-format mirror; the original AstraliteHeart repo is gated) |
+
+`imggen list` prints this from the wrapper. Pick a model per invocation with
+`-m KEY`; without one, `sdxl` is the default (or the daemon's currently
+resident model, see below).
+
+## Setup
+
+Set up the repo once:
+
+```
+cp .env.example .env
+```
+
+Edit `.env` with your real host paths and, if needed, your uid/gid:
+
+```
+IMGGEN_OUT=/path/to/output # where PNGs land
+IMGGEN_CACHE=/path/to/model-cache # where the ~7.5GB weights are cached
+IMGGEN_PORT=8765 # daemon port, localhost-only
+IMGGEN_MODEL=sdxl # model loaded on `imggen start`
+IMGGEN_UID=1000 # your host uid (id -u)
+IMGGEN_GID=100 # your host gid (id -g)
+```
+
+`.env` is gitignored; `.env.example` documents the keys. `docker compose`
+(via `compose.yaml`) reads it. The service runs as your host user (uid:gid
+plus `group_add: video` for `/dev/dri` access), so generated PNGs are owned
+by you, not root.
+
## Install the wrapper
+The `imggen` script lives in this repo and runs `docker compose` here; it
+`cd`s into `$IMGGEN_DIR` (default `$HOME/Programming/GIT/imggen`) to find
+`compose.yaml` and `.env`. There is nothing to copy elsewhere. Run it in
+place:
+
```
-cp imggen ~/bin/imggen # or anywhere on your PATH
-chmod +x ~/bin/imggen
+./imggen "a red bicycle against a stone wall"
```
-## Usage
+Or put a symlink to it on your PATH for convenience; it still operates on
+the repo via `IMGGEN_DIR`:
```
-imggen "a red bicycle against a stone wall"
-imggen "a foggy harbour at dawn" --steps 30 --seed 42
-imggen "portrait of a fox" -o fox.png -n "blurry, low quality"
+ln -s "$PWD/imggen" ~/bin/imggen
+```
+
+If the repo lives somewhere else, set `IMGGEN_DIR` accordingly.
+
+## Daemon / lifecycle
+
+A persistent daemon (`server.py`, run via `docker compose`) keeps ONE model
+resident in XPU VRAM so repeated prompts skip the ~45s model reload. It
+holds one model at a time (three at once would exceed the 12GB card) and
+swaps on demand. It is serial by construction, one GPU, one request at a
+time.
+
+```
+imggen start [-m KEY] # start daemon, load model (default sdxl), hold VRAM
+imggen stop # stop daemon, free VRAM
+imggen status # is it up? which model? (prints /status JSON, or "daemon down")
+imggen list # show the three model keys
```
-Output lands in `~/imggen-out` by default. Models cache in
-`~/.cache/imggen-models` so the ~7.5GB download happens once.
+**VRAM stays held (~9GB) the whole time the daemon is up, until you run
+`imggen stop`.** Don't leave it running unattended if you need that VRAM
+back.
-Override paths with env vars:
+A bare prompt routes automatically:
```
-IMGGEN_OUT=/srv/blog/img IMGGEN_CACHE=/mnt/models imggen "a lighthouse"
+imggen "a foggy harbour at dawn" --steps 30 --seed 42
+imggen "portrait of a fox" -m realvis -o fox.png -n "blurry, low quality"
```
+- If the daemon is UP, the prompt goes to it. If the requested `-m` differs
+ from the resident model, the daemon swaps first (a few seconds). With no
+ `-m` and an interactive terminal, a menu picks the model. A failed swap
+ (bad repo, gated repo, OOM) prints the daemon's error and the wrapper
+ exits 1.
+- If the daemon is DOWN, the wrapper falls back to a one-shot run: it loads
+ the model, generates, and exits. Slower (pays the ~45s load every time)
+ but requires no daemon management.
+
+Output lands in `$IMGGEN_OUT` (from `.env`). Models cache in `$IMGGEN_CACHE`
+so the ~7.5GB download happens once.
+
## First run
The first invocation downloads SDXL base + the fp16-fix VAE (~7.5GB) into the
@@ -98,3 +172,11 @@ If it sticks, keep it. If it does not, the fallback is a RunPod serverless
ComfyUI endpoint wrapped in the same `imggen` CLI shape, which trades local
privacy for the ability to run heavier models (Flux, refiner, batching)
on-demand at zero idle cost.
+
+## Development Approach
+
+This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback.
+
+All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions.
+
+The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability.