Skip to content

Face Recognition

PhotoPrism recognizes faces in three stages, so your pictures can be easily organized by person:

  1. Detection — a detection model locates faces in each image.
  2. Embedding — a vector is generated to characterize each face.
  3. Clustering — similar faces are grouped so they can be assigned to a person.

Detection and embedding use separate models, so each can be chosen and upgraded on its own.

If faces are missing, people are grouped incorrectly, or tagging is slow, work through the checklists under Troubleshooting > Face Recognition.

Upgrading an Existing Library

Libraries indexed before the current embedding model became available keep the model they already use, because vectors produced by different models cannot be compared: switching automatically would make every face you have already assigned to a person incomparable with newly indexed ones. Setting PHOTOPRISM_FACE_MODEL does not change it either.

Create a backup before you migrate or reset. A migration replaces the stored vector of every face and rebuilds every automatic cluster, and a reset deletes clusters, names, or markers. Neither can be undone except by restoring a backup.

photoprism faces migrate is what changes it. It re-embeds every face, keeps the people you have already identified, and records the new model as the one in use. It defaults to the model this release supports, so an ordinary upgrade needs no target — run it in a terminal with --dry-run first to see what it would cover:

photoprism faces migrate --dry-run # report the scope, change nothing
photoprism faces migrate           # re-embed every face

Expect it to take a while on a large library. Name a different target with --to only if you are migrating somewhere other than the model this release supports — or if this instance has PHOTOPRISM_FACE_MODEL set to none, which is kept rather than overridden, so the target has to be named.

Restart your instance once the migration has finished. It records the new model in options.yml, which a running instance does not reload, so face embedding work stays paused until it starts again. You do not need to stop the instance beforehand: a migration takes a lock the instance reads, so indexing and vision wait for it and edits to people are refused while it runs. Start it when no indexing or import is already under way, though — that lock is checked when such a run begins, not while one is in progress.

Afterwards, let the detector find the faces it previously missed and settle the clusters:

photoprism faces audit --fix    # resolve inconsistencies
photoprism faces index          # detect additional faces
photoprism faces update --force # re-match and cluster faces
photoprism faces optimize       # optional tidy-up

--force is what matters there: a plain photoprism faces update runs only once enough faces have been added since the last pass, which a freshly migrated library has not. With --force the pass runs regardless, every face is matched against the clusters again, and the ones left unassigned are clustered at the current settings. An automatically matched face may end up in a different cluster, while a face that you assigned manually keeps its assignment. Reach for it whenever faces have been detected but People shows no cluster for them.

To check the result, photoprism faces status reports which model is in use and why clustering is waiting if no clusters are forming.

If you would rather start from a clean state, create a backup, then run photoprism faces reset -f followed by photoprism faces index. All detected faces must then be reassigned.

A complete rescan will also detect additional faces, but takes longer since more indexing tasks are performed.

Creating a Backup

Faces, clusters, and people are stored in the index database, so a dump of it is what lets you undo a migration or a reset. Save the dump under a name of its own rather than the default date-based one: scheduled backups replace a dump from the same day and delete older ones beyond the configured limit, but they leave a file with any other name alone.

photoprism backup -i /photoprism/storage/backup/before-faces.sql

Before a migration, also keep a copy of the options.yml file in your config folder, which is storage/config unless you changed it, or note that it does not exist yet. The migration records the new model there, so a restored database without the matching options.yml would leave face embedding work paused, because the configured model cannot read the restored vectors.

To roll back, restore the dump, put the saved options.yml back (or delete the one the migration created), and restart your instance:

photoprism restore -i -f /photoprism/storage/backup/before-faces.sql

The path shown is where the storage folder is mounted in our Docker images; adjust it if yours is elsewhere. When running commands with Docker Compose, prefix them with docker compose exec photoprism. For a complete backup that also covers your originals and thumbnails, see Creating Backups.

Face Detection

PhotoPrism ships with YuNet, a compact face detection model that runs on ONNX. It detects faces that are partially occluded (covered by hands, objects, etc.), works well with off-axis or angled faces, effectively handles difficult lighting conditions, and locates facial landmarks, which are used to align each face before embedding.

A custom detector can be selected with PHOTOPRISM_FACE_DETECTOR. If left unset, the detector is derived from the face model in use, so a matching combination is the default.

PHOTOPRISM_FACE_ENGINE is deprecated: it selected a runtime rather than a model. Only PHOTOPRISM_FACE_ENGINE=none still has an effect, and PHOTOPRISM_FACE_DETECTOR overrides it. Existing configurations keep working.

Small Faces in Group Pictures

PHOTOPRISM_FACE_SIZE is measured on the 720 px thumbnail used for detection, not on the original picture. In a crowded photo this can push every face below the minimum, so PhotoPrism automatically runs a second pass at a smaller minimum size when a picture would otherwise yield no faces at all. Set PHOTOPRISM_FACE_SIZE_RETRY to -1 to switch that off.

Using Faces Without Automatic Detection

If you only want to see faces you mark yourself or import from XMP metadata, without PhotoPrism detecting faces in your pictures, set PHOTOPRISM_FACE_RUN to "never":

  • The People section, existing faces, and names remain available.
  • Faces can still be marked and named manually in the full-screen viewer.
  • Face regions and names from XMP metadata are still imported when Import Faces from XMP is enabled.

Faces you mark manually or import from XMP are not compared with other faces, so they are not assigned to people automatically. Faces that were detected before you changed the setting are kept, and can still be grouped and matched when you name a person.

