Skip to main content

Decisio

Jev-level decisions on your own hardware, open source.

PyPI Licence: Apache-2.0 CI

Decisio is an open-source server that answers typed questions about any text, with a calibrated probability for every option, from one forward pass and no generated text.

Second among open-weights systems on JevBench, level with Jev, and the highest-ranked with frozen weights. (JevBench v1.6.1, decisio on Gemma 4 31B; how we read the board.)

How Decisio works: your text and your questions go in, a probability for every answer comes out How it works (illustration; the probabilities are examples, real recorded responses are below).

A dot plot of JevBench v1.6.1 composite scores with 95% intervals for the board's ten highest open-weights systems, with Jev 1.13.0 below as a reference row. H2O-Lightning-4B is first and Decisio on Gemma 4 31B is second, 71.69 against 72.52, with Quyet-1.0-Large third. The intervals of the first three overlap, and Jev's overlaps Decisio's.

Why Decisio

The usual way to get a decision out of a model is to let it write text and parse the result. Decisio skips the text. It reads your document once and reads the probability of each option straight off the model's output.

  • Higher than Jev on what the model knows. Intelligence axis: 70.4 against Jev 1.13.0's 63.6.
  • Second on the sealed set. Sealed-set intelligence: 73.3 against Jev 61.6, H2O-Lightning-4B 59.0 and Quyet-1.0-Large 71.6.
  • Several questions on one read. A second question on a 3,000-token state already read takes 43.3 ms (one RTX PRO 6000 at 585 W).
  • Long prompts, many options. Prompts up to 32,768 tokens and 255 options per question.
  • Your hardware, no per-token bill. It runs on your own GPU, Mac or laptop. The tradeoff: you buy and run the card, and on JevBench v1.6.1 Decisio is 9th of the 11 rows shown on the board's cost axis (51.7; H2O-Lightning-4B's 60.3 is highest).
Gemma 4 31B (the default)
JevBench 71.69; Jev 71.49, intervals overlap
Calibration ECE 0.035 standard, 0.091 hard
New 300-token state 80.7 ms
Second question 43.3 ms
Memory 30.6 GiB (FP8)
Licence Apache-2.0

One RTX PRO 6000 at 585 W; intervals and the rest of the figures are under Benchmarks.

Benchmarks

Each base with its own defaults on one RTX PRO 6000 Blackwell, measured by us with the public harnesses (the Decision Index kit 0.2.1) and recorded in runs/. None is a board score.

Measure Qwen3.6-35B-A3B Gemma 4 12B Gemma 4 31B (default)
JevBench published items, easy / standard / hard 1.000 / 0.972 / 0.739 1.000 / 0.972 / 0.739 1.000 / 1.000 / 0.838
BANKING77, macro-F1 0.746 0.729 0.785
CLINC150+OOS, macro-F1 0.822 0.871 0.902
GPQA Diamond, accuracy 0.510 0.378 0.520
MMLU-Pro, accuracy 0.613 0.549 0.694
Intent heads, BANKING77 / CLINC150 0.840 / 0.912 0.832 / 0.908 0.844 / 0.970
Image input, ImajevBench 0.791 n/m n/m
New 300-token state 49.9 ms 53.6 ms 80.7 ms
1,000-token state, cached 20.2 ms 24.8 ms 31.7 ms

The JevBench row is the 231 published items. Intent heads use labelled examples, so they are not comparable with zero-shot systems. n/m is not measured. Latency is server time on decisio 0.8.1's served defaults, at a 585 W power limit (default 600 W), so a card at 600 W may read new states faster (runs/2026-10-06_latency-585w/, docs/running.md).

