When Immich has multiple person records sharing a name (e.g. unmerged
face clusters), winnow would previously run separate jobs for each,
with the second job wiping the first job's output directory — resulting
in far fewer training images than expected.
New behaviour:
- At startup, duplicate names are detected and a warning is printed
showing asset counts for each duplicate.
- By default (MERGE_DUPLICATE_PEOPLE=false), only the person with the
most assets is processed; smaller duplicates are skipped cleanly.
- With MERGE_DUPLICATE_PEOPLE=true, the duplicates are permanently
merged inside Immich via PUT /api/people/{id}/merge (keeps the
largest), then the people list is re-fetched before jobs run.
Also adds an explicit comment in executor.py confirming that replacement
targets come exclusively from tracker-mapped files, so manually-added
Frigate training images are never selected for deletion.
93 lines
5.4 KiB
YAML
93 lines
5.4 KiB
YAML
services:
|
|
winnow:
|
|
image: ghcr.io/sudolulo/winnow:latest
|
|
container_name: winnow
|
|
environment:
|
|
# ── Required ──────────────────────────────────────────────────────────
|
|
- IMMICH_URL=${IMMICH_URL}
|
|
- API_KEY=${API_KEY}
|
|
- FRIGATE_URL=${FRIGATE_URL}
|
|
|
|
# ── Mode & Strategy ───────────────────────────────────────────────────
|
|
# Auto mode is active by default when no TTY is present (Docker/cron).
|
|
# Set AUTO_MODE=true to force auto mode in an interactive terminal.
|
|
# To run interactively: docker exec -it winnow winnow
|
|
# - VERBOSE=true # Enable DEBUG-level console output
|
|
# TRAINING_MODE: face = upload to Frigate face recognition API
|
|
# object = save crops to output dir for manual Frigate placement
|
|
- TRAINING_MODE=face
|
|
# STRATEGY: auto = objective diversity (recommended), standard = 30 imgs, broad = 100 imgs
|
|
- STRATEGY=auto
|
|
# - LIMIT=50 # Custom image count; overrides STRATEGY preset
|
|
# - OBJECT_CLASS=dog # Object label for object mode (e.g. dog, cat, car)
|
|
|
|
# ── People Filtering ──────────────────────────────────────────────────
|
|
# - ONLY_PEOPLE=John,Jane # Comma-separated; process only these people
|
|
# - SKIP_PEOPLE=Unknown # Comma-separated; skip these people
|
|
# - MIN_FACE_COUNT=5 # Skip people with fewer than N assets in Immich
|
|
# - YEARS_FILTER=10 # Only include images from the last N years (default: 10)
|
|
# - MERGE_DUPLICATE_PEOPLE=true # Auto-merge Immich people with the same name (keeps most assets)
|
|
|
|
# ── Image Quality ─────────────────────────────────────────────────────
|
|
# - MIN_FACE_WIDTH=50 # Minimum face width in pixels (default: 50)
|
|
# - FACE_MARGIN=0.15 # Padding around face crop as fraction (default: 0.15)
|
|
# - ENABLE_FACE_ALIGNMENT=true # Align face before cropping (default: true)
|
|
# - USE_FULL_RESOLUTION=true # Use full-res images vs thumbnails (default: true)
|
|
# - MIN_CONFIDENCE=0.7 # Minimum face detection confidence (default: 0.7)
|
|
# - BLUR_THRESHOLD=100.0 # Laplacian blur threshold; lower = accept more blur (default: 100.0)
|
|
# - MAX_AUTO_IMAGES=80 # Hard cap on auto-diversity selection (default: 80)
|
|
|
|
# ── Caching & Models ──────────────────────────────────────────────────
|
|
# - FORCE_CPU=true # Disable GPU, fall back to CPU
|
|
# - OPENVINO_DEVICE=GPU # Intel variant only: use Arc/iGPU instead of CPU (default: CPU)
|
|
# - ENABLE_CACHE=false # Disable embedding cache (default: true)
|
|
- CACHE_DIR=/app/.if_cache
|
|
- HF_HOME=/models/huggingface
|
|
- INSIGHTFACE_HOME=/models/.insightface
|
|
|
|
# ── Tracker overrides (one-shot, remove after use) ────────────────────
|
|
# - DRY_RUN=true # Preview selection without downloading/uploading
|
|
# - RETRY_REJECTED=true # Re-attempt previously rejected images
|
|
# - RESET_PERSON=John # Clear uploaded+rejected history for one person
|
|
|
|
# ── Scheduling ────────────────────────────────────────────────────────
|
|
# CRON_SCHEDULE controls container lifetime:
|
|
# unset — run once on startup, then exit
|
|
# empty string — stay alive, run nothing; trigger manually with:
|
|
# docker exec -it winnow winnow
|
|
# cron expression — run on startup, then on schedule
|
|
# - CRON_SCHEDULE= # Manual mode (keep alive, no auto-run)
|
|
# - CRON_SCHEDULE=0 3 * * 0 # Every Sunday at 3 AM
|
|
# - CRON_SCHEDULE=0 3 1 * * # First of every month
|
|
volumes:
|
|
# Replace with absolute paths on your host, e.g. /opt/winnow/models
|
|
- /path/to/winnow/models:/models
|
|
- /path/to/winnow/cache:/app/.if_cache
|
|
- /path/to/winnow/output:/app/frigate_train
|
|
restart: unless-stopped
|
|
|
|
# ── GPU device passthrough ─────────────────────────────────────────────────
|
|
# NVIDIA (default — requires nvidia-container-toolkit):
|
|
deploy:
|
|
resources:
|
|
reservations:
|
|
devices:
|
|
- driver: nvidia
|
|
count: all
|
|
capabilities: [gpu]
|
|
#
|
|
# AMD ROCm — replace the deploy block above with:
|
|
# devices:
|
|
# - /dev/kfd
|
|
# - /dev/dri
|
|
# group_add:
|
|
# - video
|
|
# - render
|
|
#
|
|
# Intel Arc / iGPU — replace the deploy block above with:
|
|
# devices:
|
|
# - /dev/dri
|
|
# group_add:
|
|
# - render
|
|
# Also set: OPENVINO_DEVICE=GPU in the environment section above.
|