Commit Graph
17 Commits
Author SHA1 Message Date
flanandClaude Sonnet 4.6 b2be19e259 feat: add ROCm (AMD GPU) and Intel GPU support (v0.2.12)
New image variants:
- :rocm  — InsightFace via ROCmExecutionProvider, SigLIP via PyTorch ROCm 6.3
- :intel — InsightFace via OpenVINOExecutionProvider (onnxruntime-openvino);
           Intel GPU compute runtime auto-installed from Intel graphics repo;
           OPENVINO_DEVICE=GPU opts into Arc/iGPU inference (default: CPU)

Also adds:
- pyproject-rocm.toml + uv-rocm.lock, pyproject-intel.toml + uv-intel.lock
- compose.yml device passthrough snippets for AMD and Intel
- CI: build-rocm and build-intel jobs in docker-publish.yml; all four
  variants built and tagged in release.yml
- README reworked: cleaner structure, GPU variant quick-start examples,
  OPENVINO_DEVICE env var documented
- CHANGELOG entry and version bump to 0.2.12

Fix: IntPrompt in dict literal was eagerly evaluated in the no-embedding
fallback path of _get_strategy_choice, prompting users for a custom count
regardless of which strategy they picked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 02:31:09 +00:00
flanandClaude Sonnet 4.6 882af37d8e feat: VERBOSE=true enables DEBUG-level console output
The log file already captures DEBUG unconditionally. This env var wires
the same to the Rich console handler for troubleshooting without needing
to read the log file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:49:28 +00:00
flanandClaude Sonnet 4.6 3db52c2141 fix+logging: model load logging, CPU fallback, log level audit
Bugs fixed (from high-effort review):
- InsightFace CPU fallback now passes providers=['CPUExecutionProvider'] and
  wraps in _suppress_output() so broken GPU drivers don't cause fallback to
  try the same broken provider again, and C-extension noise stays suppressed
- scheduler.py: BaseException → Exception (KeyboardInterrupt already re-raised;
  winnow has no sys.exit() calls, so SystemExit would not occur, but Exception
  is the correct scope)
- compose.yml: fix inverted AUTO_MODE comment (docker run -it enables
  interactive mode via TTY, not non-interactive)

Model loading logging (embeddings.py):
- InsightFace: disk cache check, "not cached — downloading now (~300 MB)",
  "loading into memory on GPU/CPU...", "ready on GPU/CPU (Xs)"
- SigLIP: same treatment; cache path derived dynamically from model_name
  via HuggingFace slug convention (models--org--model) so it stays correct
  if the model variant ever changes

Logging level audit (INFO/DEBUG/WARNING/ERROR):
- diversity.py: internal algo steps (clustering, medoids, adaptive threshold,
  auto-stop decision) → DEBUG; final selection summaries stay INFO
- immich_api.py: "Fetching assets" and "Retained N assets" → DEBUG (callers
  already print this to the console via rprint)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:23:44 +00:00
flanandClaude Sonnet 4.6 015db63d19 feat: empty CRON_SCHEDULE keeps container alive for manual docker exec
Three container lifetime modes via CRON_SCHEDULE:
  unset          — run once on startup, exit
  empty string   — sleep infinity; use docker exec -it winnow winnow
  cron expression — run on startup, then on schedule

This replaces the need for a separate MANUAL_MODE env var. The empty
string is a natural "I want the container alive but unscheduled" signal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:01:00 +00:00
flanandClaude Sonnet 4.6 2804b21f9e refactor: auto-detect headless mode via TTY; AUTO_MODE becomes an override
The primary use case is headless Docker, so auto mode is now the default
whenever stdin has no TTY. Interactive mode activates when a terminal is
present (docker run -it, local shell). AUTO_MODE=true remains as an
explicit override for scripting with a pseudo-TTY.

Removes AUTO_MODE=true, stdin_open, tty, and FORCE_CPU=false from
compose.yml — none are needed for headless operation. Updates README
and the interactive-mode hint in the CLI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 14:59:09 +00:00
flanandClaude Sonnet 4.6 196b0a5147 fix: INSIGHTFACE_HOME path, entrypoint, caching default, CRON_SCHEDULE opt-in
- Dockerfile: ENV INSIGHTFACE_HOME=/models → /models/.insightface to
  match compose.yml and .env.example; the old value caused InsightFace
  to store models at /models/models/buffalo_l (double-appended subdir)
- entrypoint.sh: use /app/.venv/bin/winnow (installed entry point)
  instead of python -m winnow.cli