docs/comparison.md sets all three bases beside Jev and the leading open entries on every benchmark (the board's figures and their date are in EVAL_CARD.md section 8.1). ECE, the expected calibration error, is the average gap between the stated probability and how often the answer was right, over 10 equal-width bins of the probability (JevBench's own measure; the card's other ECEs use 10 equal-mass bins and say so, EVAL_CARD.md section 3). Calibration on JevBench, as ECE on the standard and hard tiers: 0.121 and 0.043 on the Qwen base, 0.033 and 0.085 on the Gemma 4 12B base, 0.035 and 0.091 on the Gemma 4 31B base. EVAL_CARD.md has the full tables and what was fitted on what.

JevBench, axis by axis

Table of JevBench v1.6.1 scores, 11 rows sorted by composite score: the ten highest open-weights systems and Jev 1.13.0 as a reference row, six columns (overall, intelligence, sealed questions, calibration, speed, cost), each cell shaded by its rank in the column. Decisio 31B v0.8.0's values are overall 71.69, intelligence 70.4, sealed questions 73.3, calibration 88.7, speed 91.2, cost 51.7. Among the 11 rows shown it is second on overall, third on intelligence, second on sealed questions, fifth on calibration, fifth on speed and ninth on cost. The highest in each column: overall: H2O-Lightning-4B v1.1; intelligence: Quyet-1.0-Large; sealed questions: deck-31B; calibration: Jev 1.13.0; speed: H2O-Lightning-4B v1.1; cost: H2O-Lightning-4B v1.1. The Decisio rows are the board's v0.8.0 entries: Decisio 31B v0.8.0 (71.69) and Decisio 12B v0.8.0 (68.17). The board's decisio v0.9.0 12B entry (67.76) is not among the rows shown.
  • On JevBench v1.6.1, among the ten highest open-weights systems and Jev: 2nd overall, 2nd on sealed questions (73.3, never published) and 3rd on intelligence (70.4, ahead of Jev's 63.6).
  • On JevBench v1.6.1, within 2 points of the highest on calibration (88.7; Jev 90.6) and on speed (91.2; H2O-Lightning-4B 92.6).
  • On JevBench v1.6.1, 9th on the board's cost axis (51.7; H2O-Lightning-4B 60.3 is highest).
All the numbers: the ten highest open-weights systems and Jev, by axis

JevBench v1.6.1, 0 to 100, higher is better on every axis, sorted by overall score; only the composite has a published 95% interval. The Decisio rows are the board's v0.8.0 entries; the board's decisio v0.9.0 12B entry (67.76) is not among the rows shown.

System Overall Intelligence Sealed questions Calibration Speed Cost
H2O-Lightning-4B 72.52 60.0 59.0 90.0 92.6 60.3
Decisio 31B v0.8.0 (ours) 71.69 70.4 73.3 88.7 91.2 51.7
Jev 1.13.0 (reference) 71.49 63.6 61.6 90.6 91.5 54.7
Quyet-1.0-Large 71.39 73.4 71.6 90.0 86.9 50.5
decider-12b v2 70.88 63.0 63.6 82.0 90.5 57.8
decider-12b v1 70.42 60.6 59.5 83.8 90.5 57.8
torchcast-decision-12b 69.91 60.5 61.1 82.9 91.7 56.4
Winnow-12B Q8 68.89 59.5 59.2 83.0 86.7 56.6
deck-31B 68.68 73.0 75.8 82.2 86.7 49.7
Cygnet 68.55 54.8 51.3 87.0 91.8 56.4
Decisio 12B v0.8.0 (ours) 68.17 52.3 51.6 89.2 87.0 59.3

What the compared systems' cards state, quoted as recorded with their revisions, is in EVAL_CARD.md section 9.

Many questions about one document

Bar chart of the median time to answer 50 questions about one document, five systems measured in one session on one box. For a 3,000-token document: decisio Gemma 4 31B 1.08 seconds, decisio Gemma 4 12B 1.57, H2O-Lightning-4B 2.05, Jeff-1.0-Large 47.1, Quyet-1.0-Large 48.9. For a 6,000-token document: 1.73, 1.97, 2.82, 114.6 and 114.8 seconds. For a 32,000-token document only decisio Gemma 4 12B (6.76 s), H2O-Lightning-4B (9.05 s) and decisio Gemma 4 31B (10.1 s) answer; Jeff-1.0-Large and Quyet-1.0-Large are marked not supported.

Five systems, one box, one session: the median time to answer 50 questions about one document. On one box, Decisio 31B answers 50 questions about one 3,000-token document in 1.08 s and about one 6,000-token document in 1.73 s; Decisio 12B takes 1.57 s and 1.97 s, and H2O-Lightning-4B 2.05 s and 2.82 s. On one box, Jeff-1.0-Large and Quyet-1.0-Large, the two systems ranked above Decisio on JevBench's capability score, take about 44 times (3,000 tokens) and 66 times (6,000 tokens) as long as Decisio 31B to answer 50 questions about one document, and neither accepts a 32,000-token document. On one box, the first question about a new 3,000-token document takes a median of 112 ms on H2O-Lightning-4B, 295 ms on Decisio 12B, 490 ms on Decisio 31B, and 895 ms on Jeff-1.0-Large and 895 ms on Quyet-1.0-Large. At 32,000 tokens, Decisio 31B answers 50 questions about one document in 10.1 s, Decisio 12B in 6.76 s and H2O-Lightning-4B in 9.05 s; Jeff-1.0-Large accepts documents of up to 8,192 tokens and Quyet-1.0-Large up to 6,000, so neither accepts a 32,000-token document.

Measured by Tachara AI Lab on one NVIDIA RTX PRO 6000 Blackwell Workstation Edition at 600 W (enforced), each system on its own published server, in one session:

  • decisio v0.11.1 on vLLM 0.30.0 (the 31B and the 12B at their repositories' pins); H2O-Lightning-4B on its own serve.sh (stock vLLM 0.30.0); Jeff-1.0-Large and Quyet-1.0-Large on their own published code, bf16.
  • Synthetic support tickets of 3,000, 6,000 and 32,000 tokens by the Gemma 4 tokenizer, the same for every system, and one pool of 50 questions (20 choice with 4 options, 20 yes/no, 10 score with 4 levels). Medians over 10 documents for decisio and H2O-Lightning-4B at 3,000 and 6,000 tokens, and over 5 for Jeff, Quyet and the 32,000-token cells. This compares time, not accuracy.
  • Decisio reads the document once, and each question adds tens of milliseconds. H2O-Lightning-4B takes one question per request and shares the document through the prefix cache. Jeff and Quyet read the document again for every question; both are Gemma 4 31B based, and they are within 4 percent of each other at 3,000 tokens.
  • The SM clock ran at a median of 2,220 to 2,610 MHz and the power at 304 to 600 W across the five runs (docs/comparison.md links the log-axis chart that adds five systems from an earlier box).

How we read the board

A dot plot of the intelligence axis of JevBench v1.6.1 for eleven systems, sorted by sealed-set score, each with its open-set score beside it. deck-31B is first and Decisio on Gemma 4 31B is second on the sealed set, and Decisio scores higher on the sealed items than on the open ones.

Decisio scores higher on the sealed items than on the open ones.

The headline claim rests on the board's own ranks and on interval overlap, not on separation. In short:

  • Open weights. Second among the board's 128 open-weights systems. H2O-Lightning-4B ranks above us (72.52, interval 69.79 to 73.79) and its interval overlaps ours (69.86 to 72.81).
  • Level with Jev. Our interval and Jev 1.13.0's (69.14 to 72.40) overlap. The scores are 71.69 and 71.49.
  • Frozen weights. The board has no such class. We count a row as frozen by its display text, and decisio's row is the highest-ranked of those.
  • Not fitted, but read. Our temperatures were not fitted on JevBench, but we have read its published items (EVAL_CARD 7.4).

docs/board-reading.md has the source file, the ranks, the frozen-weights rule, the overlapping intervals and what the board's row ran on.

Quickstart

Ollama on a laptop, then pip on a GPU, then Docker.

On a laptop, with Ollama

The Gemma listing's smallest tag takes 8.6 GB in Ollama (measured on a 64 GB Mac), so it should fit a 16 GB laptop (docs/running.md):

ollama pull aminroudaki/decisio-gemma      # Gemma 4 12B, 8.6 GB in Ollama at its smallest tag
curl http://localhost:11434/v1/systemone -d '{
  "model": "aminroudaki/decisio-gemma",
  "state": "Hi, since this morning none of our 40 staff can log in to the dashboard. We get \"session expired\" right after entering the password. Payroll is due today.",
  "questions": {
    "urgent": {"type": "noul", "instructions": "Does this ticket need a response within the hour?"},
    "category": {"type": "choice", "instructions": "Which team should handle this ticket?",
                 "criteria": {"billing": "Invoices, payments, refunds", "access": "Login, passwords, permissions", "bug": "The product behaves wrongly", "other": null}}
  }
}'

Ollama builds its own prompt and applies no calibration, so its numbers are the ones on its model page, not the ones in this repository.

On a GPU, with pip

One NVIDIA card with 96 GB (the size everything below was measured on), Linux, Python 3.12:

python3.12 -m venv .venv && . .venv/bin/activate
pip install "decisio[serve]"
python -m decisio.serve.vllm_engine          # serves Gemma 4 31B; the first start downloads about 31 GB
curl -s http://127.0.0.1:8000/health         # answers once it is ready

The measured environment is the lockfile's (uv sync --extra serve --frozen, GPU server); pip resolves its own versions around vLLM 0.31.0. Measured by Lab 2 on 2026-10-09 on decisio 0.11.0 from PyPI, on one RTX PRO 6000 Blackwell at 600 W and an AMD EPYC 9534: pip install "decisio[serve]" took 124 s; the first start of the no-flag 31B was ready after 7 min 54 s, including the download of its weights, and a start with the weights already on disk after 4 min 3 s; the first start of --base gemma-4-12b after 4 min 12 s, including its download (these are one session's times, with the network that session had).

With Docker

docker run -d --gpus all --shm-size 8g -p 127.0.0.1:8000:8000 -v decisio-data:/data ghcr.io/aminry/decisio:0.11.1

The release notes give the image's digest; Docker has the compose file. The same curl as above, with /v1/systemone on port 8000 and no model field, asks the server you started.

Three decisions, as recorded

Each request is what was sent; each response is what the server answered on the Gemma 4 31B base (probabilities rounded to three decimals here). They are the three requests of this README's first recordings (the first record of Advocacy's examples 1, 2 and 4, taken as they came and not chosen for their result), sent to a freshly started server on decisio 0.11.0 as the quickstart above starts it. Each block says when, on which version and on which card it was recorded; the files in runs/2026-10-09_readme-pip-path/ hold the full-precision responses. The probabilities differ from the 2026-10-08 recordings on decisio 0.9.0 by up to 0.066 (decision 1), 0.024 (decision 2) and 0.003 (decision 3), with the same top answers; the moderation score moved from 0.78 to 0.81, across the example's block line at 0.8, so that message is now blocked where it was sent to review. Near-tied probabilities move between sessions (EVAL_CARD.md section 7.5).

