Skip to content

Tiny models · Post two

The exam it passed, the gate it failed

Our small model scored 400 out of 400 on the held-out exam, then finished 1 of 25 real notes in the pipeline it was meant to run. What the exam could not see, why the promotion gate caught it, and the recorder that is now building the training set for the fix.

August 28, 2026local AI · model distillation · LoRA fine-tuning · Qwen3
  • 25 / 25Notes the incumbent finishedThe model being replaced
  • 1 / 25Notes the student finishedSame work, same order, same store
  • 0.644Exam agreement, 4B studentThe bar to beat was 0.53
  • 0 out of 534On the call shape it never sawTrained on one of six shapes

You keep the human work. We build the rest.

Every number below was read on 28 August 2026, Denver time, from files our own systems wrote for themselves. Nothing was started, stopped, or changed to produce it.

In post one we promised that if the student missed, we would publish the miss with the same numbers attached. It missed, and the miss is why we now have a fix that builds itself.

Figure 1

The gate: the same 25 notes, run twice

Notes finished by the incumbent and by the studentThe incumbent finished 25 of 25 notes and matched the required answer shape on 100.0% of calls. The 4B student finished 1 of 25 notes and matched the required answer shape on 11.7% of calls.Incumbent25 / 25notes finishedCalls that matched the required answer shape100.0%4B student1 / 25notes finishedCalls that matched the required answer shape11.7%
  • Incumbent
  • 4B student
One square is one note from our own backlog. The candidate and the model it would replace ran the identical work, in the same order, against the same graph store.SourcePromotion-canary evidence pack CANARY-2026-08-28.md and CANARY-2026-08-28.json, with the per-arm run files canary-arm-a-canary-27b-20260828.json and canary-arm-b-canary-student-20260828.json and their per-call records.
01

The short version

We trained two small models to take over the reading job from the 27-billion-parameter model doing it now. Both sat the 400-question exam we held back. The 4-billion-parameter student won, with a perfect record on answer format.

Then we put the winner inside the real pipeline, on real work, beside the model it would replace. It finished 1 of 25 notes. The incumbent finished 25 of 25.

The gate said no, and it was right.

02

The exam sweep

Figure 2

The scoreboard both students passed

Exam results for both studentsAgreement with the teacher was 0.607 for the 1.7B student and 0.644 for the 4B student, against a bar of 0.53. Valid JSON was 393 of 400, 98.25%, for the 1.7B student and 400 of 400, 100%, for the 4B student.Agreement with the teacher0.53 — the bar to beat1.7B student0.6074B student0.644Valid JSON, out of 400 questions1.7B student393 / 400 · 98.25%4B student400 / 400 · 100%
  • Exam result
  • The bar to beat
Both students cleared the bar, and the bar is not a correct answer: it is how much two competent large models agreed with each other on the same paragraphs.SourceHeld-out 400-pair exam scorecards exam-4b-full-merged.json, exam-4b-head135.json, exam-4b-full-tail.json, exam-4b-step2800.json, exam-v1b-full.json, exam-v1b-retest.json and exam-v1-step900.json.
Figure 3

Serving speed, against the speed the savings case needs

Observed serving speeds against the required bandsObserved speeds: about 20 tokens per second in post one, 18 to 26 across the first 135 exam items, 63.5 across the other 265, 65.0 on a separate 100-item run, 86.1 for the 1.7B student and 99.9 for an earlier checkpoint of it. Ten seconds an item needs 63 to 85 tokens per second; five seconds an item needs 127 to 169. A dedicated run on a free card has not happened.Ten seconds an item63 to 85Five seconds an item127 to 169Post one, card held by the big modelabout 204B student, first 135 exam items18 to 264B student, the other 265 items63.54B student, separate 100-item run65.01.7B student, its own 400 items86.11.7B student, earlier checkpoint99.9A dedicated run on a free cardStill has not happened04488132176tokens per second
  • Observed
  • Speed the projection needs
  • Not measured
Every observation so far is a by-product of an exam rather than a benchmark: nothing was reserved and nothing was pinned. The shaded columns are the speeds post one's arithmetic requires.SourceHeld-out 400-pair exam scorecards exam-4b-full-merged.json, exam-4b-head135.json, exam-4b-full-tail.json, exam-4b-step2800.json, exam-v1b-full.json, exam-v1b-retest.json and exam-v1-step900.json.

Two students, one exam, 400 questions neither had seen.

1.7B student4B student
Valid JSON393 / 400 (98.25%)400 / 400 (100%)
Agreement with the teacher0.6070.644

The bar to beat was 0.53, which is from post one: how much two competent large models agreed with each other on the same paragraphs. Both students cleared it. The 4B cleared it by more and never wrote broken JSON, so the 4B was crowned.

Post one also promised a serving speed on a free graphics card, because the savings case rests on it. This is the best measurement we have, and it is still not the clean one.

The winning 4B served the same exam at two speeds on the same morning: 18 to 26 tokens per second across the first 135 items, and 63.5 tokens per second, 12.44 seconds an item, across the other 265. Same model, same adapter, same questions, an hour apart. The only thing that changed is how busy the machine was. A separate 100-item run of the same model landed at 65.0, so the faster figure is not a fluke. The 1.7B measured 86.1 tokens per second and 8.86 seconds an item across its own 400 while the machine was loaded, and an earlier checkpoint of it reached 99.9.

03

The gate said no

We do not promote on an exam score. We promote on a canary: the candidate runs the whole pipeline on real work, and the incumbent runs the identical work beside it. Same 25 notes from our own backlog, same order, same graph store.

Incumbent4B student
Notes finished25 / 251 / 25
Calls that matched the required answer shape100.0%11.7%
Facts written to the graph151 entities, 135 links21 entities, 8 links

