Noise is a pretraining speedrun for learning algorithms that never run a backward pass. We think replacing backprop with a much better credit assignment algorithm is inevitable. Deep learning's architectures, optimizers and hardware have co-evolved with backprop, but as compute grows, the bitter lesson suggests that more general, brute-force learning algorithms based on search will win. Dust is a big step forward: it rivals backprop under SGD and is 1,000 to 10,000x more efficient than EGGROLL, the state-of-the-art weight-space ES, but still trails backprop under Adam. These methods have also had a small fraction of the research that went into backprop. We made Noise to close the gap: better estimators, and optimizers co-designed for them instead of for backprop gradients.
The model, the data and the score are fixed: the 37.7M-parameter transformer of Dust, its 10M-token FineWeb training set, and the cross-entropy on its validation set. What changes is the learning algorithm, which may only run the model forward. The architecture is fixed for now, but we will relax this constraint later.
- Validation loss. The lowest validation loss after one epoch on one 8xH100 node, with no time limit.
- Speedrun. The shortest training time on one 8xH100 node to reach validation loss 4.2.
- No backpropagation. No autograd (reverse or forward mode) and no hand-written backward pass. Learning signal comes from evaluating the model forward: every error signal is measured against a loss by running the model forward, and may then take at most one step through a nonlinear part of the model. Steps through linear maps don't count, and a signal that has taken a step can't take another, so credit can't be chained back through the network block by block. Entries are judged by the spirit of this rule: a method should still apply to networks with non-differentiable parts.
- Fixed model. Final weights must load into
utils/model.pywith a strict state-dict match. How training computes the same function, and how it initializes it, is free. - Fixed data. Train only on
data/train.pt(4,880 sequences of 2,048 predictions), for at most one epoch: each training sequence feeds at most one update. Batch size and order are free. - Score.
utils/eval.pyon the final weights: mean next-token cross-entropy over the 1,114,112 predictions ofdata/val.pt. No checkpoint selection on validation loss. - Timing (speedrun track; reported on the other). From the start of the first update to the end of the last, excluding any validation. An untimed warmup on random tokens may compile kernels, as long as training then starts from a fresh state (the baselines rebuild everything from the seed). Runs use seed 0.
Requires Linux, an NVIDIA GPU with bfloat16 support and uv.
uv sync
uv run utils/prepare_data.pyutils/prepare_data.py streams FineWeb sample-10BT, tokenizes it with the fixed BPE-4096 tokenizer in
tokenizer/, and writes data/train.pt and data/val.pt, the train_10M.pt
and val.pt of the Dust repo. Both are checked against pinned hashes.
uv run torchrun --standalone --nproc_per_node=8 train/val/run.py # track 1
uv run torchrun --standalone --nproc_per_node=8 train/speedrun/run.py # track 2
uv run torchrun --standalone --nproc_per_node=8 train/val/eggroll.pyEach run writes config.json, metrics.jsonl, final.pt and result.json (validation loss and training time)
to logs/. uv run utils/eval.py logs/val/final.pt rescores a checkpoint.
| # | Val loss | Description | Time | Script | Contributors |
|---|---|---|---|---|---|
| 1 | 5.954 | EGGROLL w/ Adam, 128k antithetic pairs, lr cooldown | 5 h 20 min | Script | - |
| 2 | 5.058 | Dust w/ SGD, 16k population | 1 h 19 min | Script | - |
| 3 | 4.167 | Dust w/ Adam, 24k population, lr cooldown | 1 h 46 min | Script | - |
| 4 | 4.088 | Dust w/ ANVIL II on the block matrices and Adam elsewhere | 1 h 47 min | Script | @Lazarus-931 |
| 5 | 4.082 | FP32 head in the direct draws reruns | 1 h 49 min | Script | @JaydenTeoh |
| 6 | 4.035 | Orthogonal draws, coordinate-difference head, live-unit MLP jitter, 2x Adam lr | 1 h 44 min | Script | @JaydenTeoh |
| 7 | 4.008 | Associative credit memory as a prior for the draws | 1 h 46 min | Script | @JaydenTeoh |
| 8 | 3.991 | Reduce population to 16k | 1 h 12 min | Script | @serdardoesml |
| 9 | 3.945 | Boost → Cut: stagewise readout training, then credit along strong routes | 8 min | Script | @spicylemonade |
| 10 | 3.896 | Own queries in Cut: each move also reaches its token's later attention through its own query | 10 min | Script | @hoo0681, @Lazarus-931 |
| 11 | 3.777 | Exact values and a value path in Cut; Cut at batch 4, hidden credit on every unit | 18 min | Script | @CharlesDDDD |
| # | Val loss | Description | Time | Script | Contributors |
|---|---|---|---|---|---|
| 1 | 4.167 | Dust w/ Adam, 24k population, lr cooldown | 1 h 46 min | Script | - |
| 2 | 4.180 | Track 1 record at 5k population | 22 min | Script | @JaydenTeoh, @Lazarus-931, @serdardoesml |
| 3 | 4.184 | Compile the probe construction | 21 min | Script | @pculaf |
| 4 | 4.123 | Boost: stagewise forward-only training with exact readout credit | 5 min | Script | @spicylemonade |
| 5 | 4.180 | Boost on 4,200 sequences, larger probe chunks, max-autotune | 4 min 21 s | Script | @Euraba |
| 6 | 4.169 | Boost: closed-form hub and value credit, exact keys, 3,600 sequences | 2 min 37 s | Script | @Euraba |
| 7 | 4.176 | Identity-path credit with exact values: no Boost or Cut phases | 1 min 23 s | Script | @Lazarus-931 |
| 8 | 4.174 | Factored finite key and hidden probes | 1 min 2 s | Script | @jon123boss |
| 9 | 4.177 | Identity-path credit with fused probe kernels, no MLP cycle | 47 s | Script | @isaac0804 |
| 10 | 4.180 | Identity-path credit, token-sharded across GPUs | 15.4 s | Script | @RobertTLange |
| 11 | 4.188 | Drift Leap: stop early, then one leap back along the weights' drift | 14.6 s | Script | @areu01or00 |
| 12 | 4.162 | Data-free structured start: block 1's heads as lag-1 RoPE heads | 13.1 s | Script | @erodola |
| 13 | 4.144 | Moment kernels for the exact experiments, one head per GPU | 6.4 s | Script | @RobertTLange |
The same model, data and epoch trained with backprop, scored the same way:
| Optimizer | Val loss |
|---|---|
| SGD | 5.007 |
| Adam w/ lr cooldown | 3.769 |
The goal is to beat backprop by a large margin.
Open a PR that changes its track's training script in place, train/val/run.py or
train/speedrun/run.py, with the run's log (config.json, metrics.jsonl and result.json from logs/) in the log/ folder next to it. A record must beat the current one
in its track under the rules above; the training script is the record.
@misc{noise_2026,
title = {Noise: Speedrun for pretraining without backpropagation},
author = {G{\"u}lbahar, Serdar and Mandal, Bishwas and Vegesna, Akshay and Dahal, Samip},
year = {2026},
url = {https://github.com/qlabs-eng/noise}
}Core contributors: Serdar Gülbahar and Bishwas Mandal.
Released under the MIT License.
