Early alpha - macOS only (Apple Silicon) - free download

All articles
BenchmarksAI analysis12 min read

Benchmarks

How Nine AI Configs Scored on Real Footage

By AI Video Cataloger

Benchmarks

AI Video Cataloger lets you point the same folder at very different analysis backends: a fully local Gemma model, an OpenAI-compatible API, an agent CLI you already have installed (Claude Code, Codex, Cursor), or Gemini's native video input. That flexibility is only useful if somebody has actually measured what the choice costs you — in quality, in wall-clock time, and in money.

So we measured it. This post is the write-up of that benchmark, including the two experiments that failed and the one result that invalidated a conclusion we had already written down.

The footage

Every number below comes from the same fixed set of eleven real clips, about 1.1 GB in total. They are handheld DJI Pocket clips — a pocket gimbal camera, not a drone — taken from a real travel library during a museum visit. Clip length runs from three to thirty-one seconds. The material is genuinely hard for a cataloger in three specific ways:

  • Mixed indoor lighting and motion. Handheld pans across exhibits, with reflections, glass cases and backlit windows.
  • On-screen text in a language the owner does not speak. Placards, door signs and wall panels in a Scandinavian language — exactly the kind of string a person later types into a search box.
  • Polish narration. The owner talks over roughly half the clips. On this material the spoken track carries more retrievable information than the picture does, and that turns out to be the whole story.

A benchmark built from clean, well-lit, English-language stock footage would have ranked these backends in a different order, and would have missed the failure mode that ended up dominating the results.

Method

The benchmark holds everything constant except the analyzer:

ParameterValue
Frames per clip3 (the app default)
Transcriptionmanaged whisper, large-v3-turbo, identical for every leg
Harness efforthigh on every agent-harness leg
Per-clip timeout900 s
Input filesone APFS clone of the master set per leg, so no leg sees another leg's renames

Runs are resumable: a clip whose NDJSON already contains a completed event is skipped, so a leg that dies halfway does not restart from zero.

Judging is blind and dual-judge. Each clip's per-backend outputs (description, filename, tags) are stripped of any backend identity and shuffled into a judge pack, with the per-clip label mapping held separately. Two independent judge models — from different vendors — score every anonymized output, under two deliberately different lenses:

  • a retrieval lens: would the owner find this clip again by typing what they remember?
  • a faithfulness lens: is every claim in the description actually supported by the frames and the transcript?

Those two lenses disagree on purpose. A config that invents a plausible proper noun scores well on retrieval (the filename is specific and searchable) and badly on faithfulness (the specific thing is not true). Averaging them without looking at the split hides the most important property of a cataloging model.

Every clip also has a reference row (r0): a human-written filename and description produced with the clip in view. It is not a competitor, it is a ceiling anchor — so we can tell "the best machine config" from "a good result".

The headline table below has nine rows: eight machine configurations plus that human reference.

Round 1: the ranking table

ConfigBackendJudge meanPer-clip winsMedian s/clip
r0human-written reference9.1810
c8Gemini native video, flash7.39n/a36.1
c4agent harness — Claude Code7.181165.0
c6agent harness — Cursor Agent5.640172.7
c5agent harness — Codex5.180230.5
c2local Gemma 3, 12b5.00011.5
c7OpenAI-compatible API, gpt-5.54.82012.9
c3local Gemma 3, 27b4.00070.9
c1local Gemma 3, 4b3.18011.1

Four things in that table matter more than the ordering.

The human reference wins ten clips out of eleven. No machine config is close to a person who watched the clip. Any claim that automatic cataloging is "solved" is a claim about easier footage than this.

Bigger local is not better local. Gemma 27b scored below Gemma 12b (4.00 vs 5.00) while taking six times longer per clip. Its outputs were longer and more confident, and the extra confidence went into unsupported detail, which the faithfulness lens punishes hard. On this task, parameter count bought verbosity, not accuracy.

