Between 23 October and 1 November we trained seventeen models to read our threat-intelligence graph like an analyst. We spent $448 on rented GPUs (RunPod billing). The model we now trust most was not one of them. It is an open model we did not train at all, Qwen3.8-27B, with one rewritten sentence in its instructions. On our main exam it scores 197 of 200. Our best fine-tune scored 188.
This note is about why, because the reason applies to anyone fine-tuning a model to be careful.
The job
Our graph holds the facts: threat actors, malware, vulnerabilities, ransomware victims, each with a date and a source. When someone asks a question, the graph assembles a dossier (the lines about that entity), and the model answers from the dossier only. If the answer is not there, the correct reply is exactly: "The dossier does not say."
So the model never has to remember a fact. It has to do three things: find the line, quote it, and refuse when the line is not there. (Why we stopped asking the weights to remember.)
The seesaw every model sits on
Two of our eight exams pull against each other:
- Blind refusal. We remove the answering line from the dossier. Does the model say "the dossier does not say", or does it invent? Bar: 0.95.
- Indirect. The answer is there, but under an alias, another spelling, a different case or another label. Does the model still find it? Bar: 0.65.
Train a model to refuse more and it starts refusing answers that were there all along. Our fine-tunes slid up and down that edge for a week. The gpt-oss-20b runs learned discipline (invented words fell from 32 % of answers to 0.4 %), and then run after run missed a bar: refusal too low, or refusing too much. On 30 October a blend of runs 14 and 15 finally cleared every bar of the day, at 188 of 200 and refusal 0.964.
The bake-off
On 31 October we stopped training and measured nine open models untrained, through the same dossier pipeline and the same judge:
| Model (untrained) | Hand-written 200 | Blind refusal | Indirect |
|---|---|---|---|
| Nemotron 3.5 Super 120B-A12B | 196 | 0.849 | 0.805 |
| Qwen3.8-27B | 193 | 0.957 | 0.784 |
| Muse Glimmer 30B | 190 | 0.948 | 0.745 |
| gpt-oss-120b | 189 | 0.817 | 0.726 |
| our trained blend, for reference | 188 | 0.964 | 0.695 |
Untrained Qwen beat our trained blend on the exam that matters, and was the only untrained model at or above the refusal bar. Nemotron Super read best but refused too little. More careful is not the same as better, and neither is bigger.
The fine-tune that lost to its own base
Run 17 trained Qwen3.8-27B itself on our audited set. It failed on indirect. Then we ran the untrained Qwen again, this time with the exact refusal sentence our production service uses, and it failed the same bar: indirect fell from 0.784 to 0.647, under the 0.65 line.
That was the finding. The sentence was pushing the model to refuse, not the training data. Our served instruction told the model to quote verbatim and refuse if the fact was missing. It never told the model that a fact can be written under another name. So a careful model, reading "LOCKBIT" when asked about LockBit, decided the fact was missing.
W1: one sentence
We wrote a new version, called W1, and changed nothing else:
Quote the dossier verbatim: copy the exact names and lines, never paraphrase, never add anything that is not in the dossier. The fact asked for may be written under another name, spelling, case or label: check every line before deciding. Only if no line of the dossier gives the fact, answer exactly: The dossier does not say.
The pass marks were written down before the run (2 November, about 15:35 UTC). One shot, eight bars:
| Bar | Need | W1 | Old sentence |
|---|---|---|---|
| Hand-written 200 | ≥ 190 | 197 | 193 |
| Blind refusal | ≥ 0.95 | 0.968 | 0.982 |
| Indirect | ≥ 0.65 | 0.705 | 0.647 fail |
| Leak (invented names) | ≤ 1.0 % | 0.4 % | 0.4 % |
| Held-out recall | ≥ 0.80 | 0.876 | 0.840 |
| Hard set | ≥ 85 | 100 | 99 |
| Sector exam | ≥ 0.98 | 0.988 | 0.992 |
| Vulnerability exam | ≥ 0.98 | 1.000 | 1.000 |
Eight of eight. It cost about $1.19 of GPU time. The thinnest margin is refusal (95 % interval 0.94 to 0.98), and we say so on the scoreboard. The next day it passed the live gate as well: 197 of 200 and 78 of 90 turns right across 30 multi-turn dialogues, on the serving stack with live settings.
What we take from it
- Measure the untrained model with your production prompt before you train. We measured base models with a weaker probe line, so the baseline flattered them and hid the real cause for days.
- Over-refusal is often an instruction bug. If a model refuses answers that are present, read your system prompt as the model reads it. Ours never said a fact could carry another name.
- Training still has a job. It taught the 20b discipline it did not have. It is now aimed at what a sentence cannot fix: data only we hold. The next training run has to beat 197 with W1, not the old baseline.
The full scoreboard, the trade-off chart and the timeline are on Project M&M. Every question and every miss is on the 200.