Where tiny models compare two texts, and what fools them
The full run ended with three open questions. Do the attention heads I found cause the comparison? Why does rewording fool the internal judge? Does it survive quantisation? Quick answers: in the LFM models a whole attention layer compares, not a few heads; a number written another way ("1750 dollars" against "$1,750") fools every model more than a reworded sentence does; and the direction carries over from Q8_0 to Q4_0.
The setup
Everything builds on the full run: same four models (LFM2.5-230M Q6_K, LFM2.5-350M Q5_K_M, Qwen3-0.6B Q8_0, Qwen3.5-0.8B Q8_0), same machine, llama.cpp b11946, greedy, thinking off. For each model I kept what the full run fitted on its 1,024 tune checks, and didn't refit anything: the "texts differ" direction, the layer the judge reads (8, 8, 16 and 13), and its threshold. So every number below tests that fixed judge on new conditions.
Switching heads off. My probe tool already sees the attention weights through llama.cpp's eval callback. It can now also zero a head's weights there, for every position, before the next step uses them: the head then contributes nothing. Before trusting it I checked that it does what it should: with all 16 heads of the 230M's layer 8 off, the internal state of layers 0 to 7 stayed bit-for-bit identical, layer 8 onward changed by 17 to 38%, and the output scores by up to 9.6. One head off changed them by 1 to 10%.
1. Heads off: a whole layer compares, not three heads
100 held-out checks (25 each: wrong in the same wording, wrong and reworded, right copy, right reworded). In the layer where the full run found the comparing heads, I switched off the 3 heads with the highest AUC, the 3 with the lowest, 3 random others (two draws, both shown), or all of them. The number is the AUC of the judge's direction afterwards, at the layer the judge reads (0.5 = no signal):
| AUC | none off | top 3 | weakest 3 | random 3 | whole layer |
|---|---|---|---|---|---|
| 230M, L8 | 0.877 | 0.863 | 0.876 | 0.874 / 0.844 | 0.573 |
| 350M, L8 | 0.938 | 0.925 | 0.929 | 0.900 / 0.936 | 0.598 |
| 0.6B, L15 | 0.953 | 0.928 | 0.962 | 0.958 / 0.952 | 0.850 |
| 0.8B, L11 | 0.974 | 0.962 | 0.979 | 0.970 / 0.980 | 0.965 |
My prediction was that the top 3 would matter clearly more than random ones. Wrong, in different ways per model:
- The LFM models compare in the whole layer. Any 3 heads off, top or random, leave the 230M and the 350M at 0.84 to 0.94. All 16 off and the signal is nearly gone (0.57 and 0.60). Many heads do a share; no few of them are needed.
- Qwen3-0.6B leans on its top heads a little. Its top 3 off gives 0.928, below every control (0.952 to 0.962), so those heads do carry more than others. But even the whole layer 15 off only brings it to 0.850: the 0.6B has attention in all 28 layers, and other layers keep most of the comparison going.
- Qwen3.5-0.8B doesn't need that attention layer at all. Whole layer 11 off: 0.965. This model is a hybrid: three of
every four layers are a linear kind of attention (DeltaNet-style; llama.cpp builds them as
delta_net), and only every fourth is classic attention. In the full run its direction already jumped in layers 9 and 10, which are linear layers. So its comparison most likely happens there, and the classic heads I found only look along. That's my reading, not yet tested.
One thing that almost misled me: the judge's accuracy fell a lot in several of these runs (the 230M with a random 3 off: 50%, from 80%), while its AUC barely moved. Switching heads off shifts every score by about the same amount, so a fixed threshold lands in the wrong place, but the separation is still there. AUC is the right measure for "does it still know".
2. What fools the judge: numbers written another way
The full run showed the judges reject some right texts that are reworded. To see which rewording does it, I wrote 100 new right texts, 25 of each kind:
- copy: the same text,
- phrasing only: another sentence shape, numbers written the same ("The hiring team now meets on Friday at 3:30 pm in room 6A." against "New slot for the hiring meeting: Friday, 3:30 pm, room 6A."),
- format only: the same sentence, a number, date or time written another way,
- both.
| the fixed judge accepts | copy | phrasing only | format only | both |
|---|---|---|---|---|
| LFM2.5-230M | 100% | 96% | 64% | 72% |
| LFM2.5-350M | 100% | 76% | 56% | 52% |
| Qwen3-0.6B | 100% | 88% | 68% | 84% |
| Qwen3.5-0.8B | 100% | 96% | 76% | 68% |
I expected a new sentence shape to be the hard part. It isn't, in any of the four models. The hard part is a value written another way. The format-only pairs rejected by the most models (of 4):
- "at 4:30 pm" against "at 16:30": rejected by all 4
- "1750 dollars" against "$1,750", "USD 1,430" against "1430 dollars", "at 13:00" against "at 1:00 pm", "shipped on 3 August" against "shipped on August 3": 3 of 4 each
- even "at 3:00 pm" against "at 3 pm": 2 of 4
My guess at the mechanism: the internal comparison works on tokens, and the same amount in another format is made of different tokens, so it looks like a changed number. The full-run data agree in part: on its 440 reworded right texts per model, the fewer words the two texts share, the more the judge leans toward "differs" (rank correlation −0.33 for the 350M, −0.28 for the 230M, −0.27 for the 0.8B, −0.13 for the 0.6B). That's a moderate pull, not the whole story.
The 350M is the weakest in every reworded group, which fits the full run, where it accepted only 62% of reworded right texts. Now I know where that comes from: every kind of rewording costs it, and number formats cost it most.
3. Quantisation: the direction carries over
Only one model has two quantisations on disk here, Qwen3.5-0.8B in Q8_0 and Q4_0. On the same 100 held-out checks:
| Qwen3.5-0.8B | judge right | AUC |
|---|---|---|
| Q8_0, the full run's fit (1,024 tune checks) | 94% | 0.974 |
| Q8_0, fitted on 100 tune checks only | 94% | 0.975 |
| Q4_0, with the Q8_0 direction | 88% | 0.952 |
| Q4_0, fitted on its own 100 tune checks | 92% | 0.959 |
The direction found in the Q8_0 file still works on the Q4_0 file, losing about 0.02 AUC and 6 points of accuracy; fitted on its own, Q4_0 is 2 points behind Q8_0. Every fit picked layer 13, even from 100 checks. Both files' spoken answers are still PASS (50% right). The other models' other quantisations aren't on this machine, so for now this is one model.
Predictions against results
| I predicted | Result |
|---|---|
| Top 3 heads off lower the AUC clearly more than random 3 | Wrong for three models; slightly true for Qwen3-0.6B |
| The whole layer off lowers it most | Right for three; not for Qwen3.5-0.8B (0.974 → 0.965) |
| Copies accepted ≥ 95% everywhere | Right (100% in all four) |
| Phrasing hurts more than number format | Wrong in all four |
| The 350M lowest in every reworded group | Right |
| The Q8_0 direction works on Q4_0 within 0.05 AUC | Right (0.022) |
What I take from it
- Where the comparison happens differs by architecture. The LFM models do it in one attention layer as a team; the Qwen3 spreads it over layers; the hybrid Qwen3.5 seems to do it in its linear layers. "Find the comparing heads" was too narrow a question.
- The judge's blind spot is formatting, not wording. That's useful: number formats are easy to normalise with code before the check ("$1,750" and "1750 dollars" both become 1750). A cheap fix might close most of the gap; that's the next thing to test.
- One fit per model seems to survive quantisation, at least from Q8_0 to Q4_0 on one model, and 100 labelled checks are enough to fit it.
Next
- Normalise number, date and time formats in both texts before the check, and see how much of the rewording gap closes.
- Switch off the 0.8B's linear layers 9 and 10 instead of its attention, to test where it compares.
- Repeat all three tests on more checks, and on the other models' quantisations once they're on disk.
The data
2026-11-02-internals-next.csv: one row per run (test A settings, test B per model, test C variants) with the AUCs at the judge layer and the last layer, the judge's, threshold's and answer's accuracy, and for test B the acceptance per kind of rewording.
How far to trust it: 100 checks per setting, one run each (greedy decoding, so a rerun gives the same numbers, but other checks would differ); 25 per rewording type, so a difference of one check is 4 points. The big effects (whole layer off: 0.88 → 0.57; format-only 56 to 76% against copies 100%) are well outside that; the differences between top-3 and random-3 heads are within it, except for Qwen3-0.6B, where the top 3 are below all three controls.