The API leg is fast and useless. c7 ran in 12.9 s per clip and produced maritime-museum-boat-exhibit and open-welcome-sign — filenames that are never wrong and never findable. That is the generic-filler failure mode: the model declines to commit to anything specific, so every clip in the folder ends up with roughly the same name.

c8's mean is not derived the same way as c1–c7. The round-1 configs were scored clip by clip; Gemini native was added later, and its 7.39 is the average of two whole-config judge verdicts (7.95 retrieval, 6.82 faithfulness). Same clips, same rubric, different derivation — so the 0.21-point gap between c8 and c4 sits inside the noise that difference creates.

Round 2: pinned models

Round 1 compared products — an "agent harness" is whatever model that CLI happens to default to. Round 2 pinned the model explicitly on every leg and re-judged blind, again with two judges from different vendors.

ConfigRetrieval judgeFaithfulness judgeAverageWins
harness, frontier model A8.828.688.758
r0 (human reference)8.007.737.861.5
harness, frontier model B7.277.647.451
harness, fast reasoning model7.007.457.230
API + API whisper6.917.327.110
OpenAI-compatible API6.917.237.070
harness, high-effort reasoning6.827.277.050
harness, mid-tier model6.647.236.930.5
harness, gpt-5.56.456.776.610
local Gemma 3, 12b4.094.734.410
local Gemma 3, 4b3.274.053.660

The top row beat the human reference. That is not a claim that the machine is better than a person — it is a warning about cross-round comparison. The reference row moved from 9.18 to 7.86 without its text changing a single character. What changed was the field around it: a stronger set of candidates shifts where a judge puts the middle of its scale. Judge scores are ordinal within a round and meaningless across rounds. We report both rounds separately for exactly that reason.

The stable, cross-round finding is the bottom of the table: local Gemma legs score 3.7–4.4 on this footage regardless of round, model size or judge. When the information in a clip is small on-screen text in a foreign language, the local models we can actually run on a laptop are not yet in the same category.

Four outputs, verbatim

Aggregates hide what these differences feel like. Four real examples, with identifying details of the library removed.

1. The same three-second clip, seven different hallucinated sentences. One clip is a near-static shot of a hand-painted wooden sign reading OPEN, 11-17, velkommen. There is no speech on it; a dog barks somewhere off-camera. Seven configs sharing the same whisper transcript reported the audio as, in turn: "What you like?", "I do not let go", "ok" repeated, "I'm ready" twice, "I", "I'm going to go to the next slide", and — from the smallest local model — a suggestion that this "might be part of a presentation or video demonstration". Every one of those is whisper hallucinating on near-silence, and six of the seven analyzers treated the hallucination as a fact about the clip.

2. The honest abstention. On the same clip, one config wrote:

The audio transcript ("I do not let go") does not correspond to any visible content and appears to be an unrelated or mistranscribed audio clip.

That is the single most valuable behaviour we saw in the whole benchmark, and no aggregate score rewards it enough.

3. The invented placard. On a clip where the human reference notes only that an information leaflet is held blurred in the foreground, the flash config produced a filename led by a proper noun — Firroringen — that the ground truth does not support. In a later round the pro model kept the name and added a long verbatim English "guidebook transcript" that conveniently corroborated it. The faithfulness judge's verdict was blunt: the fabrication is load-bearing, because it leads the filename. A wrong entity does not merely under-serve search, it poisons it — you will search for the real name forever and never find the clip.

4. The mistranslated narration. The most consequential error class had nothing to do with the analyzer. Polish narration was decoded as English, so "alianckie łodzie podwodne" (Allied submarines) came back as a proper noun, Allianz-Kerrall, which the analyzer then wrote into the description as an entity that had damaged the ships. On other clips the same pipeline produced "the station was a website" repeated five times, and tags reading *Pain* and Thank you on a clip the model itself described as having no narration.

The entity gate, and why we reverted it