The student was faster per note, 93.9 seconds against 139.5. It was fast because it gave up.

The exam could not see the reason. The memory engine does not make one kind of request. It makes six, each asking for a different answer shape: pull out the entities, pull out the relationships, is this entity one we already have, is this fact a duplicate or a contradiction, and two more. Our student was trained on exactly one of them, because we harvested its training pairs from one hand-written prompt.

On the shape it was trained for, it was perfect inside the real pipeline: 25 of 25 clean.

On the shape it had never seen, it scored 0 out of 534. That shape is the duplicate-and-contradiction check, the call that keeps the graph from becoming a pile of repeated facts. The student failed it the same way every time. Handed the answer shape it was supposed to fill in, it printed the shape back:

{"properties": {"duplicate_facts": {"description": "List of idx values of
duplicate facts (only from EXISTING FACTS range). Empty list if none.", ...

The first 500 characters are identical across 394 of those attempts. The other 140 are the same thing, pretty-printed.

04

Why the exam missed it

Figure 4

Six call shapes, one of them trained for

Training coverage across the six call shapesOf six request shapes, the student was trained on one and was clean on it inside the real pipeline, 25 of 25. On the duplicate-and-contradiction shape it had never seen, it scored 0 out of 534. The other four shapes were not trained and were not separately measured.The shape it was trained onTRAINED25 of 25 cleanDuplicate and contradiction checkNEVER SEEN0 out of 534One of the other four shapesNOT TRAINEDNot measuredOne of the other four shapesNOT TRAINEDNot measuredOne of the other four shapesNOT TRAINEDNot measuredOne of the other four shapesNOT TRAINEDNot measuredThe note names four of the six: pull out the entities, pull out the relationships, is this entity one we already have, is this fact a duplicate or a contradiction — and two more.
  • Trained and clean
  • Measured failure
  • Not trained, not separately measured
The memory engine asks for six different answer shapes. The exam graded the student on the single shape its training pairs came from, so five of these six columns were never on the paper.SourcePromotion-canary evidence pack CANARY-2026-08-28.md and CANARY-2026-08-28.json, with the per-arm run files canary-arm-a-canary-27b-20260828.json and canary-arm-b-canary-student-20260828.json and their per-call records.

The pipeline never checks that an answer carries the keys of the question it asked. It parses the JSON, reads the key it wanted, finds nothing there, and moves on. A well-formed JSON object with the wrong keys is not an error anywhere in the stack. It silently becomes "found nothing."

So "100% valid JSON" was never the real bar. It was a number that felt like proof and measured almost nothing. The exam graded the student on its own trained prompt, in a format check the pipeline does not perform, and returned a clean pass on a model that could not run the job. We now grade the shape of every call instead, which is what the canary did.

Benchmarks measure what you ask them. Pipelines demand what they need. When those two drift apart, the benchmark keeps saying yes.

05

The part that redeems it

We tested the obvious excuse. The student's server cannot enforce an answer format, so we had put the required shape in the prompt. Maybe it copied the shape only because we showed it the shape.

So we ran the same real question three ways, five times each. Shape in the prompt: 0 of 5, copied. Shape removed: 0 of 5. Through the incumbent: 5 of 5 correct. The test rig did not cause this.

But look at what the student said with the shape removed:

duplicate_facts=[]
contradicted_facts=[1]

That is the right answer: it spotted that the new fact contradicted the stored one. It knew the answer and could not write it down. A formatting gap, not a thinking gap, and that is the kind we can train out.

06

The fix builds itself

The training data for the missing five shapes already exists. The incumbent answers those questions correctly all day, and nobody was writing them down.

So we put a recorder on the production request path. Every question the engine asks and every answer it gets back is now copied to disk, tagged with which of the six shapes it belongs to.

  • All six shapes were flowing within twelve minutes of install.
  • 56 pairs in the first thirty minutes, about 112 an hour at that rate, zero dropped and zero write errors. 25 of the 56 were the exact shape the student failed 534 times.
  • The install cost 0.44 seconds of downtime, fired at a gap between notes. The note in flight across the restart still finished, with 5 entities and 2 links.

The corpus builds itself while the work runs. The next student trains on the mixed set and faces the same canary. The builder drops any pair whose answer is missing the required keys, which is the gate the canary proved matters.

07

The gate cut both ways

The canary was pointed at the student. It also found things about the system we are replacing, which nobody had measured before.

  • It goes blank. 5 of 25 notes with real content in them came back with zero entities. The fastest refusal took 1.93 seconds. The student extracted from all 25.
  • It is not repeatable. Set to be deterministic, the same note from the same starting state gave 0 entities on one run and 9 on the next.

None of that changes the verdict. A slow engine that finishes 25 of 25 beats a fast one that finishes 1. But we have been filing part of our own backlog as empty, and we would not know it if we had not built the gate to judge the replacement.

08

One line on the other student

A second small model is in training for a different job, capturing facts from finished work sessions. Its 7,026 training pairs were written by a large cloud model that won a five-way audition, scored on how much of its output survived our live validator. Details next post.

09

The open-source part

It is the machinery, not our data: the harvester that turns a running loop's logs into training pairs, the redaction that runs before anything leaves the machine, the dataset builder that de-duplicates and splits them, the LoRA recipe, and the exam harness — whose scorer now takes a list of keys an answer must carry, which is the check this whole post is about. The canary methodology ships with it. Shipping the exam alone would hand you the tool that told us yes when the answer was no.

The pairs stay private, as post one said, and that costs you nothing. Your teacher writes your pairs, from your loops, on your machine.

10

What post three reports

The re-canary verdict for the next student, against the same 25 notes and the same six shapes. And the measured model time per day after deployment, set beside the 4.06 and 8.11 hours projected in post one.