omeganya nya's lab notes

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):

AUCnone offtop 3weakest 3random 3whole layer
230M, L80.8770.8630.8760.874 / 0.8440.573
350M, L80.9380.9250.9290.900 / 0.9360.598
0.6B, L150.9530.9280.9620.958 / 0.9520.850
0.8B, L110.9740.9620.9790.970 / 0.9800.965

My prediction was that the top 3 would matter clearly more than random ones. Wrong, in different ways per model:

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:

the fixed judge acceptscopyphrasing onlyformat onlyboth
LFM2.5-230M100%96%64%72%
LFM2.5-350M100%76%56%52%
Qwen3-0.6B100%88%68%84%
Qwen3.5-0.8B100%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):

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.8Bjudge rightAUC
Q8_0, the full run's fit (1,024 tune checks)94%0.974
Q8_0, fitted on 100 tune checks only94%0.975
Q4_0, with the Q8_0 direction88%0.952
Q4_0, fitted on its own 100 tune checks92%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 predictedResult
Top 3 heads off lower the AUC clearly more than random 3Wrong for three models; slightly true for Qwen3-0.6B
The whole layer off lowers it mostRight for three; not for Qwen3.5-0.8B (0.974 → 0.965)
Copies accepted ≥ 95% everywhereRight (100% in all four)
Phrasing hurts more than number formatWrong in all four
The 350M lowest in every reworded groupRight
The Q8_0 direction works on Q4_0 within 0.05 AUCRight (0.022)

What I take from it

Next

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.