- Python 89.5%
- Dockerfile 10.5%
| .forgejo/workflows | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
| requirements.txt | ||
| tagger.py | ||
immich-ram-tagger
Weekly batch tagger for Immich, powered by
RAM++ (Recognize Anything Plus).
Adds hierarchical AI tags (AI/RAM++/<tag>) to every image asset in your
Immich library so they're distinguishable from human-curated tags and bulk-
deletable later.
This repo only produces the container image. The Kubernetes deployment
manifests live in the synapse cluster repo at
kubernetes/infrastructure/immich-tagger/.
What it does
- Connects directly to Immich Postgres (read of
assettable + this script's owntagger_statetable for resumability). - For each pending asset: fetches the preview via Immich API, runs RAM++
inference (CPU), collects tags above the configured threshold, posts
each tag via Immich API as
AI/RAM++/<tag>, marks the asset done. - Exits when there are no more pending assets, or when
MAX_ASSETSis hit.
Designed as the entrypoint of a weekly Kubernetes CronJob. Resumable across
runs - the state table ensures previously-tagged assets aren't re-tagged
unless RAM_MODEL_VERSION is bumped.
Configuration
All via environment variables:
| Variable | Default | Notes |
|---|---|---|
RAM_MODEL_URL |
HuggingFace URL for ram_plus_swin_large_14m.pth |
Source for first-run download |
RAM_MODEL_PATH |
/cache/ram-plus/ram_plus_swin_large_14m.pth |
Where to cache (NFS-backed in cluster) |
RAM_MODEL_VERSION |
ram_plus_swin_large_14m |
Stored per-asset; bump to force re-tagging |
RAM_IMAGE_SIZE |
384 |
Inference resolution (RAM++ default) |
RAM_THRESHOLD |
0.55 |
Per-class sigmoid threshold; upstream default is 0.68 |
RAM_TAG_PREFIX |
AI/RAM++ |
Hierarchy root for tags created by this tool |
IMMICH_BASE_URL |
http://immich-server.immich.svc.cluster.local:2283 |
|
IMMICH_API_KEY |
required | Library-owner API key |
DB_HOSTNAME |
required | |
DB_PORT |
5432 |
|
DB_DATABASE_NAME |
immich |
|
DB_USERNAME |
immich |
|
DB_PASSWORD |
required | |
BATCH_SIZE |
200 |
Rows per pending-asset query |
MAX_ASSETS |
0 (unlimited) |
Cap per run if predictable runtime needed |
OMP_NUM_THREADS |
4 |
Torch CPU thread count |
API key permissions
Generate the API key in Immich UI as the library-owning user with:
asset.read(preview download)tag.create,tag.read,tag.update(upsert + attach tags)
Tags in Immich are per-user; only the library owner's API key can attach tags to assets in their library.
Building locally
podman build -t git.lost-synapse.com/lostsynapse/immich-ram-tagger:dev .
podman push git.lost-synapse.com/lostsynapse/immich-ram-tagger:dev
State table
CREATE TABLE IF NOT EXISTS tagger_state (
asset_id UUID PRIMARY KEY,
tagged_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
model_ver TEXT NOT NULL,
tag_count INT NOT NULL
);
Lives in the Immich database. Auto-created on first run. Not touched by
Immich migrations (Immich has no tagger_state table of its own).
To force re-tag of everything: bump RAM_MODEL_VERSION env in the CronJob
to a new string. The query joins on model_ver, so non-matching rows are
treated as pending.
To wipe state entirely: TRUNCATE tagger_state;.
License & attribution
- RAM++ model and code: xinyu1205/recognize-anything, Apache 2.0
- This wrapper: see
LICENSE