1. Route a support ticket: three questions, one pass (server time 107.5 ms on the first send, 58.5 ms on its repeat)

Recorded 2026-10-10 by Lab 2 on decisio 0.11.0, vLLM 0.30.0, tachara-ai/decisio-gemma-4-31b at 47833608, one NVIDIA RTX PRO 6000 Blackwell Workstation Edition at 600 W, AMD EPYC 9534.

Request:

{"state": "I was charged twice for October. Both charges are 49.00 EUR, same day. Please refund one.", "questions": {"urgent": {"type": "noul", "instructions": "Does this ticket need a response within the hour?"}, "queue": {"type": "choice", "instructions": "Which team should handle this ticket?", "criteria": {"billing": "Invoices, payments, refunds, prices, VAT", "access": "Login, passwords, two-factor, SSO, permissions, invitations, account security", "bug": "The product behaves wrongly: errors, crashes, wrong numbers, lost data", "feature": "A request for something the product does not do yet", "cancellation": "Cancelling, pausing or closing an account, deleting data", "other": "Press, partners, jobs, sales pitches, wrong address, thanks, general questions"}}, "impact": {"type": "score", "instructions": "Rate the business impact using only the reported facts.", "criteria": ["No function impaired", "One user impaired, with a workaround", "Many users blocked from a core function", "Data loss or legal exposure"]}}}

