Clone
11
Setup
Holden Salomon edited this page 2026-06-14 21:56:11 +00:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Setup Guide

Prerequisites

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

1. Get your Immich API key

  1. Open Immich → Account Settings → API 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.


3. Choose an image tag

Tag Arch Acceleration
:latest amd64 NVIDIA CUDA 12.8 · requires NVIDIA Container Toolkit · minimum driver 570
: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 · ~300 MB smaller · no GPU required

Use :cpu if your host has no supported GPU. Set a container memory limit of at least 2 GB (mem_limit: 2g) — the InsightFace model needs roughly 600 MB–1 GB.


4. Deploy with Docker Compose

Copy compose.yml to a directory on your host:

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

Create a .env file 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 should be stored:

volumes:
  - /your/path/to/models:/models
  - /your/path/to/data:/app/data
  - /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 InsightFace Buffalo_L (~300 MB) if it isn't already cached in the models volume. Subsequent runs start immediately using the cached model.


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 model) stays resident between runs, so each subsequent run starts immediately without re-loading the model.


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:12.8.1-base-ubuntu22.04 nvidia-smi

AMD (ROCm)

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

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

Intel Arc / iGPU

Use image: ghcr.io/sudoludo/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)

OPENVINO_DEVICE selects the compute device within the OpenVINO runtime:

  • GPU — Intel iGPU or Arc GPU (requires /dev/dri passthrough)
  • CPU (default) — CPU cores via OpenVINO's CPU plugin (optimised AVX512 kernels). This is not the iGPU — it runs on the CPU itself but is meaningfully faster than standard CPUExecutionProvider.

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

Mode & Strategy

Variable Default Description
STRATEGY adaptive adaptive — embedding-based diversity selection, stops when candidates become redundant; standard — fixed 30 images; broad — fixed 100 images. auto is a legacy alias for adaptive
LIMIT (unset) Exact image count — overrides STRATEGY preset
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 3 Skip people with fewer than N tagged assets in Immich
YEARS_FILTER 10 Ignore images older than N years
MERGE_DUPLICATE_PEOPLE false When Immich has multiple person records with the same name (a common side-effect of face clustering), winnow warns and processes only the largest. Set true to permanently merge duplicates in Immich instead. This modifies Immich and cannot be undone — only enable once you've verified the duplicates are the same person.

Image Quality

Variable Default Description
MAX_AUTO_IMAGES 20 Maximum training images per person winnow will manage in Frigate. Conservative default so winnow supplements — not dominates — a training set that should be primarily built from manually curated images
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 pre-upload recognize score); otherwise uses blur score. Never touches manually added Frigate files. Set false to skip people at cap

Advanced Tuning (calibrated — do not adjust)

The following variables control quality thresholds that are pre-calibrated for Frigate's ArcFace requirements. Changing them may cause image quality issues. Support will not be provided for problems caused by non-default values.

Variable Default Description
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
FRIGATE_SCORE_CEILING (unset) Below-cap novelty gate. Unset (default): dynamic — skips candidates whose Frigate score exceeds the most-redundant tracked file's score, accounting for manually-added images. 0: disabled. Positive value (e.g. 0.85): fixed hard ceiling. Requires ENABLE_FRIGATE_SCORES=true and at least one prior run
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

GPU & Models

Variable Default Description
FORCE_CPU false Disable GPU — fall back to CPU for all inference
OPENVINO_DEVICE CPU Intel variant only: GPU = iGPU/Arc (requires /dev/dri); CPU = OpenVINO CPU plugin (optimised CPU kernels, not the iGPU)
ENABLE_CACHE true Cache computed embeddings to disk (speeds up re-runs on the same library)
DATA_DIR data Path for embedding cache and upload tracker database (winnow_tracker.db)
INSIGHTFACE_HOME (system) InsightFace model cache path (Buffalo_L)

Output

Variable Default Description
OUTPUT_DIR ./frigate_train Directory where face crops are staged before upload and where winnow.log is written. 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) Set to a person's name to clear their upload history and delete their winnow-managed Frigate training files so the next run starts fresh. Set to * to reset all tracked people at once. Manually added Frigate files are never touched
TRACE_CROP_SIZE (unset) Debug: print all tracked crops whose width or height matches this pixel value, then exit

Scheduling

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