Do not use PHOTOPRISM_DISABLE_FACES for this purpose: it turns off face detection and recognition completely and also hides the People section and face markers.

Face Embeddings

After detection, PhotoPrism generates an embedding vector that characterizes each face. These vectors are used to:

  1. Match faces across different pictures.
  2. Group similar faces automatically.
  3. Assign faces to people with manual confirmation.

New libraries use SFace. Libraries created before it was available keep FaceNet, because switching would make every face already assigned to a person incomparable with newly indexed ones.

Setting PHOTOPRISM_FACE_MODEL does not change the model of a library that already has one — use photoprism faces migrate for that, which re-embeds every face and keeps your person assignments. See Upgrading an Existing Library above.

How these vectors are stored and compared is covered in the Developer Guide.

Learn more ›

Config Options

We recommend that only advanced users and developers change these parameters. The tables below cover the ones most often adjusted; Config Options › Face Recognition lists them all.

Detection Settings

Environment Variable CLI Flag Default Description
PHOTOPRISM_FACE_RUN --face-run auto WHEN face detection and recognition should run (auto, always, on-index, newly-indexed, on-schedule, on-demand, manual, never)
PHOTOPRISM_FACE_DETECTOR --face-detector yunet face detection model NAME (auto, yunet, none), derived from the face model unless named
PHOTOPRISM_FACE_SIZE --face-size 25 minimum size of faces in PIXELS (10-10000)
PHOTOPRISM_FACE_SIZE_RETRY --face-size-retry 10 (20 where a crop can reach no further than 1920, off at 720) minimum size of faces in PIXELS when a picture would otherwise have none, -1 to disable
PHOTOPRISM_FACE_SCORE --face-score 65 minimum face QUALITY score (1-100; -1 to disable), calibrated per detector when unset
PHOTOPRISM_FACE_OVERLAP --face-overlap 42 face area overlap threshold in PERCENT (1-100)
PHOTOPRISM_FACE_MODEL --face-model sface face embedding model NAME (auto, sface, none), changed with photoprism faces migrate

Clustering Settings

After changing any of the clustering parameters, run photoprism faces update --force in a terminal so that a pass runs at the new values instead of waiting for enough new faces. It applies them to the faces that are not yet in a cluster and matches every face against the clusters again; an automatically matched face may end up in a different cluster, while a face that you assigned manually keeps its assignment. Run photoprism faces reset if you want the library regrouped from scratch, after creating a backup. Changing the embedding model is a different operation and requires photoprism faces migrate.

Environment Variable CLI Flag Default Description
PHOTOPRISM_FACE_CLUSTER_SIZE --face-cluster-size 112 minimum size of automatically clustered faces in embedding source PIXELS (20-10000), calibrated per face model when unset
PHOTOPRISM_FACE_CLUSTER_SCORE --face-cluster-score 85 minimum QUALITY score of automatically clustered faces (1-100; -1 to disable), calibrated per detector when unset
PHOTOPRISM_FACE_CLUSTER_CORE --face-cluster-core 5 NUMBER of faces forming a cluster core (2-100)
PHOTOPRISM_FACE_CLUSTER_DIST --face-cluster-dist 0.72 similarity DISTANCE of faces forming a cluster core (collision distance to 1.25), calibrated per face model when unset
PHOTOPRISM_FACE_MATCH_DIST --face-match-dist 0.25 similarity OFFSET for matching faces with existing clusters, calibrated per face model when unset; radius plus match distance may not exceed 1.25
PHOTOPRISM_FACE_MATCH_MARGIN --face-match-margin 0.01 minimum DISTANCE by which the best matching cluster must beat the runner-up (-1 to disable)

The distance thresholds are calibrated for each embedding model and resolved automatically, because the models do not share a vector space — a distance that separates two people under one model can merge them under another.

Tuning Tips

  • Change a distance threshold relative to the value your model resolves to, rather than carrying a number over from another model. A higher value is more aggressive and leads to larger clusters with more false positives.
  • Leave PHOTOPRISM_FACE_DETECTOR unset unless you have a reason to pin it, so detection stays matched to the embedding model.

CLI Reference

  • photoprism faces status — show which options are actually in force, including the ones resolved from the detector or model, and why clustering is waiting if no clusters are forming. faces config is an alias.
  • photoprism faces subjects [name|uid] — list people with the clusters, files, and photos their markers support.
  • photoprism faces ls [name|uid] — list face clusters with their samples, radius, current markers, and Detail, the mean share of the crop their members' source could supply. faces clusters is an alias.
  • photoprism faces markers [name|uid] [--face ID] [--unassigned] [--dangling] — list face markers, what they are assigned to, and their Detail score.
  • photoprism faces conflicts [name|uid] — list face clusters that hold the same face but are assigned to different people.
  • photoprism faces audit [--subject UID] [--fix] — check and optionally repair face data.
  • photoprism faces reset [--detector auto|none|yunet] [--all] [--force] — remove automatic clusters and matches; --all also removes names while keeping the markers, --force removes the markers too so faces must be detected again.
  • photoprism faces index — (re)detect faces in originals.
  • photoprism faces update [--force] — cluster and match detected faces.
  • photoprism faces optimize — compact clusters after updates.
  • photoprism faces migrate [--to MODEL] [--dry-run] — re-embed every face with another model, then restart the instance. See Upgrading an Existing Library.