-
Notifications
You must be signed in to change notification settings - Fork 0
Setup
- 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)
- Open Immich → Account Settings → API Keys
- Click New API Key, give it a name (e.g.
winnow), copy the key
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.
| 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.
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 .envEdit .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:5000Edit 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_trainThese directories will be created automatically by Docker if they don't exist.
Start it:
docker compose up -dLogs:
docker compose logs -f winnowOn 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.
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.
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-smiUse image: ghcr.io/sudolulo/winnow:rocm and replace the deploy: block with:
devices:
- /dev/kfd
- /dev/dri
group_add:
- video
- renderUse 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.
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