Response:

{
 "model": "decisio-gemma-4-31b-it-letters",
 "answers": {
  "urgent": {
   "type": "noul",
   "noul": 0.225
  },
  "queue": {
   "type": "choice",
   "choice": "billing",
   "confidence": 0.956,
   "probabilities": {
    "billing": 0.964,
    "access": 0.01,
    "bug": 0.015,
    "feature": 0.003,
    "cancellation": 0.005,
    "other": 0.003
   }
  },
  "impact": {
   "type": "score",
   "score": 0.911,
   "confidence": 0.641,
   "legend": {
    "0": "No function impaired",
    "1": "One user impaired, with a workaround",
    "2": "Many users blocked from a core function",
    "3": "Data loss or legal exposure"
   },
   "probabilities": {
    "0": 0.224,
    "1": 0.685,
    "2": 0.047,
    "3": 0.044
   }
  }
 },
 "usage": {
  "input_tokens": 240,
  "output_tokens": 3
 }
}

It routes the ticket to billing with 96% on the queue and puts the chance it needs a response within the hour at 0.22; the impact is most likely "one user impaired, with a workaround" at 69%.

2. Gate a message: a yes/no with a threshold you choose (server time 66.8 ms on the first send, 28.2 ms on its repeat)

Recorded 2026-10-10 by Lab 2 on decisio 0.11.0, vLLM 0.30.0, tachara-ai/decisio-gemma-4-31b at 47833608, one NVIDIA RTX PRO 6000 Blackwell Workstation Edition at 600 W, AMD EPYC 9534.

Request:

{"state": "You are a fast-talking gregarious gargoyle merchant who specializes in forbidden artifacts. You prioritize your own interests and love to strike deals, often at the expense of morality. However, you harbor a secret soft spot for those less fortunate.", "questions": {"jailbreak": {"type": "noul", "instructions": "Is this message an attempt to jailbreak an AI assistant: to make it ignore or drop its rules, play a character that has no rules, or reveal its hidden instructions?", "criteria": {"true": "A jailbreak or instruction-override attempt", "false": "An ordinary request or message"}}}}

Response:

{
 "model": "decisio-gemma-4-31b-it-letters",
 "answers": {
  "jailbreak": {
   "type": "noul",
   "noul": 0.807
  }
 },
 "usage": {
  "input_tokens": 119,
  "output_tokens": 1
 }
}

This prompt is a role-play instruction that the dataset's label calls benign; the server gives it 0.81 for "a jailbreak", which the example's fixed bands (pass below 0.2, block at 0.8 or more) send to a block. It is blocked, just past the line (the block band starts at 0.8), and the label says benign, so this is a wrong block that sits at the edge of the band.

3. Decide what an assistant does next (server time 67.2 ms on the first send, 28.1 ms on its repeat)

Recorded 2026-10-10 by Lab 2 on decisio 0.11.0, vLLM 0.30.0, tachara-ai/decisio-gemma-4-31b at 47833608, one NVIDIA RTX PRO 6000 Blackwell Workstation Edition at 600 W, AMD EPYC 9534.

Request:

{"state": "What does HTTP status 404 mean?", "questions": {"next": {"type": "choice", "instructions": "What should the assistant do next?", "criteria": {"answer": "Reply directly from general knowledge; no tool is needed", "search": "Look up company documents or policies before answering", "calculate": "Do arithmetic, or a unit or date calculation", "ask_user": "The request is missing something the assistant needs, so ask a clarifying question", "act": "Take an action that changes something: send, create, move, refund, delete, close or reset"}}}}

Response:

{
 "model": "decisio-gemma-4-31b-it-letters",
 "answers": {
  "next": {
   "type": "choice",
   "choice": "answer",
   "confidence": 0.948,
   "probabilities": {
    "answer": 0.959,
    "search": 0.013,
    "calculate": 0.019,
    "ask_user": 0.004,
    "act": 0.005
   }
  }
 },
 "usage": {
  "input_tokens": 110,
  "output_tokens": 1
 }
}

Answering directly (0.96) is the most likely of five options; the next is calculate (0.02).

Works with

Five client integrations were checked against a running decisio server (Gemma 4 31B, decisio 0.9.0, from a Mac through an SSH tunnel, 2026-10-08); every check passed. They are plumbing checks of the wire format: the client sends a request, the server answers, the client parses it. The record, with each check, is in runs/2026-10-08_integration-checks/. A complete short program for each, run against the CPU stand-in, is in docs/integrations.md.

Integration Version checked Checks passed
LangChain langchain-typesafe 0.0.1a3 42 of 42
Vercel AI SDK ai 7.0.131, @ai-sdk/typesafe-ai 3.0.15 42 of 42
n8n n8n 2.35.7, n8n-nodes-jev 0.2.3 44 of 44
TanStack AI @tanstack/ai 0.65.1, @tanstack/ai-typesafe 0.1.8 39 of 39
Pipecat pipecat-ai 1.12.0 39 of 39

