Weight-space programming
Can forward passes train a small model on a whole dataset?
Training a model means gradients. Each example goes forward through the model, the error goes backward, and an optimiser nudges every weight a little. We asked whether a model can learn a dataset without any of that.
Our method uses forward passes and least squares only. It adds new neurons to the model and computes their weights in closed form, one layer at a time.
The model is Qwen3.5-0.8B. We trained it on five text-classification benchmarks, from 2 labels to 151, with up to 20,000 training texts each. We compared it with one epoch of LoRA, a common way to fine-tune with gradients.
The answer is yes, nearly. On TREC and Banking77 the edited model comes within 2.1 points of LoRA. On SST-2, AG News and CLINC150 it trails by 3.0 to 5.2 points. On every benchmark it keeps about 99% of the model’s next-token guesses on ordinary text unchanged.
TREC · 6 labels · 5,452 training texts
SST-2 · 2 labels · 6,920 training texts
AG News · 4 labels · 20,000 training texts
Banking77 · 77 labels · 9,993 training texts
CLINC150 · 151 labels · 18,350 training texts
Test accuracy of Qwen3.5-0.8B on five benchmarks. “Forward passes” is the better of our two edits on each benchmark.
The method
New neurons, fitted by least squares, one layer at a time
Every layer of the model ends with an MLP. Its neurons read the residual stream, and each writes back into it. A new neuron is one more row in two input matrices and one more column in the output matrix.
We give the model a prompt that names the labels, then the text, then “Label:”. The new neurons must fire at that last position and stay quiet everywhere else. Training takes four steps per layer.
1. Read
One forward pass per training text. We keep a layer's MLP input at the position where the label goes.
2. Gate
Least squares finds a direction that is +1 at that position and −1 at every other position and on ordinary text.
3. Fit
Thousands of new neurons each read the input in a different random way. Ridge regression maps their outputs to the label.
4. Write
The fit becomes the neurons' output weights, which write toward each label's first token. Then the next layer is read again.
Each new neuron multiplies two readings of its input. Together, thousands of them give the regression curved features, not only straight ones. A gate shuts every neuron off away from the label position.
Two numbers remain to choose: the ridge penalty and the strength of the write. We choose them on a tenth of the training texts held aside. Each choice must leave at least 99% of next-token guesses unchanged on Wikipedia text that the fit never saw.
In the last layer, every candidate can be scored exactly from numbers already collected. In earlier layers, the later layers reshape what a neuron writes, so we check each candidate with real forward passes.
The result
Within about two points of LoRA on two benchmarks, three to five behind on three
| Benchmark | Unedited | Last layer | Four layers | Best readout | LoRA, 1 epoch | Text unchanged |
|---|---|---|---|---|---|---|
| TREC | 15.0% | 92.4% | 95.2% | 97.2% | 97.0% | 99.04% |
| SST-2 | 50.1% | 86.6% | 88.7% | 91.9% | 93.9% | 99.42% |
| AG News | 25.3% | 90.0% | 88.9% | 92.3% | 93.0% | 99.20% |
| Banking77 | 16.8% | 85.7% | 90.8% | 93.8% | 92.9% | 98.99% |
| CLINC150 | 10.5% | 83.1% | 88.6% | 90.6% | 92.1% | 99.24% |
Test accuracy on each benchmark’s test set. “Last layer” and “Four layers” are new neurons written into the model, with no gradients; the better of the two is coloured. “Best readout” is a least-squares fit on the frozen model’s cached activations, not written into the model. “Text unchanged” is the share of next-token guesses on held-aside Wikipedia text that the four-layer edit leaves the same.
The unedited model knows the label names from the prompt and little more. It scores 15% on TREC and 10.5% on CLINC150.
Neurons in the last layer alone lift every benchmark above 83%. Neurons in four layers, fitted in turn, add 2.8 points on TREC, 2.1 on SST-2 and 5.1 on Banking77 and 5.5 on CLINC150. On AG News they cost 1.1 points.
The best edit reaches 95.2% on TREC, against 97% for LoRA. On Banking77 it reaches 90.8%, against 92.9%.
The ceiling
What the frozen model already knows sets the limit
Before writing anything into the model, we fitted the labels directly from its cached activations. This readout may use every layer and the average over the whole text. An edit at the label position cannot read the average.
On Banking77 the readout scores 93.8%, above LoRA’s 92.9%. On TREC it ties LoRA. On SST-2, AG News and CLINC150 it stays 0.7 to 2 points under LoRA. There, gradients change the model’s features themselves, and least squares on frozen features cannot.
The gap between our edits and the readout is the cost of the gate and of reading only the label position. It is 2.0 to 3.2 points. Closing it is the next piece of work.
The rest of the model
Ordinary text keeps 99% of its next-token guesses
A trained model should still be the same model on everything else. We measured this on 100 Wikipedia paragraphs from WikiText-2 that no fit ever saw.
The four-layer edits leave 98.99% to 99.42% of next-token guesses unchanged. A LoRA fine-tune changes every weight it touches on every input.
The measurement had one trap. Appending neurons to the bf16 weight matrices changes how their sums round. In layer 12, 4,096 neurons that write exactly nothing already change 1.3% of guesses. We therefore run the new neurons as a separate block whose output is added to the MLP’s. That is the same function, and the original computation stays bit for bit the same.
The cost
No backward pass, no optimiser, and a patch on a shared model
Training is forward passes and matrix solves. The memory needed is what the model needs to run, plus the collected activations.
It is not yet faster than LoRA. With the long prompt that names the labels, the four-layer edits took 2.6 to 39 minutes on one RTX 3090. The longest was CLINC150, whose prompt lists 151 labels. One epoch of LoRA took 1.7 to 5.2 minutes on the same card. Most of our time is forward passes over the training texts, once per layer and once per candidate strength.
The result is the base model plus a patch of new neurons. Many patches can share one copy of the base model, each added when its request arrives.
Try it
Train it on your own examples
The try page trains the same model on labels and examples you give it. It holds a fifth of your examples back and scores the edited model on them, against the unedited model and random neurons of the same size.
With fewer than 500 training examples, it puts neurons in the last layer only. Below that size, strengths for the earlier layers are chosen on too few examples to trust.
Try it yourself
Can your labelled examples train the model?
- Two tasks recorded and free to look at, a support inbox and home-assistant requests
- Your own labels and examples, five to sixty a label
- A scorecard on examples the fit never saw, against the unedited model and random neurons
Three runs free, then 5 cents a run.
Train on your examples- Qwen3.5-0.8B in bf16. Its 24 layers are counted from 1. The four-layer edits use layers 12, 16, 20 and 24.
- The datasets are TREC (coarse, 6 labels), SST-2, AG News, Banking77 and CLINC150 (the “plus” version, with its out-of-scope label). AG News uses a fixed random 20,000 of its 120,000 training texts. CLINC150 trains on its train and validation splits together. Every score is on the full test split.
- Accuracy is the share of test texts whose most likely label token, among the labels’ first tokens, is right. Each label is given a different first token. On 200 test texts per benchmark, greedy generation agreed with it.
- The last-layer edit has 8,192 neurons. The four-layer edit has 4,096 in each of the first three layers and 8,192 in the last. A layer whose candidates did not beat the layers before it got none.
- LoRA has rank 16 on every linear layer and a linear head on the last position. It trains for one epoch with AdamW at a learning rate of 2e-4. Each count in this post is from one run with seed 0.
More head-to-head evals
| Measure | GLM-5.3 | DeepSeek V4.1 Flash |
|---|---|---|
| Right, of 75 | 75 | 71 |
| Seconds a question, median | 3.9 | 1.8 |
| Measure | First run | Best since |
|---|---|---|
| Landscape, seconds | 937 | 233 |
| Memo, seconds | 759 | 602 |
| Measure | Qwen3 235B | GLM-5.2 | Gemini 3.8 Flash | Claude Opus 5 |
|---|---|---|---|---|
| Seconds to the plan, median | 27 | 48 | 57 | 94 |
| Plans written, of three runs | 2 | 3 | 3 | 3 |
| Measure | SubQ | jev | Decider | Nimble |
|---|---|---|---|---|
| Found, mean of five columns at section length | 64% | 65% | 66% | 68% |
| Mechanism of action, found at section length | 57% | 51% | 61% | 54% |
| Measure | ask | Apollo | treg |
|---|---|---|---|
| Usable leads | 13 of 40 | 7 of 40 | 6 of 28 |
| Cost per usable lead | $0.037 | $0.27 | $0.23 |
| Measure | ask with jev | ask with Decider |
|---|---|---|
| Questions right, of 92 | 89 | 89 |
| Wrong answers | 1 | 2 |
| Measure | jev | ask |
|---|---|---|
| Our 370 clinical decisions, right | 94.6% | 93.0% |
| PubMedQA, right (best EdgeEvals scored: 62.2%) | 77.0% | 74.4% |
| Measure | ask | Claude Opus 5.5 |
|---|---|---|
| Questions right, of 95 | 59 | 63 |
| Small companies right, of 20 | 13 | 9 |
| Measure | realestate-us | Best of four assistants |
|---|---|---|
| Floor-plan rents right, of 26 | 26 | 23 |
| Amenities claimed the listing doesn't state | 12 | 129 |
| Measure | ask | jev |
|---|---|---|
| Right, of the questions answered | 98% | 79% |
| Wrong answers, of 92 | 2 | 19 |
| Measure | Trained localiser | Best of four frontier models |
|---|---|---|
| Mean overlap with the defect (IoU, 0 to 1) | 0.421 | 0.109 |