Vision Model Comparison¶
This page compares models. For configuration examples you can copy into vision.yml, see Ollama Models in the User Guide. Learn more ›
What Was Measured¶
All figures on this page come from a single benchmark run on August 8, 2026, using Ollama 0.32.6 at a 4096-token context, over a fixed set of 16 images at 720 px — the resolution PhotoPrism sends. The images span wildlife, pets, macro, food, people, sport, vehicles, architecture, cityscape, OCR, and a UI screenshot, and several are deliberately adversarial.
- Self-hosted models ran on an NVIDIA RTX 4060 (8 GB VRAM, ~7 GB free). Every model saw the same daemon, so the self-hosted numbers are valid relative to each other.
- Cloud models were proxied through the same instance, so their latencies include one extra network hop.
Captions and labels are measured separately throughout. They are different workloads with different failure modes, and a model that is good at one is not necessarily good at the other.
Read Latency as Approximate, Especially for Cloud Models
Repeating the cloud table a few hours apart on the same day moved one model's label latency from 1.6 s to 10.8 s while its output barely changed. Self-hosted timings reproduced to within a tenth of a second across the same pair of runs. Rank hosted models on output quality; measure latency yourself when it matters.
The self-hosted run also predates capture of the daemon's KV cache and flash-attention settings, so these numbers are not directly comparable against a differently tuned instance. Qwen models are the most sensitive to KV cache quantization — re-measure those locally before acting on them.
Label Generation¶
Subject coverage is the share of images where the label set named both the main subject and its setting. Multi-word is the share of label names containing a space or separator. It is a contract violation under single-word normalization, where the phrase is collapsed to one token; under phrase it simply counts how many compound names were returned. Read the multilingual rates with that in mind: a name written in a non-Latin script is kept whole in every mode, so a compound Arabic or Hebrew label is never a violation. Learn more ›
Self-Hosted, Built-In Prompt¶
| Model | Size | Labels p50 | Labels/img | Multi-word | Coverage |
|---|---|---|---|---|---|
qwen3.5:4b |
3.4 GB | 2.5 s | 3.6 | 1.7% | 88% |
gemma4:latest (e4b) |
9.6 GB | 2.6 s | 2.9 | 0.0% | 84% |
minicpm-v4.5:8b |
6.1 GB | 4.5 s | 3.4 | 5.6% | 84% |
gemma4:e2b |
7.2 GB | 2.2 s | 4.4 | 0.0% | 81% |
gemma3:4b |
3.3 GB | 3.0 s | 4.1 | 0.0% | 81% |
minicpm-v4.6:1b |
1.6 GB | 0.8 s | 3.3 | 18.9% | 78% |
qwen3-vl:4b-instruct |
3.3 GB | 2.4 s | 3.0 | 0.0% | 75% |
qwen3-vl:8b-instruct |
6.1 GB | 5.2 s | 3.1 | 2.0% | 75% |
qwen3-vl:4b (reasoning build) |
3.3 GB | 2.1 s | 2.9 | 21.3% | 69% |
qwen3.5:9b |
6.6 GB | 3.3 s | 1.9 | 6.7% | 69% |
qwen2.5vl:7b |
6.0 GB | 2.7 s | 1.4 | 0.0% | 56% |
qwen3.5:2b |
2.7 GB | 0.8 s | 1.2 | 5.0% | 47% |
Bigger is not reliably better: qwen3.5:4b beat both the 2b and 9b tiers of its own family. Within Gemma 4 the two variants split by metric rather than by size — gemma4:latest (e4b) leads on coverage, while the smaller gemma4:e2b returns more labels per image and is faster.
Coverage Cannot See a Confidently Wrong Name
Coverage rewards naming the subject and its setting. It has no way to tell that a plausible name is the wrong one, so a model can score well while consistently mislabeling a subject.
The Gemma 4 family does exactly this on animals. Both gemma4:e2b and gemma4:latest label the benchmark cheetah a leopard — in English, German, Arabic and Hebrew, on every run, in labels and captions alike. That is systematic, not an occasional slip. Both also captioned a penguin colony as seals ("Seals rest on the rocky shore"), where every other self-hosted model tested — including the 752 M minicpm-v4.6:1b — said penguins, and both read the ski jumper as a snowboarder.
Gemma's strengths still hold: fastest self-hosted captioner, and the only family that never emitted a multi-word label in either profile. But on identifying a subject it is behind Qwen3-VL at a comparable size, which is the trade-off to weigh if your library is heavy on wildlife or other uncommon subjects.
Self-Hosted, With a Label Count in the Prompt¶
The built-in prompt asks for "label objects" without stating how many, and that omission is deliberate — a short list of high-confidence labels is more useful and cheaper than a long one, and not every model honors a count instruction anyway. The run below measures what changes when one is requested, not a gap being closed. Adding an explicit range (the Qwen3-VL example shows the shape) multiplied the label set by 1.9–3.5× and raised coverage on every model tested, at 1.7–2.8× the latency:
| Model | Labels p50 | Labels/img | Multi-word | Coverage |
|---|---|---|---|---|
qwen3-vl:4b-instruct |
5.2 s | 10.3 | 4.2% | 97% |
qwen3-vl:8b-instruct |
11.3 s | 8.8 | 2.8% | 97% |
minicpm-v4.5:8b |
8.5 s | 7.1 | 8.8% | 94% |
gemma4:e2b |
3.9 s | 8.8 | 0.0% | 91% |
gemma3:4b |
8.3 s | 14.3 | 0.4% | 91% |
qwen3.5:4b |
5.0 s | 7.1 | 3.5% | 91% |
gemma4:latest (e4b) |
5.6 s | 8.6 | 0.0% | 88% |
It is the largest single lever on the numbers, and it reverses the ranking above: Qwen3-VL gains the most (+22 points) and leads once the count is stated, while qwen3.5:4b — the strongest model on the built-in prompt — gains the least (+3) because it was already close to its ceiling.
A higher count is not automatically better output. Coverage is a recall-style floor: it rewards naming the expected subject and cannot detect a confidently wrong extra label, so a model asked for fifteen labels scores better simply by guessing more. Nothing measured here captures precision or relevance. The cost is measured, though — roughly double the latency, and more names that break the single-word contract on every model not already at zero (qwen3-vl:4b-instruct 0.0% → 4.2%, qwen3.5:4b 1.7% → 3.5%, minicpm-v4.5:8b 5.6% → 8.8%), which single-word normalization then collapses. Treat it as a per-model knob for operators who want richer labels and have checked the result.
Ollama Cloud¶
| Model | Labels p50 | Labels/img | Multi-word | Coverage |
|---|---|---|---|---|
kimi-k2.7-code:cloud |
2.3 s | 8.6 | 0.0% | 100% |
kimi-k2.6:cloud |
2.9 s | 8.6 | 0.0% | 100% |
minimax-m3:cloud |
2.9 s | 13.4 | 0.0% | 100% |
qwen3.5:397b-cloud |
5.2 s | 8.4 | 1.5% | 100% |
gemma4:31b-cloud |
10.8 s | 7.0 | 0.9% | 97% |
Across 192 cloud requests there were no errors, no empty responses, and no malformed JSON. Cloud models also volunteer 7–13 labels per image without being asked for a count, where models fitting in 8 GB return 1–4. Check a model's plan coverage and per-token terms before running one over a whole library — some sit outside the usage plans entirely.
Caption Generation¶
| Model | Caption p50 | Length |
|---|---|---|
minicpm-v4.6:1b |
0.6 s | 15 w |
gemma4:e2b |
0.7 s | 9 w |
gemma4:latest (e4b) |
0.8 s | 12 w |
qwen3.5:4b |
0.9 s | 18 w |
qwen3-vl:4b-instruct |
1.2 s | 18 w |
gemma3:4b |
1.4 s | 10 w |
qwen3-vl:4b (reasoning build) |
6.4 s | 12 w |
minimax-m3:cloud |
2.9 s | 19 w |
gemma4:31b-cloud |
3.8 s | 12 w |
The outlier is the point: a reasoning build costs roughly five times the caption latency of its -instruct sibling for a shorter caption — about 414 output tokens against 24. Service.Think: "false" keeps that reasoning out of the stored caption but does not stop the model producing it. Learn more ›
Multilingual Behavior¶
Same images and prompts with the target language appended. In language is a judge model's verdict on the labels; accurate is its view of whether the content is right.
| Model (self-hosted) | de in language | ar in language | he in language | de accurate | he accurate |
|---|---|---|---|---|---|
qwen3.5:4b |
81% | 100% | 100% | 62% | 12% |
qwen3-vl:4b-instruct |
94% | 31% | 75% | 62% | 25% |
gemma4:e2b |
62% | 0% | 6% | 56% | 56% |
| Model (cloud) | de in language | ar in language | he in language |
|---|---|---|---|
minimax-m3:cloud |
100% | 100% | 100% |
gemma4:31b-cloud |
100% | 100% | 94% |
qwen3.5:397b-cloud |
81% | 81% | 75% |
kimi-k2.7-code:cloud |
94% | 44% | 38% |
Two things stand out. Answering in the right language is a separate question from answering correctly — qwen3.5:4b produced Hebrew labels on every request and got the subject right in 12% of them, which is worse than useless for search. And a model can honor the language for captions and ignore it for labels: gemma4:e2b returned correct Arabic and Hebrew captions while returning English labels on every request, with no error and nothing in the log.
No self-hosted model that fits in 8 GB cleared both bars. A non-English library is currently better served by a cloud model.
Prompt Token Cost¶
What a 720 px image costs in prompt tokens is a property of the model's vision encoder, not of the thumbnail:
| Model family | Prompt tokens (caption / labels) |
|---|---|
gemma4:e2b, gemma4:latest |
208 / 284 |
minicpm-v4.5:8b, minicpm-v4.6:1b |
248-256 / 318-332 |
gemma3:4b, medgemma*:4b |
318-319 / 390-396 |
qwen3.5:2b / 4b / 9b |
408 / 486 |
qwen2.5vl:7b, qwen3-vl:* |
1112-1123 / 1182 |
A 5.7× spread for identical input. It is why gemma4:e2b prefills in ~140 ms where gemma3:4b takes ~770 ms for the same picture, and it matters on a metered endpoint, where prompt tokens are billed per request and a whole-library run multiplies the difference by the number of photos. Switching model can cut prefill more than lowering Resolution does.
Models to Avoid & Compatibility Notes¶
medgemma:4b/medgemma1.5:4b— trained for grounded detection rather than classification.medgemma1.5:4breturned a well-formed but empty label array on every image, which is a model-fit problem rather than a schema error. Learn more ›qwen2.5vl:7b— the weakest general labeler measured (56% coverage, 1.4 labels per image) despite being a capable captioner. Its documented requirement for Ollama 0.7.0 no longer appears to hold: we ran 32 requests against it on Ollama 0.32.6 with zero errors. If you do hit problems, the FP16 variant (qwen2.5vl:3b-fp16) remains a workaround.minicpm-v4.6:1b— the fastest labeler here and better at subjects than its size suggests, but 18.9% of its label names were multi-word, so its output needs review before it reaches a library.
Don't Trust the Capability Flags
The capabilities list returned by GET /api/tags is not a reliable way to decide whether a pulled model is multimodal or reasoning-capable. Our test instance reported gemma4:e2b, gemma4:latest, and gemma3:4b as completion,tools,thinking with no vision flag, yet all three answer image prompts correctly. /api/tags and /api/show can also disagree about thinking for the same model.
Send a request with an image and read the response — that is the dependable test, and it is what a test run already does.
Keeping This Page Current¶
These figures come from an internal harness that keeps the image set, prompts, and scoring fixed, so the page can be refreshed by re-running it when models change rather than by repeating a study by hand.
A previous version of this page reported a caption-only study of Qwen2.5-VL and Gemma 3 run on an AMD Ryzen AI 9 365 CPU, with per-image times of 24–36 s. Those figures described CPU inference of models we no longer recommend and have been superseded by the run above; they are not comparable to the GPU timings on this page.
We welcome contributions to our computer vision documentation. If you have any additions or suggestions for improvements, please click the button in the upper right corner of the page to send a pull request.