What is Ollama's d3? Decision models that score, not chat
Ollama v0.40.9 ships d3: four decision models from vLLM Semantic Router that return scored choices instead of chat. Sizes, memory, index scores, fine print.
d3 is Ollama's decision-model family: four models (2b, 4b, 9b, 27b) that read your input, score the options you name, and return probabilities. It replaces the chat-model-as-router pattern: you get a verdict, not a paragraph. Requires Ollama 0.40.9+.
For you if you route things: support tickets, documents, images-that-must-match-a-rule — anywhere a full chat model answers a question that only needed a score.
The classifier tax
Routing a support ticket with a chat model means spinning up billions of parameters to emit "This looks like a billing issue, though you may also want to check..." — prose that exists only to be parsed and thrown away. Every routed ticket pays it: tokens for hedging, latency for grammar, a JSON parser on the far end praying the paragraph still matches the schema. Name the pattern and the bill gets easier to see: the classifier tax — the gap between what a routing answer costs and what it is worth.
d3 is the receipt that the tax was optional. It does not write sentences. Give it an input and a set of named options, and it grades them — numbers out, nothing else. The library record puts it flatly: it "does not write a conversational answer."
What d3 actually is
Four words carry the whole idea:
- Decision model — a model built to pick, not to talk. Trained to score options against criteria; conversation was never the job.
- State — the thing being graded. Plain text, structured data, or a still image. One request can ask several questions of the same state.
- Choices — the options you supply, each with its own criteria ("billing = invoices and charges"). The model only picks from your menu.
- Score — a probability per option. The record's own warning: scores are "model outputs, not guaranteed real-world frequencies" — test thresholds on your own cases before one triggers an action.
Provenance, because it matters here: the family comes from the vLLM Semantic Router project — the routing layer of the vLLM ecosystem — published as d3-nano, d3-mini, d3-flash and d3 (27B), all Apache-2.0. Ollama wrapped them yesterday as 16 packages; the library page counted 755 pulls 11 hours after landing. We read the same record twice this week — pplx-decider, Perplexity's 27B decision model, arrived in v0.40.7. Decision models are becoming a shelf, not a paper.
Which size d3 do you need?
The record's own table, with the publisher's checkpoint scores beside the memory figures. Sort it; the interesting column is the gap between rows.
| Model | Loaded memory | Best fit (record's words) | Text index (checkpoint) |
|---|---|---|---|
d3:2b | 3.62 GB | Fast, local routing and classification | 38.9 |
d3 (4B) | 5.63 GB | General use — the default | 52.6 |
d3:9b | 10.09 GB | Harder decisions | 55.8 |
d3:27b | 28.61 GB | Highest accuracy in the family evaluation | 66.3 |
Read the index column the honest way. Going 2b to 4b buys 13.7 points for 2 GB of memory. Going 4b to 9b buys 3.2 points for double the memory again. The curve flattens exactly where the money starts — and the 27b top score asks for a 64 GB Apple Silicon machine to decide whether a ticket goes to billing.
Two fine-print lines from the record, pasted as they stand: the index scores are for the original checkpoints and are "not scores for the Ollama quantized packages" (MXFP8 on Apple Silicon, Q8_0 elsewhere). And the packages ship a 4,096-token context — on models whose card advertises a 256K window. For grading a ticket, 4,096 is plenty. For grading a book, it is not.
How do you run d3?
The library's own starter, verbatim:
ollama run d3 "A customer says their card was charged twice." \
--ask "Which team should handle this?" \
--choice 'billing=Invoices and charges' \
--choice 'returns=Refunds and replacements' \
--choice 'technical=App errors'
verify: read from the ollama.com/library/d3 record + the v0.40.9 release notes, 2026-10-23 · first-person bench: attempted, died at the disk (ledger below)
The structured door: same question over HTTP
Scripts skip the CLI entirely — the record's own shape, one request, several questions:
curl http://localhost:11434/v1/systemone \
-H "Content-Type: application/json" \
-d '{"model":"d3","state":"Hello World",
"questions":{"says_hello":{"type":"noul",
"instructions":"Does the state text contain a greeting?",
"criteria":{"true":"It contains a greeting.",
"false":"It does not."}}}}'
The honest ledger
- What we did not do: score it, and not for lack of trying. Every quality number above is the publisher's, measured on the unquantized checkpoints. Our own CPU run this morning died at the door — the bench microVM ships 646 MB of disk and the package alone unpacks to 2.4 GB.
- What the same release also shipped: speech — Phonon reads model output aloud through
/v1/audio/speech. Apple Silicon only, so it stays untouched here. - What d3 cannot do: video, object tracking, and anything outside the options you named. It is a grader; graders do not improvise.
The open wound, and the next receipt: the publisher's index says who wins on their benchmark. Nobody has published what matters here — verdicts per second, per gigabyte, on a plain CPU box, where routing actually lives. That measurement is the next receipt; the box knows what it owes.