Decoder Lab
Train a lookup table, an MLP and a small transformer to decode the surface code in your browser, and race them against minimum-weight perfect matching across the threshold. You leave with a logical-vs-physical error-rate chart you generated, and the numbers behind it.
Logical error rate against physical error rate
Sky lines are MWPM at d = 3, 5, 7, thin to thick: where the thick line stops being the lowest is the threshold. Coloured lines are the decoders you trained, at the trained distance only, with 95% bands. Open markers mean zero failures in the sample — an upper bound, not a rate. The dotted line is a bare, unencoded qubit.
What this reproduces
AlphaQubit (Bausch et al., Nature 2024) is a transformer that reads the detection events of a surface-code memory experiment and predicts whether the logical qubit flipped. It beat matching decoders on Google’s Sycamore data at d = 3 and 5, after pretraining on hundreds of millions of simulated samples and fine-tuning on real hardware. This page is that experiment at the scale a browser tab can run: the same code family, the same task framing (predict the logical flip, not the error), a tokens-per-stabiliser attention decoder, and the same baseline — minimum-weight perfect matching, implemented exactly for these sizes.
Everything you see was computed after you pressed the button. The noise is sampled live, the networks start from random weights, and the sweep re-decodes fresh shots at every p. Change the seed by pressing the button again; the plotted numbers will wobble by about their error bars and nothing else.
How to read the chart
Below the threshold, a bigger code is a better code: the d = 7 line sits under d = 5 under d = 3, and each step down is roughly a constant factor. Above it the order inverts — more qubits means more places to fail and the decoder cannot keep up. The crossing is the threshold, and with perfect syndrome extraction it lands near 15% depolarising p (10.3% per Pauli channel, the textbook figure). Turn on measurement error and the crossing drops to a few percent, because the decoder must now also work out when an error happened.
The learned decoders are plotted only at the distance you trained them for, because a network trained at d = 3 has no idea what a d = 5 syndrome means. They were trained at one p and are evaluated across the sweep unchanged — which is exactly how a trained decoder is deployed, and also why they can look worse far from the training point: the noise statistics they learned no longer match.
What to expect on the default budget. At d = 3 the lookup table is the best decoder on the chart, and the MLP usually beats MWPM by a few percent relative, because both see the X and Z channels together and depolarising noise correlates them (a Y fires both), while matching decodes each channel alone. At d = 5 and 7, thirty thousand samples is nowhere near enough: the networks trail MWPM badly, and the transformer, which has to learn the lattice from position embeddings alone, trails the MLP. That is the honest shape of the problem — AlphaQubit needed on the order of 108 samples — and raising the budget moves the curves visibly.
The four decoders
Lookup table. A map from every detector pattern to the most common logical outcome seen after it. With enough samples it is the exact maximum-likelihood decoder for the trained noise; its test asserts this against a brute-force enumeration of all 49 error patterns at d = 3. It is d = 3 only because the key space is 2d²−1.
MWPM. Dijkstra over the space-time detector graph with log-likelihood edge weights, then an exact minimum-weight matching: defects are split into clusters that can be matched independently (pairing two defects is only worthwhile when it beats sending both to the boundary), and each cluster of up to 14 is solved by a subset dynamic programme. Larger clusters — only far above threshold — fall to a greedy start refined by exact re-solves of 12-defect windows, and the page reports how often that happened. Tests check the exact path against brute-force enumeration on every d = 3 syndrome and hundreds at d = 5 and 7.
MLP. All detectors of both channels in, two ReLU layers of 64, two logits out. Adam, batches of 32, a few thousand parameters.
Transformer. One token per stabiliser carrying that stabiliser’s detection events across rounds, plus a learned position embedding. Two pre-LayerNorm blocks of two-head self-attention and a feed-forward layer, mean-pooled to two logits. Every gradient is hand-derived and checked against finite differences in the test suite.
What this tool does not do
It does not simulate circuit-level noise: no two-qubit gate errors, no leakage, no crosstalk, no idle dephasing during a round. The two noise settings here are the standard textbook ones — code capacity (perfect measurement) and phenomenological (flipped measurement outcomes). Real thresholds are lower than both.
It does not train on hardware data, and it does not pretrain. The learned decoders here see at most a hundred thousand samples in a minute of your CPU; the published result needed a datacentre. A curve on this page where a network beats MWPM at d = 5 would be evidence of a bug, not of progress, and the test suite would be the place to look.
It does not implement Blossom. The matching is exact for the syndromes this lab produces below and around threshold; the heuristic fallback is flagged whenever it runs. It is not a general-purpose MWPM library and should not be cited as one.
It does not decode the two Pauli channels jointly in MWPM — that is the very limitation the learned decoders can exploit here, and it is the reason the lookup table and MLP beat matching at d = 3.
Where the numbers come from
lib/qec/model.ts holds the noise model and the detector layout; lib/qec/matching.ts the graph and the matching; lib/qec/lookup.ts, mlp.ts and transformer.ts the decoders; lib/qec/session.ts the budgeted training loop and the sweep, which the worker in lib/qec/worker.ts drives. The lattice is the same one behind The Surface Code; the repetition-code duel this grew out of is Decoder Duel.