Four Layers, One Library
Indexing runs as a sequence of background workers. Each stage writes to the same SQLite catalog and each one is independently useful — you can stop after any of them and still have a working library.
The Auto Sequence runs Discovery → Processing → AI Metadata → Semantic Prep → Visual Similarity → Faces in one pass, but each stage is a separate worker you can trigger on its own from the Tools panel. A library with only Discovery finished is already browsable and filterable by date, camera and rating.
Where the Models Actually Run
Voyager does not ship a model server. It talks to one you run, which means you choose the model, the hardware and the trade-offs. Four engines are supported, and the built-in LLM Setup Wizard inspects your CPU, RAM and GPU before recommending one.
| Engine | Default endpoint | Best for |
|---|---|---|
| Ollama | http://localhost:11434 |
The common choice on a machine with a discrete GPU. |
| llama-cpp-python | In-process — no server | CPU-only machines. Loads GGUF weights directly; the wizard defaults to this when no discrete GPU is found. |
| LM Studio | http://localhost:1234/v1 |
Users who already manage models through LM Studio's interface. |
| vLLM | http://localhost:8000/v1 |
High-throughput serving, typically on a separate workstation. |
Default models
Voyager ships defaults that work on modest hardware rather than the largest models available:
- Vision:
granite3.2-vision:2b— a 2-billion-parameter vision model, small enough to run on CPU if it has to. - Text embeddings:
nomic-embed-text, used to make descriptions searchable by meaning. - Visual embeddings:
clip-ViT-B-32, fetched once and run through ONNX Runtime — no server involved and nothing to configure.
Any multimodal model your engine can serve will work in place of the default. If you want to compare candidates before committing, we benchmarked several on exactly this task.
LAYER 1 Vision Metadata Extraction
The richest layer. A vision model looks at each photo and returns a structured JSON record, which becomes every filter, tag and word cloud in the application.
How a photo is processed
- The image is decoded and downscaled to your configured analysis size, then encoded and sent to the model.
- For a video file, the first frame is extracted and analyzed as a still.
- The model is instructed to reply with a JSON object against a fixed schema.
- The reply is parsed and written into the
ai_analysistable.
When the model misbehaves
- Malformed JSON — trailing commas, unescaped quotes, commentary wrapped around the object — is repaired automatically before parsing is retried.
- Request timeouts scale to your hardware: 120 seconds when a GPU is present, 480 seconds when the work falls to the CPU.
- A photo that still fails is left unanalyzed and picked up on the next run rather than blocking the queue.
The extraction schema
Every analyzed photo produces the same set of fields. This is the contract the prompt asks the model to honour, and you can edit it in Configuration → Prompt Editor if you want different fields or different vocabulary.
| Field | Type | What it holds |
|---|---|---|
description_short |
Sentence | A one-sentence executive summary of the photo. |
description_long |
Paragraph | A narrative description covering the scene, lighting and composition. This is the text that semantic search actually searches. |
tags |
List | Free-form descriptive tags. These drive the word cloud. |
objects |
List | Main objects visible in the frame. |
people |
List | Types of people present. Distinct from face recognition, which identifies specific individuals. |
places |
List | Where the photo appears to have been taken, inferred from the image itself. |
actions |
List | Activities occurring — running, celebrating, sitting. |
mood |
Controlled term | The visual atmosphere, constrained to one of 27 permitted values. |
quality |
Controlled term | A one-word impression of the rendering, from a fixed list of 26. |
category |
Controlled term | High-level genre, from a fixed list of 26. |
is_explicit |
Boolean | Flags content for exclusion from shared galleries and slideshows. |
Why the vocabularies are fixed
Mood, quality and category are constrained to closed lists rather than left open. A free-form model will happily produce "joyful", "joyous", "full of joy" and "happy" for four near-identical photos, which makes a filter sidebar useless. Constraining the vocabulary is what turns a description into a dimension you can actually slice a library by.
The quality field above is a single descriptive word the vision model offers in
passing — "sharp", "grainy", "cinematic". It is not a measurement. The separate Technical
Quality Analysis tool is what produces real scores for sharpness, focus, noise,
contrast and composition, each with a written justification. Use that one when you intend to
cull a library by quality.
Results appear in the side detail panel and the full-screen Detail View. The left sidebar turns the same fields into filter pills for category, mood, objects, places and actions.
LAYER 2 Visual Similarity & Clustering
This layer never reads a word. It compares photographs as images, which catches resemblances no description would ever capture — the same light, the same palette, the same shape of composition.
The model
clip-ViT-B-32 runs locally through ONNX Runtime on your CPU or GPU. The weights are
downloaded automatically the first time the worker runs, then cached — there is no server
to set up and nothing to configure.
The vector
Each photo becomes a 512-dimension vector — a mathematical signature of what it looks like. Two photos with similar vectors look similar, whether or not they share a single tag.
The projection
512 dimensions cannot be drawn. Principal Component Analysis reduces each vector to
x, y and z coordinates, preserving as much of the
original spread as three axes can hold.
What it gives you
- Find Similar — select a photo and the toolbar button pulls up everything that resembles it. With several photos selected it targets the first in chronological order. The same action sits on the right-click menu as Search Similar.
- Cluster views — your whole library plotted as a star map, in 2D or 3D, where proximity means visual likeness. Rotating through it surfaces themes you never tagged and never would have thought to search for.
- Visual Cluster Journey — a slideshow that walks a coherent visual neighbourhood rather than a date range.
View menu → 2D Cluster View or 3D Cluster View. Similarity results also appear as an active filter pill you can clear like any other filter.
LAYER 3 Semantic Natural-Language Search
Keyword search finds the words you typed. Semantic search finds the meaning behind them, which is what you want when you remember a photograph but not a single word anyone ever attached to it.
How a query is answered
- Your sentence is sent to the text embedding model and comes back as a vector.
- That vector is compared by cosine similarity against the stored vector of every photo's AI-written description.
- Results are ranked by score and handed to the gallery, which applies any filters you already have active on top of them.
That last point is the useful part: a concept search and a hard filter compose. You can ask for something impressionistic and still constrain it to starred photos from 2019 taken on one particular camera.
Queries that work well
- "A peaceful afternoon by the lake"
- "Someone celebrating a birthday with a cake"
- "The feeling of a cold winter morning"
- "Dramatic light on a mountain ridge"
Semantic search reads the descriptions, not the pixels. Its ceiling is therefore set by how well the vision model described your photos in Layer 1. If a search for "a dog on a beach" comes back thin, the fix is usually a better vision model or a larger analysis image size — not a different query. Photos that were never analyzed are invisible to it entirely.
Switch the dropdown beside the search box from Keyword to Semantic, type a phrase and press Enter. Run Semantic Search Prep from the Tools panel first, so the description vectors exist.
LAYER 4 Photo Journeys
Journeys are where the three layers below combine. Each mode draws on a different one to assemble a themed slideshow with no manual curation.
Person Through Time
Follows one person across the years, using face recognition to gather them and capture dates to order them. The most affecting of the four, and the one that justifies running a face scan.
Activity Journey
Groups photos by the actions the vision model detected — every photo of people cooking, swimming or celebrating, drawn from across decades.
Semantic Search Journey
Builds the slideshow from a natural-language prompt, so the theme is whatever you can describe rather than whatever happens to be tagged.
Visual Cluster Journey
Walks a neighbourhood of the CLIP embedding space, producing a sequence that hangs together by how the photos look rather than what they contain.
Slideshow menu → Photo Journey…, then pick a mode. Journeys can narrate each slide aloud using the AI descriptions and rendered subtitles.
Tuning for Your Hardware
Two settings govern almost all of the speed-versus-quality trade-off. Both live in Configuration → AI.
| Setting | Range | What moving it does |
|---|---|---|
| Analysis Image Size | 256 – 2048 px, or original | The main dial. Small images return fast but hide fine detail, which matters for small faces, text on signs and judgements about sharpness. Raise it when descriptions are vague; lower it when analysis is slow. |
| Context Window | Up to 16,384 tokens | How much the model can hold at once. Larger costs memory and time; it needs to stay within what your model and hardware actually support. |
Symptoms and fixes
Analysis is slow
Lower the analysis image size first — it has more effect than anything else. A 2B vision model on CPU is genuinely slow, which is why the timeout stretches to eight minutes per photo without a GPU. Run the queue overnight.
Descriptions are vague or wrong
Raise the image size, then try a stronger vision model. Both fixes propagate: better descriptions immediately mean better semantic search, because search reads what the vision model wrote.
Semantic search finds nothing
The description vectors have not been built yet. Run Semantic Search Prep from the Tools panel, and confirm an embedding model is installed on your engine.
Nothing is being analyzed
Check that your engine is running and reachable at the URL in Configuration, and that the
selected model is genuinely multimodal. A text-only model will fail on every photo. The
ollama.log file records each request and its outcome.
What Leaves Your Machine
Nothing.
Every layer on this page runs against a model on your own hardware, or on a machine you chose and control. Your photographs are never uploaded for analysis, the catalog stays on your disk, and there is no account, no telemetry and no usage reporting. The only network traffic AI features generate is the one-time download of model weights — which transmits no photo content — and requests to the model server at the address you configured, which is your own machine by default.
This is also why the trade-offs on this page are real ones. A cloud service would hand you a large model and a fast answer in exchange for your library. Running locally means the quality of your results is bounded by your own hardware — and that is the deal on offer, stated plainly.
Zero manual tagging
The vision model does the cataloguing work that nobody ever gets around to doing by hand.
Discovery, not just retrieval
Visual clustering and semantic search surface photos you had forgotten you owned.
Your models, your rules
Swap the model, rewrite the extraction prompt, or turn any layer off entirely.
Photo Voyager Documentation Set Up a Local Model Getting Started Guide