Gemma-3-4B · chatbot
Writes a biography for a person who doesn’t exist
→ of made-up names get a fake bio · of normal answers unchanged
Notes from a week of weight editing · November 2026
I took four open models that each have one specific, annoying bug and fixed it by editing the weights directly: a few thousand numbers, no training. Most of what else the models say stayed the same, word for word.
Gemma-3-4B · chatbot
→ of made-up names get a fake bio · of normal answers unchanged
Qwen3-4B · agent with a shell tool
→ of attacks work · of real tool calls unchanged
Gemma-3-1B · chatbot
→ of answers end in filler · of the answer text kept
Whisper-small · speech to text
→ of non-speech clips get words · of real transcripts unchanged
Held-out examples, verbatim, greedy decoding. Each fix is about numbers in the model file. More examples per bug in section 3.
Same four bugs, every fix side by side
How often the bug still happens on held-out prompts (lower is better). “LoRA” is a fine-tune on the same practice prompts the edit was built from; “random edit” changes the same number of weights at random. Full breakdown in the scoreboard.
On November 2, an MIT CSAIL team posted Sparks of Weight-Space Programming. They had GPT-6 Astra read a small model’s raw weights and edit 0.016% of them. Qwen3.5-0.8B went from 7.9% to 48.1% on MATH-500, with no training. Reddit and the tech press split into two camps within a day:
If you can do it en masse then you have a form of recursive self improvementr/accelerate
man, scary times are ahead.r/MachineLearning
Singularity here we come?r/LocalLLaMA
Like gene editing for neural networksVentureBeat headline
That’s the refusal ablation recipe, pointed at looping instead.r/Qwen_AI
It’s not a breakthroughr/AIBubble
Its nothing burger news.r/tech_x
Critics say its biggest result relied on standard ML engineering.R&D World headline
I spent the week testing which camp is right. Claude Opus did the editing in agent sessions, on models from a 37k-parameter toy up to 4B chat models. Then I rebuilt the part that worked as a small open framework and compared it with the thing both camps skip: plain fine-tuning (LoRA) on the same examples.
Short version
Given only the weights and tools, the agent usually worked out what the network was doing without being told where to look. Blind runs found the same mechanism 3 out of 3 times on Whisper, language mixing and ResNet.
If training keeps going after the edit, the optimizer undoes it.
The edit gives a head start, then falls behind for good.
Grokking a+b mod 97 (2-layer MLP). Held-out accuracy after the agent’s edit, vs plain training and random edits of the same size. Seed 0.
Each line is one training run from the same checkpoint. 95% counts as solved. Hover or tap for values.
Same story in all four experiments: training rebuilds whatever the loss wants, and weight decay wipes out what no gradient defends. A model editing itself mid-training is fighting its own optimizer.
| Experiment | What the edit gave | Left after more training | Peak lead → at end |
|---|
Most deployed models are frozen, and they have specific bugs you can see. So I dropped the optimizer and used one recipe for every bug, taken from what the blind agents found on Whisper.
The edit rewires one neuron to read “this name is made up” and write “Sorry”.
Step through what the edited neuron does. Switch to a real name and it stays silent.
The neuron’s input weights are a probe direction d. If d·x clears the threshold θ, its output weights raise the logit of “Sorry”. Scores here are illustrative; the real distribution is in the next figure. Layer , unit .
The model already knows: made-up names score far above anything else it reads.
The edited neuron’s score on held-out prompts, relative to its threshold.
Each curve is a histogram. The neuron only fires right of the threshold line; everything left of it is untouched.
Held-out data with new phrasings. Every fix only saw practice data. “LoRA” is a fine-tune on exactly the same practice prompts.
What did each fix break?
Top left: how often the bug still happens (lower is better). Top right: share of normal outputs that come out exactly as before (higher is better). Below: the task’s own “kept” check, drift on normal inputs (KL, log scale) and how many weights were touched.
Same input, four fixes. Read the actual outputs.
Held-out items: cases the weight edit fixes, one where the cheap fix breaks a real answer, and its misses. Verbatim, greedy decoding.
Tabs switch between the unmodified model, the cheap fix (system prompt, or tuned decoding thresholds for Whisper), the weight edit and the LoRA fine-tune. ✓ / ✗ is the task’s own scorer. Whisper audio is the first ≤8 s of each clip; transcripts are for the whole clip. Sources and licences.
ResNet-50, a standard image classifier, learned shortcuts from its training photos. A face in a car means seat belt, underwater means snorkel, snow means snowplow. Spurious ImageNet is a benchmark of photos that show only the shortcut and not the object. Three blind Claude Opus sessions found these shortcut channels from the weights alone and turned them down in the last layer. Below is session 2’s edit (5,000 numbers) on held-out benchmark photos, plus real photos of the same objects.
The edit stops the model naming objects that aren’t there. Sometimes it breaks a real one.
ResNet-50 (ImageNet). The big number is how sure the model is of the shortcut word, before and after the agent’s weight edit. Held-out photos the agent never saw.
ImageNet has no class for “a woman in a car” or “a snowy street”, so after the edit the model often has no right answer to give. It falls back to the next-nearest class, sometimes another shortcut (snowplow becomes snowmobile). Overall ImageNet accuracy went from 62.9% to 62.3%. Fine-tuning the last block on the same few photos removed more shortcuts but cost 12 points on the repaired classes. Same pattern as the text bugs: with about 40 labelled photos per class, standard last-layer retraining (DFR) was cleaner than the edit.
Maybe the edit only beats LoRA because LoRA had too little data. So I varied the data.
With a handful of examples the weight edit wins. With lots of data, LoRA does.
Weight edit vs LoRA refit on subsets of the practice data. Lines are the mean over seeds; bands span min–max.
x is the number of labelled practice examples (log scale). Hollow points on a dashed line are extra-data runs. Dashed horizontal lines are the unmodified model and the cheap fix.
--theta-q 0.999) brings the edit to , ahead of LoRA’s (picked on a subset, checked once on the full set).Every LoRA checkpoint has more side effects than every weight edit, at any fix level.
Made-up names task. The weight edit at 5 write strengths vs LoRA stopped at 6 points in training; same practice data.
Bottom-left is best: fewer fake bios, fewer side effects. Hover for details.
If you have the data and don’t mind a model that’s a bit different everywhere, train. If you need this one behaviour fixed and nothing else touched, editing the weights is the better tool.
I fine-tuned the last four layers on ordinary chat data, the kind of thing anyone downstream does, and watched the fix.
The weight edit is gone within 20 steps of unrelated fine-tuning. The LoRA fix lasts a bit longer.
Made-up names (Gemma-3-4B): fake bios on held-out prompts as fine-tuning continues.
Does the edited neuron still fire on made-up names?
“Chat” = normal instruction data. “Conflict” = chat mixed 1:1 with the model’s own fake bios. Lower is better.
The edited neuron’s own weights barely move (cosine with the edit). The layers below it shift, and it stops receiving the signal it was built to read. The LoRA fix is half gone after 50 steps and fully gone by 100.
Gemma caves 80% of the time when asked “Are you sure?”, but its sense of “I was right” is weak (probe AUC ≤ 0.70). There’s nothing to act on.
Qwen and Llama barely invent bios ( on Llama). Forcing the edit on anyway made Llama loop “Sorry,SorrySorry…” until I added --silence-after-fire.
Chinese leaking into German, Russian and Thai answers can start at any token. A one-neuron edit didn’t help. The agents’ own edit, a context-gated penalty on Chinese tokens, did: → .
Phi-3’s over-refusal uses the same direction as its real refusals. Edits halve false refusals but cost 5–10 points of correct ones.
Made-up names answered with a fake bio (held-out %); facts kept on real entities in brackets.
Leak = answers with Chinese script (held-out). Unchanged = normal chat answers word-for-word identical.
Models really can read weights. Blind sessions found the same mechanism 3 out of 3 times on Whisper, language mixing and ResNet.
Writing doesn’t stick. In my test, 20 steps of ordinary fine-tuning erased the edit. That’s a sticky note on a frozen model, not self-improvement.
Much of it is classic interpretability: probes, steering, ablation.
Classic still fixed four real bugs while leaving most other outputs unchanged (69–100% of normal outputs, depending on the bug), and you can say exactly when it fires and what it writes.
I wrote the recipe above. So I gave Claude Opus the made-up-names task blind: practice data, tools to read activations and write weights, no gradient descent, about an hour.
On its own, the agent got about a third of the way. The hand-tuned recipe gets most of the way.
Made-up names (Gemma-3-4B), same held-out set as the scoreboard.
Session details: results/entity/agent_sessions.
git clone https://github.com/kevinpl07/weight-patching && cd weight-patching && pip install -r requirements.txt python -m patchkit.run all entity # data → base → probe → weight edit + random edit → LoRA → eval python -m patchkit.run sweep entity # weight edit vs LoRA as data grows
A fresh copy on a different GPU reproduces the numbers within noise (REPRODUCTION.md). A new bug is one file: ADDING_A_TASK.md.