D1A models: what each can do (2026-10-14)
What each D1A model line can do today. "Decisions" means D1A's System One API (POST /v1/systemone): yes/no, choice and score questions over a document, answered in one pass with calibrated probabilities. Numbers are from each model's card; "not measured" means the card has no number yet.
Table with columns: D1A-E4B v0.6.1, D1A-E2B v0.6.1, D1A-E2B-it v0.6, D1A-12B | D1A-E4B v0.6.1 | D1A-E2B v0.6.1 | D1A-E2B-it v0.6 | D1A-12B |
|---|
| Base model (trunk) | Gemma 4 E4B (pretrained base) | Gemma 4 E2B (pretrained base) | Gemma 4 E2B-it (instruction-tuned) | Gemma 4 12B-it QAT; not trained yet (jonpol01/d1a#270, shelved) |
Decisions (/v1/systemone) | yes | yes | yes (experimental) | — |
| PR labeling, 487 PRs newer than all training: severity / change type | 79.1% / 90.6%; P0/P1 found 13 of 30 | 77.2% / 87.5%; P0/P1 0 of 30 | 72.9% / 87.3%; P0/P1 3 of 30 ("not a PR labeller") | — |
| Skill suites (hard, developer tools, long documents, transfer, Japanese JGLUE) | measured (card) | measured (card) | not measured | — |
Photos, voice and video (/v1/systemone/media, MLX builds with media/) | yes, zero-shot | yes; 25 of 28 demo answers match E4B | yes; 21 of 28 match E4B | — |
Routing temperature ("use_case": "routing") | yes, T 1.18 (from v0.6.1) | yes, T 0.95 (from v0.6.1) | no | — |
| Self-learning (outcome log, recalibration, learned flags) | yes, when served by d1a.serving.serve | yes | yes | — |
| Chat / text generation | no: base trunk; the MLX build has the adapter merged | no (same) | yes: build it with scripts/export_mlx.py --unmerged and serve it; with the adapter off it is Gemma 4 E2B-it (Enable chat, Chat with D1A). Also runs as an unmerged adapter in the Mieru iPhone app | planned: adapter off = Gemma 4 12B-it |
| Embeddings | — | — | from a GGUF embedder served beside it (D1A_EMBED_GGUF) | — |
| Builds | PyTorch JohnP1/d1a-e4b; MLX 8-bit JohnP1/d1a-e4b-mlx-q8 (7.6 GB with 1.0 GB of media encoders) and mirror mlx-community/d1a-e4b-8bit; Core ML int8 preview JohnP1/d1a-e4b-coreml (text only, ≤512 tokens) | PyTorch JohnP1/d1a-e2b; MLX 8-bit JohnP1/d1a-e2b-mlx-q8 (4.8 GB) and mirror mlx-community/d1a-e2b-8bit; Core ML int8 JohnP1/d1a-e2b-coreml (text only, ≤512 tokens) | PyTorch adapter JohnP1/d1a-e2b-it; MLX JohnP1/d1a-e2b-it-mlx-q8 (4.8 GB) and -mlx-q4 (3.6 GB), both merged; Core ML JohnP1/d1a-e2b-it-coreml and -coreml-4bit | 4-bit Q4_0 export ready (, ) |
| Calibration temperature | 1.95 | 1.45 | 1.41 | — |
| Where it runs | the Mac mini playground and the PR labeler (MLX 8-bit, v0.6.1) | — | the Mieru iPhone app | — |
Older single-purpose builds: JohnP1/d1a-e4b-pr-labeler-mlx-q8 (v1) and JohnP1/d1a-e4b-routing / -routing-mlx-q8 (v0.1), superseded by D1A-E4B v0.6.1.
Kept current in the D1A repository: docs/MODELS.md.
What's inside
A LoRA adapter (rank 16 on the attention and MLP projections: q, k, v, o, gate, up, down) and a small pointer head (256-dimensional) on google/gemma-4-E2B at revision d29ff6b4.
Table with columns: Version, Stage, Training data, Settings| Version | Stage | Training data | Settings |
|---|
| v0.1 / v0.2 | General decisions | decision-v7 suite: ~12,500 records from public classification datasets plus generated policy and rule data | 1 / 2 epochs, lr 5e-5; v0.2.1-2epoch-calibrated adds the calibration temperature (1.52) |
| v0.6 | Every later D1A skill, in one run | PR labels: 4,000 English (severity-stratified), 753 Japanese, 1,500 with a blast-radius label, and 479 hermes-agent PRs created 2026-10-02 to 10-05 shown twice (once in each half); hard-v1 4,000; devtools-v1 4,000; documents-v1 2,500; JGLUE 2,000; routing: agent factory 1,216, generic 1,000; decision-v7 replay 1,500: 23,427 records | from v0.2.1, 1 epoch, lr 5e-5, states up to 5,120 tokens, 2,929 steps (1 h 43 m on one NVIDIA L40S) |
E4B reached the same skills over several stages (v0.2 to v0.6). E2B gets them in one mix at the final proportions, so no stage has to replay an earlier one. The version number jumps from v0.2 to v0.6 to match the E4B release with the same skills. Before training, the mix was screened against every evaluation partition, the 487 newer PRs below included: none of their documents or PRs is in it.
Calibration: a single temperature, T = 1.45 (90% interval [1.38, 1.52]), fitted on pooled rows of the decision-v7 calibration split and the PR-labelling development set. Calibration error is 0.051 before and 0.024 after, out of fold. It is stored in d1a_config.json and head.pt, and there are no per-use-case temperatures.
Results
Pull requests newer than all training
487 hermes-agent pull requests created after every PR in v0.6's training, held back before it was trained. All models are MLX 8-bit at their served temperatures, with the serving context. Differences are paired over PRs, with 95% bootstrap intervals. E4B v0.6 is shown for reference:
Table with columns: Question, Majority answer, E2B v0.2.1, E2B v0.6, E4B v0.6, E2B v0.6 − v0.2.1| Question | Majority answer | E2B v0.2.1 | E2B v0.6 | E4B v0.6 | E2B v0.6 − v0.2.1 |
|---|
| Severity (P0–P4) | 67.8% | 33.5% | 77.2% | 79.1% | +43.7 [+38.2, +49.3] |
| Change type | 51.5% | 26.9% | 87.5% | 90.6% | +60.6 [+56.1, +64.9] |
| P0 recall (7 PRs) |
Every suite, against E2B v0.2.1
Held-out data only. Both E2B models are MLX 8-bit (JohnP1/d1a-e2b-mlx-q8) at their served temperatures (v0.2.1 1.52, v0.6 1.45), scored with d1a.eval.benchmark through D1A's quality gate. Differences are paired over questions, with 95% bootstrap intervals. E4B v0.6's numbers (its own card) are for reference:
Table with columns: Set, E2B v0.2.1, E2B v0.6, Δ [95% CI], Calibration error, E4B v0.6| Set | E2B v0.2.1 | E2B v0.6 | Δ [95% CI] | Calibration error | E4B v0.6 |
|---|
| Hard decisions (hard-v1, 1,083 questions) | 31.4% | 62.1% | +30.7 [+26.9, +34.4] | 0.187 → 0.056 | 68.8% |
| Developer-tool decisions (devtools-v1, 1,074) | 50.5% | 65.4% | +14.9 [+12.1, +18.1] | 0.157 → 0.042 | 70.1% |
| Long documents (documents-v1, 920) |
* Not like for like: E4B v0.6's card scored transfer-v4 on 764 questions and semif-v1 on 252, different partitions from the 656 and 144 here.
Pooled over all 21 lines, v0.6 − v0.2.1 = +18.9 [+17.4, +20.4]. Latency is unchanged against v0.2.1: v0.6 over v0.2.1 on short requests is 1.0013, within run-to-run noise (measured interleaved).
Calibration: error is lower than v0.2.1's on 12 of the 22 suites, most on hard and developer-tool decisions. It is higher on 10, most on typesafe-v1 (0.106 → 0.212), dates (0.043 → 0.109), agent factory (0.031 → 0.091), long documents (0.017 → 0.036) and decision-v7 (0.030 → 0.042).
Photos, voice and video
With the media extra, d1a.serving.serve answers questions about a photo, a voice clip or a video with this same model through Gemma 4 E2B's own vision and audio encoders, unchanged by the adapter (POST /v1/systemone/media). No media in training (zero-shot). Zero-shot, measured on only the playground's 14 photo, voice and video demo requests. v0.6 answers all 14, and calls 2 of the 3 intact photos damaged (the locker and the mailbox):
- 26 of 28 answers match E2B v0.2.1. The changed two: the damaged wet-parcel video is now called damaged (right), and the intact-mailbox photo is now called damaged too (wrong).
- 25 of 28 match E4B v0.6. The intact-locker and intact-mailbox photos are called damaged, and the mailbox's place is "in a delivery locker". So it calls intact items damaged more often than E4B does.
The questions it was trained for
PR labelling works best with these questions, worded exactly so, over a document of the form title / author / stats / body / files (one - status path +added/-deleted line per file):
type (choice): "Primary change type from files and body, not the title prefix." Options: type/bug, type/docs, type/feature, type/perf, type/refactor, type/security, type/test.
blast (choice): "How far a mistake in this PR spreads in production." Options: review:blast-contained (one module), -moderate (one subsystem), -broad (shared helper or config), -massive (auth, permissions, or all paths).
sev (choice): "How serious the problem this PR addresses is — not the risk of merging the diff as-is." Options P0 to P4.
The PR-labeler recipe has the exact wording, the document builder and the training and scoring scripts. The mix builder builds and screens mixes like v0.6's.
Run it
pip install "d1a[serve] @ git+https://github.com/jonpol01/d1a"python -m d1a.serving.serve --run JohnP1/d1a-e2b@v0.6.1 --port 8009
or in-process: from d1a import D1A; D1A.load("JohnP1/d1a-e2b@v0.6.1").decide(state, questions). On Apple Silicon the 8-bit MLX build, JohnP1/d1a-e2b-mlx-q8 v0.6, is faster and smaller (4.4 GB with the photo, voice and video encoders). For general decisions only, @v0.2.1-2epoch-calibrated is 1.4 points better on decision-v7.
Limits
- Never act on its raw top answer for tool gating. On the playground's $4,999 payment example it is a near-tie (allow 0.36, ask 0.35, deny 0.29), so the top answer allows the call. Gate tool calls through D1A's fail-safe thresholds instead (
d1a.agents.presets.advise: deny at p ≥ 0.5, allow only at p ≥ 0.8, otherwise ask), which turn this case into "ask".
- Not a replacement for E4B v0.6 as a PR labeller. On the 487 newer PRs it never predicted P0 or P1: P0/P1 recall is 0/30 (E4B v0.6: 13/30). On the frozen English test set it finds 4 of 47 P1 PRs (11 P1 calls) and never predicts P0. With severity offsets fitted on the development set it finds 26 of 47, but at a precision of 0.19. Use E4B for severity, or flag a PR when p(P0) + p(P1) is high instead of taking the top answer.
- Behind E4B v0.6 on almost every suite: hard decisions 62.1% against 68.8%, developer tools 65.4% against 70.1%, transfer 63.6% against 73.0%, JGLUE about 5 points lower, typesafe-v1 53.9% against 74.5%, dates 80.9% against 92.1%.
- General decisions are 1.4 points below v0.2.1 (the release exception above), and dates 2.6 points below: 83.4% → 80.9%, −2.6 [−5.0, −0.1].
- Calibration error rose on 10 of 22 suites. On typesafe-v1, TypeSafe's own suite for its hosted API, it went from 0.106 to 0.212. On dates it went from 0.043 to 0.109, and the share of answers given at 90% confidence or more fell from 0.36 to 0.10. It also rose on agent factory, long documents and decision-v7 (numbers above). Probabilities on those sets are less trustworthy than v0.2.1's.
- Media: zero-shot, measured on 14 demo requests only. It calls 2 of 3 intact photos damaged, more often than E4B v0.6 does (above).
- grades answers less sharply than v0.2.1 did. For the English "good answer", error goes from 0.088 to 0.153 and quality from 3.81 to 3.51 (out of 5).
Versions
Table with columns: Tag, What it adds| Tag | What it adds |
|---|
v0.1, v0.1-1epoch | general decisions (decision-v7, 1 epoch) |
v0.2, v0.2-2epoch | general decisions, 2 epochs |
v0.2.1-2epoch-calibrated | the same weights with a calibration temperature (1.52) |
v0.6.1 | v0.6's weights with a routing temperature: "use_case": "routing" is served at T 0.95 (others keep 1.45); factory routing calibration error 0.091 → 0.035, answered at ≥ 0.9 confidence 34% → 55%, no answer changed (jonpol01/d1a#264) |
License and data
Apache-2.0. Base model: Gemma 4 by Google (Apache-2.0). Code: github.com/jonpol01/d1a, built on Kev by Jared Palmer (Apache-2.0). Japanese decision data derived from JGLUE by Yahoo Japan Corporation and Waseda University (CC BY-SA 4.0). Pull-request data from NousResearch/hermes-agent (MIT); the labelled PR dataset itself, including the recent PRs, is private.