I edited 12 tensors so a 2B model stops saying "Wait", then taught it to say "I'm stuck"
Small reasoning models have a failure mode that eats your token budget: they reach the answer, then keep re-checking it. "Wait." "Hmm." "Actually, let me verify." On my test set, 34 out of 100 tasks never finished inside
Small reasoning models have a failure mode that eats your token budget: they reach the answer, then keep re-checking it. "Wait." "Hmm." "Actually, let me verify." On my test set, 34 out of 100 tasks never finished inside a 4000-token budget, and a lot of the finished ones were long loops of the same check.
I built two models to deal with this. Both are on Hugging Face, both are Apache-2.0, both run in llama.cpp.
Lineage
- Qwen3.5-2B
- Heretic abliteration by saidutta69 (
Qwen3.5-2B-heretic) - Focused: a weight edit (part 1)
- Focused-Honest: a LoRA merged into Focused (part 2)
Part 1: Focused, a weight edit with no training
The idea: if the model "decides" to re-verify before it types "Wait", that decision should be visible in the residual stream.
- I recorded activations right before re-verification phrases ("Wait", "Hmm", "Actually", "verify") and right before ordinary sentences, using 33 reasoning traces.
- The difference between the two sets is an "intent to re-verify" direction in layer 18. A probe trained on "Let's check" also picked up "Wait" (AUC 0.74 and 0.79 in the two directions), so it is not just one token.
- In layers 13 to 18, every weight that writes into the residual stream (
ffn_down, attention output,ssm_outon DeltaNet layers,attn_outputon layer 15) gets the direction removed:
W <- W - 0.75 * d (d^T W)
Only 12 tensors change, each by about 1.6%. No gradient steps, no data, no new layers. The edited weights are re-quantized to Q8_0.
Why 0.75 and not 1.0: at full strength the edit also removed useful self-checking, and the model started giving confident wrong answers. 0.75 was the best compromise I tested.
Results on 100 fresh tasks, 4000-token budget, one sample each, answers checked by code:
| Metric | Before | Focused |
|---|---|---|
| Finished and answered | 52 | 66 |
| Correct (lenient parse) | 49 | 61 (p = 0.004) |
Correct (strict ANSWER: format) |
47 | 56 (p = 0.078) |
| Median tokens per task | 3909 | 2243 |
The 34 unfinished tasks were the same for both versions. Calendar tasks stayed at 0/15: the edit removes needless re-checking, it adds no knowledge.
Part 2: Honest, teaching the model to give up on purpose
Focused still burns the whole budget on problems it cannot solve. I wanted it to stop and say so.
Data. 440 synthetic math and logic tasks across 12 families, written by Claude Haiku with answers computed by code. Two families (logic_grid, word_rate) were held out entirely for evaluation. The base model solved each task 4 times to label it "can't solve", "solves" or "borderline".
Verified dead ends. From each candidate stopping point, the base continued 8 more times (up to 3000 tokens each). A point counted as a dead end only if none of the 8 continuations was correct. This matters: without it, the model learns to quit on problems it could have solved.
757 training examples:
- 304 solve: the model's own correct traces, cut at 1000 to 3000 tokens, then completed
- 179 keep going: points that looked stuck but where a continuation succeeded
- 274 give up: verified dead ends, followed by a short wrap-up ending with
UNSOLVED: <reason>
The wrap-ups were written by a Gemini Flash model that did not see the answer. Endings that gave up on traces already containing the right answer were filtered out. The task prompts mention ANSWER:, CONTRADICTION: and INSUFFICIENT:, but never UNSOLVED:. The model learned that token on its own.
Training. QLoRA (nf4) on bf16 weights, rank 16, alpha 32, layers 8 to 23, 1 epoch, learning rate 1e-4 with cosine decay, batch 8. About 10 minutes on one L40S. Then merge, then Q8_0.
Results (4 seeds per task, 4000-token budget):
| Focused | Focused-Honest | |
|---|---|---|
| Median tokens per attempt | 4000 | 1875 |
| Correct | 27% | 20% |
| Out of budget | 68% | 9% |
On held-out task types the base cannot solve, UNSOLVED went from 0% to 86% and out-of-budget runs from 88% to 7%.
On ARC-Challenge (zero-shot, 4-bit), accuracy moved from 35.67% to 36.86% (McNemar p = 0.038). With several comparisons run, I treat that as a hint, not proof.
What it costs
- On solvable held-out tasks, Honest gives up 29% of the time (10% on trained task types). Overall correctness drops from 27% to 20%.
-
UNSOLVEDexplanations are summaries in the teacher model's style, not verified diagnoses. - Evaluation is narrow: synthetic math and logic (425 English, 15 Russian tasks) plus ARC-Challenge. MMLU and GSM8K are untested.
- Focused was verified on one base model only.
Use Focused if you want accuracy. Use Honest if an explicit "can't solve" is worth more to you than a long unfinished trace.
Run it
llama-cli -m Qwen3.5-2B-Focused-Honest-Q8_0.gguf \
--temp 1.0 --top-p 0.95 --top-k 20 --presence-penalty 1.5
Eval tasks, raw outputs for both models and checksums are in the repo. The Focused edit is reproducible from apply_edit.py plus the direction file.
- Focused: https://huggingface.co/AmaLS367/Qwen3.5-2B-Focused-GGUF
- Focused-Honest: https://huggingface.co/AmaLS367/Qwen3.5-2B-Focused-Honest
- Base I started from:
saidutta69/Qwen3.5-2B-heretic(made with Heretic)
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.