← all posts
// vision · vision-models

Vision models for chart and diagram understanding: local, hosted, and hybrid vision deployment

This one has already happened on more than one team: somebody feeds a dashboard screenshot to a vision model, asks about the dip in week three, and gets four confident sentences built on an axis read backward. The model saw a resized, cropped, tiled version squeezed into a token budget, and the fluent answer can be grounded in it, a corrupted crop, or nothing at all.

Read the data before you read the picture

The material worth worrying about is dashboards, plots, architecture diagrams, schematics, and slide visuals: recovering a relationship between shapes and labels, not describing a scene. Feed the system the original image or vector export, the caption, legend, units, and the exact question, narrower than "understand this image" and more measurable.

Check first whether you even need a vision model. Most charts started as data or a source graph; read that directly and skip the pixels. A vision-language model earns its place once the baseline hits layout, ambiguity, or a relationship fixed parsing rules can't resolve economically. Route by sensitivity, image size, task difficulty, hardware location, deadline.

Log what the model actually saw (visionmodels)

Once a task needs a model, build the evaluation before touching the prompt: run the same test locally and against a hosted API, count upload and review time as cost, set escalation conditions up front, and keep the original asset untouched with every transformation recorded. A model name alone tells you nothing; you also want:

  • model ID, API/runtime, prompt revision
  • image: dimensions, crop, resize, orientation, count, ordering, frame timestamps
  • OCR or metadata supplied alongside the pixels
  • token accounting: visual, input, output
  • first-response and total latency, peak memory
  • outcome: grounded pass, unsupported claim, abstain, repair

Log the actual image-detail or resolution value used, not the default assumed. For local models, say through Ollama's vision models, record the projector, quantization, context window, and preprocessing implementation: text weights from one release and a projector from another can fail in ways that look like a normal, if slightly dumb, answer.

The acceptance gate is label transcription, relationship accuracy, numerical consistency, cited evidence, and abstention on unreadable detail. Score an unsupported claim worse than a missing one: an omission gets flagged for review; an invented serial number, control, trend, or attribute can trigger a wrong action unnoticed. Include unanswerable examples on purpose and score "can't tell" as a win.

Make it show its work

The failure worth naming: a model describing a convincing trend while it reversed an axis, a series, a unit, or an arrow direction. A second failure cuts both ways: quietly uploading a sensitive image once the local model stumbles, or routing every thumbnail to an expensive frontier endpoint unchecked. Neither shows up in a demo, and both pass casual review because the output sounds like something a person would say.

Point every conclusion at something visible: a region, a page, a frame, a label, shown to the reviewer instead of buried in a log nobody opens. Force the reasoning through four layers, since collapsing them is how a guess becomes an action. "Red indicator top right" is observation. "It belongs to the network panel" is association. "The connection has failed" is inference. "Restart the gateway" is an action, needing a far higher evidentiary bar than the first three combined. Don't let observation jump straight to action.

Multiple images multiply the identity risk. Label each one, state whether they show the same object, a page sequence, one camera, or a stretch of time, and strip duplicates that burn tokens without evidence. If order matters, attach timestamps and shuffle the frames as a test: a model with the same story after a scramble was never using the sequence.

Draw the line in code, not in the prompt

None of this holds if the rule only lives in a prompt. Keep privacy hard, keep remote escalation visible, and track accepted tasks per dollar and per second. Put it in preprocessing, routing, validation, or an authorization check, not prompt text a future edit can soften. Store the model and pipeline version with results so an upgrade replays against the same images.

Privacy runs on both sides of inference: crop irrelevant rooms, faces, screens, addresses, and reflections before the image travels anywhere, and set retention separately for originals, thumbnails, OCR text, embeddings, prompts, and debug captures. Local execution cuts external transfer, but does nothing for an unencrypted disk or an overbroad dashboard account. People forget that.

For a hosted path, say through the Gemini CLI's multimodal mode, count upload time, regional routing, retention, rate limits, and provider errors as part of the real number. Locally, count cold load, projector memory, CPU/GPU placement, preprocessing time, heat, and concurrency, then compare both at p50 and p95. I'd stop trusting a benchmark reporting only tokens per second; it hides most of what makes a system usable.

Stop optimizing once the gate passes at acceptable latency, cost, and abstention. A bigger model and more pixels aren't automatically safer: they can expose more private detail per request and nudge the system toward answering beyond the evidence.

Given the choice, I default to local for anything sensitive or repetitive, and I accept that tradeoff on purpose: a lower capability ceiling, no burst capacity when a backlog spikes, and an occasional flat refusal a bigger hosted model would have pushed through. That's the price of knowing what happened to an image before the answer came back, and I'd pay it again.

#vision-models#multimodal#evaluation