A neural quantum error decoder for the surface code, trained and benchmarked entirely on Apple Silicon with MLX. It reads the syndrome a rotated surface code emits and predicts whether the logical qubit flipped, and it is measured head-to-head against minimum-weight perfect matching — the decoder the field actually ships.
Quantum error correction has a decoding bottleneck. A superconducting processor emits one round of syndrome measurements roughly every microsecond, and the classical decoder has to keep pace or the error backlog grows without bound. Minimum-weight perfect matching (MWPM) is the industry standard, but it is provably sub-optimal: it decomposes correlated errors into independent components and throws away correlation information a learned decoder can use. DeepMind's AlphaQubit (Nature, November 2024) showed a transformer decoder beating matching on real hardware syndromes.
That work runs on GPUs and TPUs. maxwell asks a narrower question: how far can you get with a small transformer decoder that trains and runs entirely on-device, on a laptop, through MLX? Decoding is the one place the AI-for-quantum intersection is genuinely load-bearing rather than hype, and there was no MLX implementation of it. This is that implementation, at a scale you can reproduce on an Apple Silicon Mac in about an hour.
git clone https://github.com/rajanshxrma/maxwell.git
cd maxwell
uv sync
# generate a training set — rotated surface code, circuit-level depolarizing
# noise, mixing five physical error rates (200k shots each = 1M total)
uv run maxwell generate --distance 3 --rounds 3 \
--rates 0.002,0.003,0.005,0.008,0.01 --shots-per-rate 200000 \
--out data/d3_train.npz
# train the transformer decoder
uv run maxwell train --data data/d3_train.npz --arch transformer \
--epochs 12 --batch-size 512 --lr 3e-4 --out checkpoints/d3_transformer
# benchmark against MWPM on fresh shots, including single-shot latency
uv run maxwell eval --checkpoint checkpoints/d3_transformer \
--shots 200000 --json-out results/d3_report.json
# render the logical-error-rate comparison chart
uv run maxwell plot --json results/d3_report.json --out results/d3_comparison.pngAt code distance 3, the transformer decoder beats MWPM on logical error rate at every physical error rate tested — one model, trained once across the whole noise range, evaluated on 200,000 fresh shots per rate:
| Physical error rate | Shots | MWPM LER | maxwell LER | Relative reduction |
|---|---|---|---|---|
| 0.002 | 200,000 | 0.307% | 0.266% | 13% |
| 0.003 | 200,000 | 0.662% | 0.601% | 9% |
| 0.005 | 200,000 | 1.693% | 1.575% | 7% |
| 0.008 | 200,000 | 4.022% | 3.837% | 5% |
| 0.010 | 200,000 | 5.853% | 5.656% | 3% |
The gain is largest in the low-noise regime, where correlated errors make up a larger share of the failures MWPM leaves on the table. Training took about an hour (12 epochs, ~5 minutes each).
There is a real cost on the other side of the ledger, and it is the one that matters for a live processor. Single-shot decode latency is 5 µs for MWPM against 1017 µs for the neural decoder (median), and batched throughput is 4.5M shots/s versus 15k — roughly two orders of magnitude apart. The decoder is more accurate but not yet fast enough for the microsecond-per-round budget real-time decoding demands. Closing that gap is the interesting engineering problem, not an afterthought.
Measured on an Apple M1.
Syndrome generation. Stim compiles a rotated memory_z surface-code circuit under a circuit-level depolarizing noise model — depolarization after each Clifford layer and before each measurement round, plus measurement and reset flips — the standard "circuit-level noise" benchmark rather than the easier code-capacity model. A detector sampler yields, per shot, the binary detection events (space-time syndrome differences) and the true logical observable flip.
Baseline. PyMatching builds a matching graph directly from Stim's detector error model with correlated errors decomposed, giving the same MWPM decoder used in practice — the honest, strong baseline any learned decoder has to be measured against.
The decoder. Each detector is a token — a learned embedding of its binary value plus a learned embedding of its position in the syndrome — and a prepended CLS token is pooled after a small stack of pre-norm transformer blocks to produce a single logit for "the logical observable flipped." The model is deliberately small (under a million parameters) so the whole thing trains on-device.
One model across a noise range. The training set mixes shots from several physical error rates (0.002 to 0.01), so a single decoder learns to read both the sparse syndromes of a quiet processor and the dense ones of a noisy one. Evaluation always scores on freshly sampled shots drawn from a disjoint seed range, so the model is never tested on shots it trained on.
This is a first result, scoped deliberately narrow:
- Memory-experiment decoding only — it decodes the logical observable of a
memory_zexperiment, not a full computation with lattice surgery or logical gates. - Distance 3 — this first result is at code distance 3; scaling to larger distances is the natural next milestone (see below).
- One model across a noise range — a checkpoint is trained across the 0.002–0.01 range; behaviour outside that range is untested.
- Not real-time — the latency benchmark measures single-shot decode time honestly, but the model is not yet optimized to hold the microsecond-per-round budget a live processor imposes.
Natural next steps: a larger-capacity model to carry the win to distance 5 and 7 and show the below-threshold trend (larger distance, lower logical error rate), soft (analog) measurement information for the decoder, and profiling the decode path toward the real-time latency target.
uv run pytestMIT — see LICENSE.