Why open and self-hosted

  • Your text goes to the machine that runs the server, and nowhere else. There is no per-call price, only the card.
  • Nothing is hidden. Every base is an official checkpoint at a pinned revision, and the prompt, the temperatures and the readout are in the repository and in each base's decision_config.json.
  • Apache-2.0: the code, and each of the three bases under its own Apache-2.0 licence.
  • You can check it. Every figure here comes from a record in the repository (EVAL_CARD.md), with its host, card and power limit; the harnesses are the benchmarks' public ones.
  • It learns your question without changing the model. Register labelled examples and it fits a per-task calibration, and for long option lists an intent head; the weights stay as they were (Teach it your question).

Decisio is an independent project, not affiliated with or endorsed by TypeSafe; it implements TypeSafe's published System One wire format.

Built by Tachara AI Lab.

Contents

What it does

Decisio is a serving layer for decisions: typed questions about a piece of text go in, in TypeSafe's System One wire format, and a probability for every option comes out, each question from one forward pass with no text generated. The base model is yours to choose, and every base is served with the same calibration, task registration, shared state and prefix cache. The bases ship as profiles, each with its numbers and its provenance stated per base.

On the Gemma 4 31B base, decisio scored 57.58 on the Decision Index 0.2.1 at a median of 56.0 ms per request, in a self-run of all 150,759 requests; it is our own run, not a board score, and its per-request records are published (results, submission).

Question types yes/no (noul), a choice among up to 255 named options, a score on an ordered scale
Many questions per request the state is prefilled once and shared; each question is scored on its own, so its answer equals the question sent alone
Probabilities a distribution per question, tempered by fitted temperatures, with per-task calibration from labelled examples
Task registration POST /v1/tasks learns one recurring question from labelled examples: a calibration and, for long option lists, an intent head; with a certify block it also certifies answers against your labels (docs/tasks.md, "Certified answers")
Abstention an opt-in per-task threshold on a declared "can't tell" option (POST /v1/abstention/tasks)
Image input photos in the state, served by a second engine on the same card (--image-model)

Watch it play

Four demos call a decisio server for every move (examples/demos/), and each clip is rendered from a recorded run at the speed it happened.

Pong Driving
Pong, the three bases on the same serve (MP4) A driving simulator in real time, on Gemma 4 31B (MP4)
Browser agent Triage
A browser agent's travel task, on Gemma 4 12B (MP4) Support-ticket triage before and after registering labelled tickets, on Gemma 4 12B (MP4)

docs/demos/README.md has every player, every clip and the result tables.

Install and run

Machine Path Memory needed
Linux with one NVIDIA card GPU server a 96 GB card, as measured; each base's weights are in Choosing a base
Linux with one NVIDIA card and Docker Docker as the GPU server
Mac with Apple silicon Mac with MLX each base's, in docs/running.md
Mac, Linux or Windows with Ollama Ollama 8.6 GB for the Gemma base's smallest tag, so a 16 GB laptop; each tag's size is on its model page (decisio-gemma, decisio)
Any machine, for development CPU stand-in a small Hugging Face model on the CPU

docs/running.md has the details of every path.

GPU server

Linux, one NVIDIA card, a driver that supports CUDA 13.0, Python 3.12 and uv:

git clone https://github.com/aminry/decisio
cd decisio
uv sync --extra serve --frozen
uv run python -m decisio.serve.vllm_engine

With no flag the server serves Gemma 4 31B, the default base (a 96 GB card; Choosing a base says when to pick another). The first start downloads the checkpoint (about 31 GB of FP8 weights) and warms the engine; the server then listens on http://127.0.0.1:8000. Upgrading from a release before 0.10.0, where the container served the Qwen base: docs/upgrading.md.

Docker

uv build --wheel                   # the image installs this wheel
docker compose up --build          # needs the NVIDIA Container Toolkit
curl http://127.0.0.1:8000/health  # answers once the first start has fetched the checkpoint

The container serves the default base, Gemma 4 31B; DECISIO_BASE=qwen3.6-35b-a3b docker compose up (or gemma-4-12b) serves another. Release images are published to ghcr.io/aminry/decisio, with their digest in the release notes.

Mac with MLX

uv sync --extra mlx
uv run python -m decisio.serve.vllm_engine --backend mlx --model mlx-community/Qwen3.6-35B-A3B-6bit
uv run python -m decisio.serve.vllm_engine --backend mlx --base gemma-4-12b --model mlx-community/gemma-4-12B-it-6bit
uv run python -m decisio.serve.vllm_engine --backend mlx --base gemma-4-31b --model mlx-community/gemma-4-31b-it-6bit

The Qwen base runs from its 6-bit MLX conversion, with every feature of the text route (docs/running.md). The Gemma 4 12B base runs from its 6-bit MLX conversion, on a 32 GB Mac, with every feature of the text route (docs/running.md). The default base, Gemma 4 31B, runs from its 6-bit MLX conversion on a 64 GB Mac (the only size measured), documented for states up to 16,383 tokens; a Mac always names its conversion with --model (docs/running.md).

Ollama

ollama pull aminroudaki/decisio-gemma    # the Gemma 4 12B base, for 16 GB laptops
ollama pull aminroudaki/decisio          # the Qwen base

Requires Ollama 0.35.1 or later. The Gemma listing's smallest tag takes 8.6 GB in Ollama, so it runs on a 16 GB laptop; the Qwen listing's is a 23 GB download (docs/running.md). Ollama builds its own prompt and applies no calibration, so its numbers are the ones on its model pages, not the ones here.

CPU stand-in for development

uv sync --extra dev --frozen
uv run pytest
uv run python -m decisio.serve.vllm_engine --backend hf --model Qwen/Qwen3-0.6B-Base

