Weight-Space Programming Works: An LLM Fixed Qwen's Math Loop by Editing 0.016% of Its Weights
One hundred thirty-one thousand numbers. That is the entire size of the edit that moved Qwen3.5-0.8B, a small open reasoning model, from 7.9% to 48.1% on MATH-500, from 13.8% to 67.1% on GSM8K, and from 21.0% to 62.3% on
One hundred thirty-one thousand numbers. That is the entire size of the edit that moved Qwen3.5-0.8B, a small open reasoning model, from 7.9% to 48.1% on MATH-500, from 13.8% to 67.1% on GSM8K, and from 21.0% to 62.3% on IFEval, an instruction-following benchmark. No gradient descent was involved, no training data, no fine-tuning run. A frontier model called GPT-6 Astra read the model's raw weights, identified a single direction written by two MLP layers that was trapping the model in repetition loops, and subtracted it. The whole repair touched 0.016% of the network's weights.
The result comes from "Sparks of Weight-Space Programming," a November 2026 research post by Rikiya Takehi, Jayden Teoh, Alex Zhang, and Omar Khattab at MIT CSAIL. The claim behind it is larger than one clever repair: a general-purpose language model, used off the shelf with no task-specific training, can read neural network weights well enough to say what a network was trained to do, and can write weights well enough to beat reinforcement-learning policies trained for hundreds of millions of steps. The post is careful, the logs are public, and the failure cases are reported next to the successes. It deserves a close read, so here is one.
What weight-space programming actually claims
The authors give the idea a precise definition. In weight-space programming, a general-purpose LLM reads and writes a network's weights directly, not through an optimizer, and in particular not with gradient descent, working toward a natural-language specification, sometimes with no environment feedback at all. Three capabilities get tested in turn. Reading: given only the weights, say what the network was trained to do. Fixing: given a failing network, find the cause and repair it. Writing: given a task description, produce a working network from scratch.
The contrast with business as usual is the point. Today, weights are written by symbolic optimizers like Adam or Muon, by secondary networks trained to generate them, or by compilers from formal programs. Humans cannot meaningfully edit a weight matrix by hand, which is exactly why weights have remained the exclusive territory of those algorithms. The post argues this assumption is now breaking: the same reasoning ability that lets a frontier model debug code transfers, at least partially, to the continuous space of network parameters.
Reading weights without running anything
The first experiment is a clean test. Four policies were trained with PPO to play four different games, grid versions of Breakout, Pong, Pac-Man, and Freeway, on the same 10x10 grid with the same five actions and identical architectures: an MLP of shape 500 to 32 to 32 to 5, just 17,253 weights, trained for a billion steps each. Astra received the raw weights as text plus a description of the grid and the actions, without the list of candidate games. It named the right game for all four networks. Its reasoning, summarized in the logs, is the kind a human expert would attempt: the first layer's weights concentrate where each input channel matters, so for Breakout the agent channel's weights lie along the bottom row where the paddle lives, and the output layer separates different actions for different games.
import numpy as np
def weights_as_text(state_dict):
# The experiment-1 setup in one function: hand the model every
# weight as plain text, with the architecture described in prose.
parts = []
for name, tensor in state_dict.items():
arr = np.asarray(tensor, dtype=np.float32).ravel()
parts.append(f"{name} {arr.shape}: " + " ".join(f"{v:.6f}" for v in arr))
return "\n".join(parts)
The second experiment moves to generative models: three small diffusion models trained to draw circles, squares, and triangles on 12x12 grayscale images, 23,824 weights each. Astra named each model's shape from the weights alone, with no tools and no forward passes. The tell that it was reading rather than simulating: it drew every shape as an outline, while the actual models generate filled shapes. It was reading the geometry of the output layer, where each hidden unit's weights trace one segment of an edge, not replaying the network in its head.
The third experiment is the strongest read, and the one most worth your skepticism. Three character-level transformers of 7.16 million parameters were trained on a billion characters each of Python code, romanized Japanese literature, and English Wikipedia. Astra received only the four middle transformer blocks, no input embedding and no output layer, so nothing in what it saw maps any dimension to any character, plus a Python session for analysis and a hard ban on running the network on any input. It named the right language for all three models, in both of its attempts, and it listed every copying head, the induction heads that let a model repeat earlier text, matching the measured ground truth exactly: heads 2.1, 3.1, and 3.5 for Python, 3.3 for romaji, 3.1 for English. To do this it independently re-derived the induction-head analysis from Elhage et al.'s well-known interpretability work, a method nobody mentioned to it. The romaji detail is my favorite in the post: the final block Astra was given writes in fewer distinct directions, exactly what you would expect from an alphabet that never uses q, l, v, or x.
Writing weights that beat trained policies
Reading is a parlor trick if it does not generalize to writing, so the authors escalated. For three MinAtar games, Breakout, Seaquest, and Asterix, Astra received the rules and source code, a fresh network of shape 600 to 32 to 32 to 6 with every weight set to zero, and nothing else: no data, no loss, no gradients, no tools, no rollouts in the environment. It wrote all the weights as text in a single reply. The results, scored over 1,000 episodes each:
| Game | PPO, 100M steps | PPO, 500M steps | Astra, one-shot |
|---|---|---|---|
| Breakout | 15.8 | 25.3 | 517.4 |
| Seaquest | 5.6 | 88.9 | 53.1 |
| Asterix | 25.8 | 55.2 | 53.2 |
Against PPO trained for 100 million steps, the hand-written networks win all three games. Against PPO trained for 500 million steps, they score twenty times higher in Breakout, come close in Asterix, and reach 60% of the trained score in Seaquest. How does it do it? It writes programs in neural form: for Breakout, it assigned the first layer to compute where the ball will land and the second layer to move the paddle to that position. That is not a metaphor. It is a hand-coded algorithm expressed in matrix weights.
The Go experiment then pushes the scale up. The target network for 9x9 Go has 1,480,274 weights, far too many for the context window, so a Python sandbox held the tensors while Astra edited them with numpy, unable to run the network except through a budget of forward passes, each one a batch of up to 128 practice games. With a budget of zero forward passes, meaning a single Python run of 336 lines, the authored network already won more than half its games against two smaller PPO networks. With 50 forward passes, it beat an equal-sized PPO network trained on 20 million games. The program it wrote is recognizable Go: early layers mark each side's stones and their liberties, middle layers propagate along chains to find groups in danger, and the final layer scores each move, capturing here, saving a group there, avoiding self-atari, never filling its own eyes.
The repair experiment sits between reading and writing. A PPO-trained car policy for a Kinetix ramp level, 171,664 weights and a billion training steps, had converged to a local minimum: it drove straight at the ramp and stalled, succeeding zero times in 256 episodes. Given the weights, a description of the scene, and one recorded episode, Astra explained the failure and rewrote 3.5% of the weights in a single reply. The car then succeeded in all 1,024 evaluation episodes. The mechanism it described is surgical: it added a small side path, a few units per layer, that reads the car's position and speed, triggers the back-up-and-accelerate behavior, then switches itself off once the car clears the obstacle so the trained policy drives the rest.
The Qwen repair, number by number
The headline experiment scales the repair to a real language model. Qwen3.5-0.8B, with thinking enabled, is prone to repetition loops; its own model card warns about this. The setup gave Astra a Python kernel over the model's weights with no GPU, practice problems drawn from the GSM8K and MATH training sets (7,469 and 7,275 problems, disjoint from every test set), and a budget of 10, 25, or 50 forward passes, where one forward pass means the model answers up to 512 problems or reads up to 1,024 texts. Training and gradients remained forbidden. Sampling followed the model card exactly: temperature 0.6, top-p 0.95, top-k 20, presence penalty 1.5.
The failure mode was unmistakable once looked for: 85 of the base model's first 96 practice answers ran all the way to the 32,768-token limit, repeating themselves and never reaching an answer. Astra traced the looping to one direction written by the MLPs of layers 15 and 19, and subtracted that direction from 64 output columns in each layer, 131,072 weights in total.
edited = 131_072 # weights changed in the Qwen3.5-0.8B repair
total = 800_000_000 # parameters in the model
print(edited / total) # 0.00016384, i.e. 0.016% of all weights
The measured outcome, on benchmarks Astra never saw:
| Qwen3.5-0.8B | MATH-500 | GSM8K | IFEval | Hit token limit |
|---|---|---|---|---|
| Base | 7.9% | 13.8% | 21.0% | 93.0% |
| Edited, 50 forward passes | 48.1% | 67.1% | 62.3% | 33.1% |
The loops are not specific to math, so the gains are not either: IFEval, which measures instruction following, nearly tripled. Lower budgets barely helped, since at 10 or 25 forward passes the loops mostly survived, which is itself useful information about how much interaction this kind of repair currently needs.
# Schematic of the repair Astra described for Qwen3.5-0.8B: the MLPs in
# layers 15 and 19 each write one "looping" direction, and the edit
# subtracts that direction from 64 output columns per layer.
for layer in (15, 19):
W_out = blocks[layer].mlp.weight # output side of the MLP
d = looping_direction[layer] # the isolated direction
W_out[:, columns] -= d[None, :] # 64 columns, 131,072 weights
The two failures that make the results believable
The post earns unusual credibility from its negative results. In the sycophancy experiment, two copies of Gemma 3 270M were fine-tuned identically, one to answer correctly and one to always agree with the user's suggestion, with embeddings and output layers frozen so the input-output distributions stay identical. From the weights alone, Astra failed: across four attempts it found many weight differences but could not map them to behavior. Only when the authors relaxed the setup, letting Astra write up to 16 texts of its choosing and inspect only the attention patterns of both models, never their outputs, did it identify the sycophant, correctly, in all three pairs. Its explanation was mechanical: in the sycophant, middle-layer heads shift attention from the question's content to the user's suggested answer. One head, 10.2, moves from spending 94.3% of its attention on the question's numbers in the honest model to spending 85.7% on the user's guess in the sycophant.
The second failure is the control experiment everyone should cite. Gemma 3 270M rarely loops, only 8.5% of its answers hit the token limit, so the authors asked Astra to simply make it better at math. It could not. Reading its failures, Astra found ordinary reasoning errors, wrong arithmetic and invalid algebraic steps, with no single component responsible for them. Its edits stayed small and targeted, and none moved MATH-500 by more than about a point, a gain Astra itself reported as not established. The boundary this draws is the most important sentence in the post: editing weights can remove an obstacle that hides an ability, but it cannot add an ability the model lacks.
How this compares to fine-tuning and interpretability
Against fine-tuning, the Qwen repair wins on three axes and loses on one. It needed no training data and no gradient pipeline; it touched 0.016% of the weights, which sidesteps the catastrophic forgetting that broad fine-tuning invites; and the improvement generalized sideways to instruction following instead of trading one capability for another. What it loses is reliability and cost structure: the repair worked because the failure happened to have a single-direction cause, and 50 forward passes through up to 512 problems each on a frontier model is not free, merely cheaper than a training run.
Against mechanistic interpretability, the shift is one of reader, not target. The field has built excellent purpose-built tooling, from probes to circuit tracing to feature dictionaries, and more recently has trained models to read activations or explain single neurons. What is new here is that the reader is a general-purpose frontier model with no interpretability-specific training, working in natural language over raw tensors, and reproducing a known research method on its own. The sycophancy negative result matters here too: pure weight reading has a ceiling, and pairing the reader with a lightweight behavioral probe, the attention tool, is what broke through it.
Against reinforcement learning, the from-scratch results are genuinely startling at small scale: one-shot authored weights beating PPO at 100 million steps in three games, and beating a 20-million-game PPO run in Go with 50 forward passes. But note the parameter counts, 17 thousand to 1.5 million. Nobody wrote a 0.8-billion-weight model from scratch; the language-model result is a repair, not an authorship. Extrapolating the writing results to frontier scale is speculation the authors themselves decline to make.
What to watch if you run open models
The authors list the applications plainly, and each is worth tracking as an engineering direction rather than a shipped product. Auditing without evaluation: reading hidden behaviors, backdoors or deceptive circuits, directly from weights, without needing a test set that anticipates them. Zero-data steering and unlearning: removing a capability by editing a handful of weights instead of collecting data and fine-tuning, with the rest of the model left intact. Targeted hotfixes: the looping repair is exactly the shape of bug that currently forces a retrain or an embarrassed system-prompt patch. And true model merging: grafting a circuit from one model into another of a different architecture, instead of averaging weights, which only works between identical twins.
The near-term checkpoint for all of this is public. The authors are building a benchmark and harness for weight-space programming, and they have released complete logs, every prompt, every reasoning summary, every piece of code, every network, and every evaluation, at github.com/RikiyaT/lm_understand-logs. The stated bottlenecks are context length and harness efficiency, and the stated scope is early. If the logs hold up under community re-runs, this is the beginning of a real engineering discipline; if they do not, it was still the most interesting negative result of the month. Either way, the honest move for practitioners is the same: watch the benchmark, try the harness when it lands, and keep your training pipeline warm.
Originally published on Dispatch.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.