Example 3 has an obvious fix: forbid the model from naming an entity unless the name is legibly visible in a frame. We tried that three times.

RoundChangeJudge resultPlaceholder filenamesMedian s/clip
c8baseline, no gate7.95 / 6.82 (retrieval / faithfulness)0 of 1136.1
c11entity gate v16.27 / 5.644 of 1138.7
c12re-cut gate: one evidence rule across description, filename and tagsnot promoted2 of 1143.7
c13prompt v3: concrete-attribute floor for filenames and tagsnot promoted4 of 1135.6

The gate worked, in the sense that the fabrications went away. It also produced this, on a clip full of usable content:

filename: video-3 · tags: (none) · description: "Inside a maritime museum, the camera pans past traditional wooden fishing boats, including a Lofotbåten exhibit with detailed rigging, wooden hulls, and hanging nets..."

The description still names the exhibit. The filename is video-3 and there are no tags at all. The gate did not make the model more careful — it made the model abandon the fields the gate was checking while leaving the same unverified claim in the field it was not checking. Blind judges scored c11 at 6.27 and 5.64, well below the ungated baseline on both lenses: the retrieval lens because four clips in eleven became unfindable, the faithfulness lens because a placeholder filename sitting over a confident description is not honesty, it is inconsistency.

c12 halved the placeholder rate by applying one evidence rule to all three fields. c13 added a floor — if no entity is verifiable, name the concrete attributes you can see — and the placeholder rate went straight back to four in eleven. At that point we reverted the gate entirely.

The honest lesson: prompt-only entity gating trades fabrications for lost specificity, roughly one for one, and the trade is bad. A rule that says "do not say what you cannot verify" is enforced by the same model that cannot tell what it can verify. Suppression is not verification. Fabrication control belongs in a separate pass that can genuinely re-check a claim against the frames, not in a longer prompt.

The pilot, and the variable we had been holding constant

The eleven-clip benchmark said Gemini native video was the leading machine config. Before committing a full library to it we ran a 102-clip pilot on a single folder: both legs to completion, zero errors, judges sampling every fifth clip (21 of 102).

LegAnalyzerTranscriptionRetrievalFaithfulnessCost/clipMedian s/clip
Aagent harness, fast model, low effortwhisper, English-decoded5.46.8$0~66
BGemini native video, flash, Batch APIprovider-native6.43–7.387.29–8.6$0.00855~10 (see note)
Cagent harness, high-effort modelwhisper, English-decoded6.67.4$028.6 (analysis only)
Eagent harness, high-effort modelwhisper, language=auto7.98.33$031.27

Two medians need an asterisk. Leg B's ~10 s is dominated by upload and batch polling, and only 24 of the 102 clips were computed in that round, so it is not a single-pass end-to-end figure. Leg C reused cached transcripts, so its 28.6 s covers the analysis layer only. Leg E is the only harness number that includes transcription computed from scratch.

Legs A, B and C said the same thing the eleven-clip benchmark had said, more loudly, and we wrote the recommendation: Gemini, roughly $36 for the whole library, a cost irrelevant next to a poisoned index.

Then we went looking for why the harness legs kept inventing names, and found that the transcription adapter never passed a language flag to any whisper backend. Not to the local whisper.cpp binary, not to the API call. With no language specified, each backend fell back to an English-leaning default, so Polish narration was being translated, badly, before the analyzer ever saw it. Allianz-Kerrall was not the analyzer hallucinating. It was the analyzer faithfully reporting a corrupted input.

Leg E is the same analyzer as leg C, with one config key changed (whisper_language=auto) and transcription recomputed from scratch instead of reused from cache. It moved from 6.6 / 7.4 to 7.9 / 8.33, beating Gemini on both lenses for the first time in the entire study — at $0 instead of $36. All three headline fabrications from the earlier legs disappeared, including an invented door legend that a previous leg had promoted into a filename and tags, for a door that actually reads CREW ONLY.