- config.py: ENABLE_CACHE default false → true; embedding cache is
  always beneficial in practice; users can opt out with ENABLE_CACHE=false
- compose.yml: comment out CRON_SCHEDULE so scheduling is opt-in;
  flip ENABLE_CACHE to commented opt-out to reflect new default
- README.md: update ENABLE_CACHE default documentation to true
- tests/test_config.py: update default assertion to match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 05:36:47 +00:00
flanandClaude Sonnet 4.6 e4d5f603d8 docs: remove TrueNAS references, make volume paths platform agnostic
- compose.yml: generic /path/to/winnow/... placeholder paths
- docs/setup.md: replace TrueNAS section with generic GPU passthrough guide
- docs/faq.md: remove platform-specific path example
- README.md: soften crop quality disclaimer, remove TrueNAS compose note
- CHANGELOG.md: scrub TrueNAS mentions from release notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 02:13:29 +00:00
flanandClaude Sonnet 4.6 c3bf81d490 fix: direct venv python in entrypoint, fix INSIGHTFACE_HOME path, add badges
- entrypoint.sh: replace `uv run` with `/app/.venv/bin/python` to skip
  uv's sync check which was re-downloading ruff and rebuilding the package
  on every container startup
- compose.yml, .env.example: fix INSIGHTFACE_HOME /models → /models/.insightface;
  InsightFace appends models/ to root, so /models produced /models/models/buffalo_l
- README.md: add Immich and Frigate badges from upstream
- CHANGELOG.md, pyproject.toml, uv.lock: bump to 0.2.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 02:10:01 +00:00
flanandClaude Sonnet 4.6 eea7baa19f refactor: rename project to winnow
- Rename Python package directory if_curator/ → winnow/
- Update all imports, entry points, and CLI references
- Update pyproject.toml: name, scripts, package list, repository URL
- Update Dockerfile, compose.yml, entrypoint.sh, scheduler.py
- Update GitHub Actions workflow image names
- Update README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 01:07:46 +00:00
flanandClaude Sonnet 4.6 c861d56a53 feat: expose all interactive CLI options via env vars
- config.py: wire BLUR_THRESHOLD, MIN_CONFIDENCE, MAX_AUTO_IMAGES,
  FACE_MARGIN, USE_FULL_RESOLUTION, ENABLE_FACE_ALIGNMENT to env vars
  (were hardcoded class defaults, inaccessible in AUTO_MODE)
- jobs.py: add LIMIT env var for custom image count in auto mode;
  overrides STRATEGY preset (mirrors interactive Custom Count option)
- compose.yml: document all env vars with inline comments grouped by
  concern — mode/strategy, people filtering, image quality, caching,
  tracker overrides, scheduling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 00:37:16 +00:00
flanandClaude Sonnet 4.6 52c245a677 fix: correct output volume mount path to match OUTPUT_DIR default
Volume was mounted at /app/output but OUTPUT_DIR defaults to
./frigate_train (i.e. /app/frigate_train). Mount was never being used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 00:32:39 +00:00
flanandClaude Sonnet 4.6 0f3e67d5cc fix: clean output dir per run, fix cron inline comment, clarify volume placeholder
- executor.py: wipe person output dir before each run so stale crops
  from previous runs don't accumulate on disk
- compose.yml: move inline comment off CRON_SCHEDULE value (croniter
  would parse the comment text as part of the expression)
- compose.yml: add note clarifying <pool> placeholder in volume paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 00:27:52 +00:00
flanandClaude Sonnet 4.6 d106d30060 feat: RGBA fix, per-person tracking, dry-run, retry-rejected, reset-person
- Fix RGBA→JPEG error: convert all images to RGB before saving
- Upload tracker: per-person breakdown in JSON, reset_person(), get_person_summary()
- mark_rejected() only fires on face-detection failures (not all HTTP 400s)
- New env vars: DRY_RUN, RETRY_REJECTED, RESET_PERSON
- Tracker summary printed at startup showing uploaded/rejected counts per person
- Document new env vars in compose.yml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 22:39:11 +00:00
root b9b734507b automated update: 2026-06-10 22:25:47 2026-06-10 22:25:47 -04:00
flan fc1afb1b58 Update compose.yml 2026-06-10 16:11:19 -04:00
flan cfc2018090 Update compose.yml 2026-06-10 15:56:37 -04:00
flan 9c1fbc1da2 Create compose.yml 2026-06-10 15:25:57 -04:00