Skip to content
Holden Salomon edited this page Jun 13, 2026 · 11 revisions

Setup Guide

Prerequisites

  • Immich v1.106+ with face recognition enabled and people tagged
  • Frigate v0.16+ (face mode only)
  • Docker with the appropriate GPU runtime (optional but strongly recommended)

1. Get your Immich API key

  1. Open Immich → Account SettingsAPI Keys
  2. Click New API Key, give it a name (e.g. winnow), copy the key

2. Get your Frigate URL

This is the base URL of your Frigate instance, e.g. http://192.168.1.10:5000. Only needed for face mode — omit it entirely if you're using object mode.


3. Choose an image tag

Tag Arch Acceleration
:latest amd64 + arm64 NVIDIA CUDA 13.3 (amd64) · requires NVIDIA Container Toolkit
:rocm amd64 AMD ROCm · pass /dev/kfd + /dev/dri
:intel amd64 Intel Arc / iGPU via OpenVINO · pass /dev/dri, set OPENVINO_DEVICE=GPU
:cpu amd64 + arm64 CPU only · ~2 GB smaller · no GPU required

Use :cpu if your host has no supported GPU — it skips the entire GPU stack. Set a container memory limit of at least 2 GB (mem_limit: 2g) — the embedding models need roughly 1–1.5 GB.


4. Deploy with Docker Compose

Copy compose.yml and .env.example to a directory on your host:

mkdir winnow && cd winnow
curl -O https://raw.githubusercontent.com/sudolulo/winnow/main/compose.yml
curl -O https://raw.githubusercontent.com/sudolulo/winnow/main/.env.example
cp .env.example .env

Edit .env with your values:

IMMICH_URL=http://192.168.1.10:2283
API_KEY=your-immich-api-key
FRIGATE_URL=http://192.168.1.10:5000

Edit the volume paths in compose.yml to point to directories on your host where models, cache, and output crops should be stored:

volumes:
  - /your/path/to/models:/models
  - /your/path/to/cache:/app/.if_cache
  - /your/path/to/output:/app/frigate_train

These directories will be created automatically by Docker if they don't exist.

Start it:

docker compose up -d

Logs:

docker compose logs -f winnow

5. First run

On the first run, winnow downloads the embedding models (~1–2 GB) from HuggingFace and InsightFace. This happens once — subsequent runs use the cached models from your mounted volume and start immediately.


6. Scheduling

CRON_SCHEDULE controls both the run schedule and container lifetime:

CRON_SCHEDULE Behaviour
(unset) Run once on startup, then exit
(empty string) Stay alive; trigger manually with docker exec -it winnow winnow
Cron expression Run on startup, then repeat on schedule

Example — every Sunday at 3 AM:

CRON_SCHEDULE=0 3 * * 0

In scheduled mode the process (and loaded models) stays resident between runs, so each subsequent run starts immediately without re-loading models.


GPU passthrough

NVIDIA

Include the deploy block in your compose.yml (present in the example) and ensure the NVIDIA Container Toolkit is installed on your host:

deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: all
          capabilities: [gpu]

Verify GPU access:

docker run --rm --gpus all nvidia/cuda:13.3.0-base-ubuntu22.04 nvidia-smi

AMD (ROCm)

Use image: ghcr.io/sudolulo/winnow:rocm and replace the deploy: block with:

devices:
  - /dev/kfd
  - /dev/dri
group_add:
  - video
  - render

Intel Arc / iGPU

Use image: ghcr.io/sudolulo/winnow:intel and replace the deploy: block with:

devices:
  - /dev/dri
group_add:
  - render
environment:
  - OPENVINO_DEVICE=GPU   # omit to run OpenVINO inference on CPU (default)

Set OPENVINO_DEVICE=GPU to target the Intel GPU. Omitting it (or setting CPU) runs OpenVINO on CPU — useful if you want Intel's optimised runtime without GPU passthrough.


Debugging

Set VERBOSE=true in your .env to enable DEBUG-level output on the console. The log file always captures DEBUG regardless of this setting:

# log file is written to the output volume (frigate_train mount)
docker exec winnow cat /app/frigate_train/winnow.log

Environment Variables

Connection

Variable Default Description
IMMICH_URL (required) Full URL to your Immich instance
API_KEY (required) Immich API key
FRIGATE_URL (unset) Frigate base URL — required for face upload; omit for object mode only

Mode & Strategy

Variable Default Description
TRAINING_MODE face face — upload crops to Frigate; object — save crops to disk
STRATEGY auto auto (embedding-based adaptive), standard (30 images), broad (100 images)
LIMIT (unset) Exact image count — overrides STRATEGY
OBJECT_CLASS dog Target class for object mode (any YOLO class: dog, cat, car, etc.)
AUTO_MODE (auto) Force non-interactive mode in a terminal; auto-detected otherwise
VERBOSE false Enable DEBUG-level console output (log file is always DEBUG)

People Filtering

Variable Default Description
ONLY_PEOPLE (unset) Comma-separated whitelist — process only these people
SKIP_PEOPLE (unset) Comma-separated list — skip these people
MIN_FACE_COUNT 0 Skip people with fewer than N tagged assets in Immich
YEARS_FILTER 10 Ignore images older than N years

Image Quality

Variable Default Description
MIN_FACE_WIDTH 90 Minimum face crop width in pixels
FACE_MARGIN 0.15 Padding around bounding box crop (fraction of face size)
ENABLE_FACE_ALIGNMENT true Align to ArcFace 112×112 format using facial landmarks
USE_FULL_RESOLUTION true Download full-resolution originals rather than preview thumbnails
MIN_CONFIDENCE 0.7 Minimum Immich face detection confidence
BLUR_THRESHOLD 120.0 Laplacian variance threshold — higher rejects more blur
MAX_AUTO_IMAGES 80 Maximum training images per person in Frigate
QUALITY_REPLACEMENT true When at cap, swap a weaker tracked image for a better candidate. With Frigate scoring active, targets the most redundant image (highest recognize score); otherwise uses blur score. Never touches manually added Frigate files. Set false to skip people at cap
FRIGATE_SCORE_CEILING 0.0 Skip uploads whose pre-upload Frigate recognize score exceeds this value — they are already well-covered. 0 disables; requires at least one prior run to have scores
ENABLE_FRIGATE_SCORES true Call Frigate's recognize endpoint pre-upload to store diversity scores used for quality replacement. Adds ~200 ms per upload. Disable to use blur-score replacement only

GPU & Models

Variable Default Description
FORCE_CPU false Disable GPU — fall back to CPU for all inference
OPENVINO_DEVICE CPU Intel variant only: set GPU to use Arc or iGPU
ENABLE_CACHE true Cache computed embeddings to disk (speeds up re-runs on the same library)
CACHE_DIR .if_cache Path for embedding cache and upload tracker files
HF_HOME (system) HuggingFace model cache path (SigLIP)
INSIGHTFACE_HOME (system) InsightFace model cache path (Buffalo_L)

Output

Variable Default Description
OUTPUT_DIR ./frigate_train Directory for object-mode crops and the winnow.log file. In Docker, set this via the volume mount instead

Tracker Overrides (one-shot — remove after use)

Variable Default Description
DRY_RUN false Preview selection without downloading or uploading
RETRY_REJECTED false Re-attempt assets previously rejected by Frigate
RESET_PERSON (unset) Clear upload history for one person and delete their winnow-managed Frigate training files so the next run starts fresh. Manually added Frigate files are never touched

Scheduling

Variable Default Description
CRON_SCHEDULE (unset) Unset = run once and exit; empty string = stay alive; cron expression = scheduled

Clone this wiki locally