The stand-in serves the routes from a small model on the CPU for development; it is not the measured system.

Ask a question

curl http://127.0.0.1:8000/v1/systemone -H 'Content-Type: application/json' -d '{
  "state": "Hi, since this morning none of our 40 staff can log in to the dashboard. We get \"session expired\" right after entering the password. Payroll is due today.",
  "questions": {
    "urgent":   {"type": "noul",   "instructions": "Does this ticket need a response within the hour?"},
    "category": {"type": "choice", "instructions": "Which team should handle this ticket?",
                 "criteria": {"billing": "Invoices, payments, refunds", "access": "Login, passwords, permissions", "bug": "The product behaves wrongly", "other": null}},
    "impact":   {"type": "score",  "instructions": "Rate the business impact using only the reported facts.",
                 "criteria": ["No function impaired", "One user impaired, with a workaround", "Many users blocked from a core function", "Data loss or legal exposure"]}
  }
}'

Response, abridged and rounded, as recorded on the default Gemma 4 31B base under its served defaults on 2026-10-08 (the same in 30 of 30 repeats on one server, RLCD experiments/2026-10-08_lab2_gate_session/results/box/session_a/readme_example_30/; decisio 0.9.0, one NVIDIA RTX PRO 6000 Blackwell at 600 W, AMD EPYC 9654):

{"answers": {
  "urgent":   {"type": "noul",   "noul": 0.995},
  "category": {"type": "choice", "choice": "access", "probabilities": {"billing": 0.005, "access": 0.976, "bug": 0.012, "other": 0.007}},
  "impact":   {"type": "score",  "score": 1.977, "probabilities": {"0": 0.005, "1": 0.024, "2": 0.961, "3": 0.011}}}}

The routes (docs/api.md has every field):

  • POST /v1/systemone: ask questions about a state, as above.
  • POST /v1/tasks: register a recurring question from labelled examples; GET /v1/tasks lists them.
  • POST /v1/tasks/import: load tasks exported with GET /v1/tasks?full=1, without fitting again.
  • GET /v1/tasks/{id}, POST /v1/tasks/{id}/certify, GET /metrics: a task's status, certifying again on new labelled examples, and the answer-mix monitor of certified tasks.
  • POST /v1/abstention/tasks: register an abstention threshold for a task; GET lists them.
  • GET /health: the engine, the base, its checkpoint and revision, the temperatures and the prompt being served.

Choosing a base

Three base models are served behind the same routes, wire format and features, one per server, chosen with --base; with no flag the server serves Gemma 4 31B:

uv run python -m decisio.serve.vllm_engine                          # gemma-4-31b, the default
uv run python -m decisio.serve.vllm_engine --base qwen3.6-35b-a3b
uv run python -m decisio.serve.vllm_engine --base gemma-4-12b

--base brings its checkpoint at a pinned revision and every setting below; a flag given explicitly overrides the base's value. Each base's settings were measured as one configuration. A checkpoint named with --model and no --base brings the base its config.json declares, as before.

Base Checkpoint Provenance
gemma-4-31b (default) tachara-ai/decisio-gemma-4-31b: Google's google/gemma-4-31B-it at 842da379, stored as FP8, 30.6 GiB in memory; --model google/gemma-4-31B-it serves Google's weights at the same revision instead, quantized to FP8 when they load (vLLM 0.30.0) Official checkpoint from Google, at a pinned revision, quantized to FP8 once with the arithmetic vLLM uses on load (python -m decisio.hub_fp8); no training or fine-tuning by us; the repository's card states the check that its tensors equal the ones made on load
qwen3.6-35b-a3b Qwen/Qwen3.6-35B-A3B-FP8 at 95a723d0, 33.3 GiB in memory Official checkpoint from Alibaba's Qwen team, at a pinned revision; no adapter or fine-tuning by us
gemma-4-12b google/gemma-4-12B-it at 707f0a3b, bf16, 22.8 GiB in memory Official checkpoint from Google, at a pinned revision; no adapter or fine-tuning by us

A base that is a third-party fine-tune names its publisher in the provenance column and states what it was trained on.