One caveat, because we tripped over it ourselves: an earlier attempt at leg E was invalid. The run found an existing variant for the same configuration id and skipped all 102 files, so the "fixed" leg was judged on cached English-decoded records. The judge caught it and said so — the comparison could not answer the question it was asked. Only the run with genuinely fresh transcription counts, and that is the one in the table.

We had been benchmarking analyzers while the decisive variable was transcription. Four legs, two judges and a written recommendation, all comparing the wrong axis. The bug is fixed — whisper_language is now a real config key defaulting to auto, and a --whisper-language flag on the CLI — but the methodological lesson is worth more than the fix: if two legs share an upstream stage, you are not comparing the legs, you are comparing the stage.

Costs

ConfigMeasured $/clip11-clip benchmark runProjected: 4,189-file library
Gemini native, flash$0.008941$0.098~$37
Gemini native, pro-preview$0.018284$0.201~$77
Gemini flash, Batch API (pilot, measured over 102 clips)$0.008552$35.82
Agent harness (existing CLI subscription)$0$0$0
Local Gemma$0$0$0

Flash versus pro is the cleanest cost/quality data point we have: 7.39 against 7.59 on the judge mean, 36.1 s against 44.3 s per clip, and roughly twice the price. The pro leg fixed three of the flash leg's seven recorded fabrications and introduced two new ones — including that fabricated guidebook transcript, which is a worse failure than the original, because it manufactures its own corroboration. Paying double for errors that are harder to spot is not an upgrade.

Also worth recording, because it costs a day if you hit it blind: our attempt to benchmark the previous-generation pro model failed outright. Every request returned 404 NOT_FOUND with "no longer available to new users", on a credential that lists the model and answers fine for the current preview. Model availability is not a property of the API, it is a property of your project's creation date.

Time is the other currency, and the zero-dollar path is not free. The measured harness leg runs at 31.27 s per clip including fresh transcription, which projects to roughly 36 hours of machine time for a 4,189-file library — about a day and a half of background running, against a few hours for a batched cloud run. That is a real trade, and for plenty of people $37 is obviously the right answer.

What we recommend

For this footage — a personal library with non-English narration — the recommendation is an agent-harness analyzer with transcription language set to auto, at $0. It wins both judge lenses, it is the only variant that preserves the owner's own spoken phrases as searchable text instead of flattening them into English summaries, and it never returned an empty tag set. The Gemini leg, by contrast, produced a video placeholder filename with zero tags on about 19% of sampled clips — reliably on the richest material.

That recommendation is narrower than it looks. It holds because the information in this library lives in the audio. For silent footage the picture reverses: the same judges repeatedly noted that Gemini's native video reading caught on-screen text the frame-sampling legs missed, and a frames-only pipeline sampling three stills from a thirty-second pan loses whatever was legible in the other 27 seconds.

Which is why the app ships no single blessed configuration. Every analysis is stored as a variant keyed by its full configuration, so you can run two backends over the same folder and compare them side by side on your own material — the same thing we did here, minus the judges.

Limitations

Stated plainly, because a benchmark that hides these is marketing:

  • n = 11 for the main rounds, 21 of 102 sampled for the pilot. Small samples: a 0.2-point difference in a judge mean means nothing.
  • One shooting session, one subject, one narrator, one camera. Everything above is a statement about this library, not about video in general.
  • The judges are LLMs. Two vendors and two opposed lenses reduce single-model bias; they do not eliminate it.
  • Single runs. Nothing was repeated, so we have no variance estimate and cannot separate a real 0.5-point gap from run-to-run noise.
  • Rounds are not comparable. The reference row moved 1.3 points between rounds with identical text. Compare within a table, never across.
  • A snapshot in time. Model versions, prices and availability all moved during the study; two of the configs above cannot be reproduced today as run.

The benchmark package — protocol, fixed clip set, runner scripts, raw NDJSON, judge packs and aggregates — is self-contained and re-runnable, which is the only real defence against every one of those limitations.