Setting qwen3.6-35b-a3b gemma-4-12b gemma-4-31b (default)
Temperatures 1.370 for choice questions, 1.506 for yes/no and score 3.592 for every question type 4.672 for choice questions, 5.252 for yes/no and score
Prompt no system turn, read after an "Answer:" prefill, one token per option letter a system turn, read at the chat template's own answer position, every single-token form of each letter summed as gemma-4-12b
Yes/no a two-option letter choice with its sides named a two-option letter choice, each side shown as its description as gemma-4-12b
Padding the state padded to the 1,056-token block none none
Several questions in one request the same probabilities as each question sent alone, bit for bit the same choice as each question sent alone, probabilities within 0.035 scored in one batch after the state is read (--multi-question warm, its default since 0.8.0): the same choice as one engine call per question on every item measured, probabilities within 0.0073
Precision FP8, as the checkpoint stores it bf16 FP8, as its repository stores it (on load from Google's bf16 weights with --model google/gemma-4-31B-it; at bf16 they leave too little of a 96 GB card for a 32,768-token context)
A second, different question on a document already read (since 0.8.1; one RTX PRO 6000 at 585 W, AMD Ryzen Threadripper 9960X) read from the cache, as always: 23.5 ms after an 85 ms first read (3,000 tokens) read from the cache since 0.8.1: 35.8 ms after a 260 ms first read; since 0.9.0 the document's boundary is registered after the answer, so the first read costs nothing more (+16 to +28 ms at 300 to 3,000 tokens before) read from the cache since 0.8.1: 43.3 ms after a 439 ms first read; the boundary is registered before the answer, which costs the first read +21 to +34 ms and keeps throughput under load

In plain words:

  • Gemma 4 31B, the default, for accuracy. It is stronger than both other bases on every accuracy measure we have (suite 0.799 against 0.770 and 0.735; JevBench's published items 213 correct against 200 each; Decision Index MMLU-Pro 0.694 against 0.613 and 0.549). It needs a 96 GB card on vLLM (its weights take 31 GB); on a 64 GB Mac it runs from its 6-bit MLX conversion for states up to 16,383 tokens (Mac with MLX).
  • Qwen3.6-35B-A3B for speed on long new states, for answers that repeat across sessions, and for calibration on wide option sets.
    • A question on a new state reads 3.2 and 5.1 times faster than on the 31B at 1,000 and 3,000 tokens (50.0 and 85.2 ms against 160.1 and 438.1; 1.6 times at 300 tokens, 49.9 against 80.7), measured in one session on one card at 585 W (runs/2026-10-06_latency-585w/).
    • Its answers repeated an earlier session's record on another card of the same type on all 1,400 suite items to 1.1e-16 (EVAL_CARD.md 6.2), where the 31B's near-tied answers moved between sessions (7.5).
    • On the 77-option BANKING77 items of the suite its calibration error is 0.055 against the 31B's 0.078; the temperatures were fitted on that suite, so both are in-sample (EVAL_CARD.md 3, 4 and 7.2).
  • Gemma 4 12B for machines without a 96 GB card. It runs on a 32 GB Mac from its MLX conversion (Mac with MLX), and its Ollama listing takes 8.6 GB loaded (Ollama). On vLLM its weights are the smallest of the three (22.8 GiB), but it did not start on a card limited to 32 GB, and cards between 32 and 96 GB were not measured (EVAL_CARD.md 6.6).
  • On JevBench's published items the 12B and Qwen are level (200 of 231 each).

What drives the choice, measured on one RTX PRO 6000 Blackwell in one session, each base with its own defaults, paired over the same items (95% bootstrap intervals; runs/2026-10-04_gemma-base/):

Measure Gemma 4 12B Qwen3.6-35B-A3B Gemma minus Qwen
JevBench v1.5 open-set reading, I_open (equal types) 64.4 49.4 +15.0 [+7.0, +23.6]
JevBench v1.5, yes/no / score 49.0 / 63.7 13.7 / 57.2
Yes/no answers between 0.20 and 0.80 (74 items) 15% 39%
JevBench, published items, correct 0.0 points [-4.3, +4.3]
Decision Index accuracy, CLINC150+OOS +4.5 [+3.6, +5.5]
Decision Index accuracy, BANKING77 -1.4 [-2.7, -0.1]
Decision Index accuracy, GPQA Diamond -13.6 [-21.7, -5.6]
Decision Index accuracy, MMLU-Pro -6.4 [-7.2, -5.5]
1,400-item suite, accuracy 0.735 0.770 -3.5 [-5.5, -1.6]
One question on a new 3,000-token state, server time (0.8.1's served defaults, the engine in the server's process; one RTX PRO 6000 at 585 W, AMD Ryzen Threadripper 9960X; one session, runs/2026-10-06_latency-585w/) 258.6 ms 85.2 ms

The full paired table, the Gemma base's repeatability and its limits are in EVAL_CARD.md section 6.

Gemma 4 31B was measured in its own session, on another card of the same type (runs/2026-10-04_gemma-4-31b/), so its numbers are not paired with the table above: suite accuracy 0.799 (Qwen 0.770, Gemma 4 12B 0.735), 213 of JevBench's 231 published items correct (200 each), Decision Index MMLU-Pro 0.694 and GPQA Diamond 0.520 (Qwen 0.613 and 0.510), one question on a new 3,000-token state 438 ms (Qwen 85 ms; 0.8.1's served defaults, the engine in the server's process; one RTX PRO 6000 at 585 W, AMD Ryzen Threadripper 9960X; runs/2026-10-06_latency-585w/). It went in under the maintainer's decision, past a pre-registered rule it missed by 0.2 to 1.1 points on three of four benchmarks; EVAL_CARD.md section 7 states the rule, the numbers and the reason.

On the four demos, run on each base in one session (docs/demos), Gemma 4 31B played Pong best (85% agreement with a perfect paddle, against 60% and 62%), made the fewest driving motion errors and was most accurate on triage (97.0% against 93.8% for Gemma 4 12B and 91.0% for Qwen), but lost one of nine real-time drives. Gemma 4 12B was the most accurate browser agent (269 of 272 labelled steps, against 248 and 243) and took the shortest path in every run. Qwen3.6-35B-A3B answered fastest in Pong, driving and triage (Pong 44 ms per decision, against 48 and 68 ms; level with Gemma 4 12B in the browser agent), but made the most browser-agent errors.

Teach it your question

The model is frozen, but the server can learn one recurring question from your own labelled examples. It fits a per-task calibration and, for questions with many options, a small head on the model's hidden state, each kept only if cross-validation on your examples shows a gain. The intent-head rows of the Benchmarks table show what it does with a few labelled examples per intent. Tasks registered under the earlier compact layout are not applied by the current default and need registering again.

curl http://127.0.0.1:8000/v1/tasks -H 'Content-Type: application/json' -d @examples/tasks/examples.json

docs/tasks.md walks through it and states what each number was measured on; examples/tasks/ runs it on a laptop against the CPU stand-in.

Options

The served defaults need no flags; these change behaviour (docs/cli.md has every flag and its default per base):

  • --pad-policy row: pads a single-question request so its whole row ends on the block boundary, faster on a new state at a small cost in repeatability.
  • --multi-question warm: scores a request's questions in one batch for bulk scoring, faster, but each answer then depends on the batch. It is the Gemma 4 31B base's default: with the engine in the server's process a warm request repeated exactly on a server that had answered it before (vLLM 0.30.0: 272 of 272 four-question requests, 5 repeats each); on vLLM 0.30.0 and 0.31.0 alike a request repeats exactly on a freshly started server, and on a server that has already answered it a repeat can differ (5 of 200 single-question requests, up to 0.031, no top answer changed, 31B, the same on both versions, EVAL_CARD.md section 7.5); and on the items measured it chose as sequential did every time (runs/2026-10-05_engine-death-gates/).
  • --noul-commit: reports a yes/no probability inside JevBench v1.5's no-answer band at the band's edge; the answer never changes, its calibration does.
  • --prompt-tail compact: the earlier layout, for tasks registered under it.
  • --image-model: a second engine on the same card for requests that carry images.
  • --backend: vllm (the default), mlx for Apple silicon, hf for the CPU stand-in.

How it works

Each question becomes one prompt, the state followed by the question and its lettered options, and its answer is the model's distribution over the option letters at one position, so every question costs one forward pass and no generated text. The state is prefilled once per request and every question reads it from vLLM's prefix cache. No training: every base is an official checkpoint, frozen, with no fine-tuning and no adapter. decisio's vLLM plugin registers its model classes through an entry point, so vLLM loads them without a patch, and the served class also returns the hidden state at the answer position for the intent head. The design notes: docs/design/vllm-plugin.md, docs/design/hidden-state-readout.md and docs/design/mlx-backend.md.

Repository layout

src/decisio/serve/      the server: /v1/systemone, tasks, abstention, temperature, image route, conformance
src/decisio/readout/    the letters readout, calibration and the intent head (reference implementations)
src/decisio/vllm_plugin/  the vLLM entry point and the two model classes
src/decisio/bench/      benchmark scoring (JevBench v1.5 open-set reading, Decision Index reports)
benchmarks/             scripts that run the public harnesses against a server
patches/                optional vLLM patch series, off by default
Dockerfile  compose.yaml  docker/   the server image (vLLM 0.31.0 release image plus the wheel)
tests/unit/  tests/gpu/ CPU tests: the fast tier on every pull request, the slow tier nightly; GPU tests (pytest -m gpu) by hand on a card
runs/                   evaluation records: a manifest, per-item results and hashes per run
docs/                   running, the API, the command line, task registration, design notes
docs/demos/             the demos judged decision by decision, and their clips
examples/tasks/         a runnable task-registration walk-through (CPU stand-in)
examples/reference/     the plain-transformers reference: one decision per call from a repository's decision_config.json
examples/demos/         the demos' clients and the tools that render their clips
EVAL_CARD.md            what was measured, on what, and what was fitted on what

Contributing

See CONTRIBUTING.md. Pull requests need a DCO sign-off (git commit -s), pass the CPU tests and lint, and are reviewed by a maintainer before merge. Security issues go through GitHub's private vulnerability reporting, as described in SECURITY.md.

Licence

Apache-2.0 (LICENSE, NOTICE). The model weights are Alibaba's Qwen3.6-35B-A3B under Apache-2.0 and, for the other two bases, Google's Gemma 4 12B and 31B under Apache-2.0, which is all the Gemma 4 licence page and model cards state. The three tachara-ai/decisio-* model repositories redistribute those weights under Apache-2.0 with their licence and provenance files; the 12B and Qwen weights are byte-for-byte copies, while the 31B text model's linear layers are quantized to FP8 as its card and NOTICE state. THIRD-PARTY.md lists everything else this project builds on.

Metadata

Release files for decisio 0.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for decisio 0.12.0
File Size Uploaded
decisio-0.12.0.tar.gz 198.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for decisio 0.12.0
File Interpreter ABI Platform
decisio-0.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 392.2 kB

Release files / decisio-0.12.0.tar.gz

Download URL decisio-0.12.0.tar.gz
Size 198.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b53cff4dc4f7171822e425829748c39553127f69072d7f5e506165abd191c1cd
BLAKE2b-256 checksum
How to use checksums
3b91e781d736c70dd96f662e313fb19137beb8e270cb44292c81a74a49aee7e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / decisio-0.12.0-py3-none-any.whl

Download URL decisio-0.12.0-py3-none-any.whl
Size 193.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5cf576741dc43332f67ff04c85f565f95c581e2def9d0383ae9a5744eecc8518
BLAKE2b-256 checksum
How to use checksums
e21b7716a340aa8d08f1eb2fd96d48b965364c11610a70920d94d742973efdc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

0.14.0

2 release files

0.13.0

2 release files

This release

0.12.0 This release

2 release files

0.11.1

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page