Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path →
AlphaCode,
explained.
Competitive programming is code as sport: read a fiendish problem, invent an algorithm, implement it flawlessly, all against the clock. AlphaCode reached the level of a median human competitor — and it got there not by being a brilliant single-shot programmer but by being a relentless one. Its strategy is almost brute: generate a staggering number of candidate programs, throw away the ones that fail the visible tests, group what survives by how it behaves, and submit a few from the biggest groups. Correctness is rare per attempt but findable in bulk, if you can sift. Here's the sift.
What changes against sampling a few: sample a million and filter
Rung 1 samples a handful of candidates and reports whether one works. This rung takes that observation to its limit: if the model solves a problem some small fraction of the time, then sampling enormously and selecting well should solve problems it cannot solve reliably at all. The target is competitive programming — problems requiring an actual algorithmic insight, where rung 1's models were near-hopeless.
The pipeline is generate, filter, cluster. Generate candidate programs on the order of a million per problem. Then filter on the example tests the problem statement provides, which eliminates the overwhelming majority — this is the step that makes the scale usable, and it is free, because the examples come with the question.
The survivors are still far too many to submit, since contests limit attempts, and the clever part is how they are reduced. Cluster by behaviour, not by text: generate additional inputs, run every surviving program on them, and group programs that produce identical outputs. Each cluster is one distinct solution strategy, however differently written, so submitting one representative per cluster covers the space of genuinely different attempts rather than submitting ten spellings of the same wrong idea. Stated in units: reaching roughly median human in real contests, from a model that gets any individual sample right very rarely.
Code as sport
Competitive programming problems aren't like the tidy functions of HumanEval. They're puzzles: a clever problem statement that hides an algorithmic insight, a strict time and memory limit, and hidden tests that punish any edge case you miss. Solving them requires genuine reasoning — pick the right algorithm, get the complexity under budget, implement it without bugs. For a long time this looked like a stronghold of human ingenuity.
AlphaCode's insight was that you don't need a model that gets it right on the first try — you need one that gets it right somewhere among many tries, plus a reliable way to find that right answer in the pile. So it split the job into two halves: a model that generates a huge, diverse set of candidate programs, and a selection pipeline that separates the wheat from the chaff. Brilliance in aggregate, not per sample.
Generate millions of candidate programs, discard the ones that fail the example tests, cluster the survivors by behavior, and submit a few from the largest clusters.
Sample at scale
The first half is a large transformer trained on public code and fine-tuned on competitive-programming problems, used to sample candidate solutions — but at a scale most systems never attempt. For a single hard problem, AlphaCode generates up to millions of candidate programs, using high sampling temperature and metadata conditioning to keep them diverse.
Why so many? Because for a genuinely hard problem, the per-sample probability of being correct is tiny. But "tiny per sample" across a million samples still yields a healthy number of correct ones — if some correct solution is within the model's reach at all. Massive sampling is a way of buying coverage of the solution space. The whole strategy rests on it: you can afford to be wrong nearly every time, as long as you're right often enough in absolute terms and can identify the winners.
Filter by examples
A million candidates is far too many to submit — and contests punish wrong submissions and cap how many you can make. So the pile must be cut down, hard. The first cut is filtering: every problem comes with a few public example tests, so AlphaCode runs each candidate on those and throws away any that fail. This is cheap (just execution) and brutally effective — it eliminates the large majority, often ~99%, of the samples, because a program that can't even pass the given examples is certainly wrong.
Filtering is the workhorse that turns an unmanageable flood into a manageable shortlist. It costs almost nothing — no model, just running code against a handful of tests — yet removes nearly everything wrong. What's left has cleared the lowest bar (it works on the examples), but there are still far too many to submit, and many are duplicates. That's where clustering comes in. The runnable version below filters candidates and shows only the passers survive.
Cluster and pick
The thousands of surviving programs aren't thousands of distinct solutions — many are syntactic variations of the same underlying algorithm. AlphaCode clusters them by behavior: it generates additional test inputs (with a separate model), runs every survivor on them, and groups programs that produce identical outputs. Programs in the same cluster are effectively the same solution; different clusters are genuinely different attempts.
Then it submits one program per cluster, prioritizing the largest clusters, until it hits the submission budget. The logic is a form of consensus: if many independently-sampled programs converge on the same behavior, that behavior is more likely to be correct than a lone outlier. Clustering both deduplicates (don't waste submissions on the same solution) and ranks (agreement is a signal). It's the same "sample many, take the majority" idea that powers self-consistency in reasoning — here applied to whole programs judged by what they compute.
How AlphaCode was built and run, step by step
AlphaCode (Li, Choi, Chung, Kushman and colleagues at DeepMind) is a pipeline, not just a model. In order:
- Pre-train on GitHub. The pre-training set is a snapshot of public GitHub code in a dozen popular languages, including C++, Python and Java, about 715 GB after deduplication and filtering. Each file is split at a random point: the encoder reads the first part and the decoder is trained to produce the rest, with a masked-language-model loss on the encoder as well.
- Use an asymmetric encoder-decoder. Problem statements are long and solutions shorter, so the encoder takes 1,536 tokens and the decoder 768. The encoder is shallow and the decoder deep, and attention uses multi-query attention, in which all heads share one set of keys and values, to make sampling cheaper. Models range from 300M to 41B parameters, with an 8,000-token SentencePiece vocabulary shared across programming languages and English.
- Fine-tune on CodeContests. The team built and released this dataset: problems from Codeforces and other sources, with correct and incorrect human submissions, and a strict temporal split so that every validation and test problem appeared after the training data was collected. Extra tests were generated by mutating existing test inputs and keeping those on which correct solutions agree, to cut false positives.
- Condition on metadata. The fine-tuning prompt includes the problem's difficulty rating, its algorithm tags, the language, and whether the solution is correct. At sampling time the model is always told the solution is correct, and the rating and tags are randomized to make samples more diverse.
- Train with GOLD and tempering. Because a contest needs only one correct solution per problem, the loss uses GOLD, an off-policy objective that weights each token by the model's own probability of it, so the model concentrates on solutions it already finds likely rather than spreading itself over all of them. Logits are divided by a temperature of 0.2 during training, which smooths the learned distribution; sampling uses a separately tuned temperature.
- Sample at scale. For each problem the models sample on the order of a million programs, split between Python and C++.
- Filter on the examples. Every sample runs on the example tests given in the problem statement; about 99 percent fail and are discarded.
- Cluster by behavior. A separate model, trained to write plausible test inputs from a problem description, generates new inputs. The survivors run on them and are grouped by identical outputs.
- Submit ten. One program is taken from each cluster, largest cluster first, until the limit of 10 submissions per problem is reached.
Why each stage is there
Pre-training gives general code knowledge, fine-tuning gives the contest format, and the sampling tricks (metadata randomization, high-volume sampling in two languages) buy diversity, because coverage of genuinely different attempts is what the later stages need. Filtering is nearly free and removes almost everything; clustering exists because the few thousand survivors are mostly the same handful of behaviors written differently, and ten submissions cannot be spent on near-duplicates.
The n@k metric, tempering and the GOLD objective
k— samples generated per problem;n— submissions allowed, 10 in AlphaCode's main metric. A problem counts as solved if any submitted program passes all hidden tests.pass@k— the special case where every sample may be submitted, so it upper-bounds 10@k at the same k; the gap between them measures how good the selection is.zt, T— the decoder's logits and the training temperature; because training divides by 0.2, the raw logits the model learns are flatter than the data.P̂θ(yt)— the model's own probability of the demonstrated token, used as a constant weight with no gradient flowing through it.
At the extremes: n = 1 is the hardest version, a single submission, and n = k is pass@k. If the GOLD weight were replaced by 1, the objective would be ordinary maximum likelihood, which tries to cover every human solution; with the weight, solutions the model finds unlikely are down-weighted, trading recall for precision, which is what a contest that needs one correct program rewards.
What AlphaCode measured
AlphaCode was evaluated two ways: on 10 recent Codeforces contests, each with more than 5,000 participants, by simulating participation with up to 10 submissions per problem under the contest's penalty rules, and on the held-out CodeContests test set with the n@k metric.
| Measurement | Result |
|---|---|
| Average ranking across the 10 Codeforces contests | top 54.3% of participants |
| Estimated Codeforces rating | 1238, within the top 28% of users active in the previous six months |
| Samples removed by the example tests | about 99% |
| Solve rate against number of samples | roughly log-linear, still rising at a million |
| Clustering against a random choice of 10 filtered samples | clearly better, with a gap left to pass@k |
A ranking in the top 54.3 percent places AlphaCode near the median contestant, slightly below it. The ablations credit every part of the recipe: each fine-tuning addition (metadata conditioning, value conditioning, GOLD, tempering) raised solve rates at large sample budgets, larger models helped, and more samples helped at every model size. The scaling result is also the method's main limit: solve rate grew roughly with the logarithm of the sample count, so each further gain needed ten times the compute.
The dataset work exposed a problem in earlier benchmarks. With only a few tests per problem, many programs that passed were actually wrong; the authors report high false-positive rates in existing datasets and say their generated tests brought CodeContests down to a few percent. They also checked for copying and found that AlphaCode's solutions shared substrings with the training data at about the same rate as human solutions, mostly input-parsing boilerplate rather than problem-solving logic. Solve rates fell steeply with problem difficulty, and the hardest problems stayed out of reach.
DeepMind's AlphaCode 2 (2023), built on Gemini, kept the sample, filter and cluster skeleton, added a learned model to score candidates, and is reported to perform better than about 85 percent of contest participants.
What the authors admit, and what happened next
The compute cost is stated and it is extraordinary — a million samples per problem is a quantity of inference nobody would spend on a real task, so this is a demonstration of what is possible rather than a method. It also depends on example tests being supplied with the problem, which is a property of programming contests and not of programming.
And competitive programming is a narrow, self-contained domain: a precise specification, a closed input space, a definite answer. Success here transfers less than the framing suggests, which the paper is more careful about than its coverage was.
How it held up: the recipe is the ancestor of test-time compute for code, and behavioural clustering is the durable idea — semantic deduplication by observed output is cheap, does not care how the program is written, and has no equivalent in text. What did not hold is the economics: within a couple of years, reasoning models reached comparable and better contest performance with a tiny fraction of the samples, because a model that reasons before answering does not need a million attempts to stumble on the insight. Read this rung as the strongest available demonstration that search over samples and reasoning within a sample are substitutes, and that the second is far cheaper once available.
Filter, cluster, submit
AlphaCode's selection pipeline is two simple operations. Filtering keeps only candidates that pass the example tests — 5 samples, 3 survive. Clustering groups the survivors by identical behavior on probe inputs, so three programs computing [1,2] form one cluster and a lone [9,9] forms another; the largest cluster is the consensus, and submitting within a budget of 2 sends one representative from each of the two biggest clusters. That "many agreeing programs are probably right" is majority vote over code. Change the pass/fail flags or behaviors and watch the shortlist re-form.
Write the body of cluster. Everything else in the file is
already written; this is the function the paper is about. Press ▶ Run to check it against
the 5 assertions below — they start red.
- Filtering keeps only candidates passing the example tests
- Clustering groups candidates by identical behavior
- The largest cluster is the majority-behavior group
- Picking respects the submission budget
- Picking the largest clusters first captures consensus
What it showed
AlphaCode is a landmark case of test-time scaling for code: rather than a smarter single generation, throw compute at many generations and select well. That pattern — sample-and-select — recurs across the field, from self-consistency in reasoning to best-of-N with a verifier, and it foreshadowed the reasoning models that spend heavy compute exploring many solution paths before answering. AlphaCode made the case, on a hard task, that quantity plus good selection can substitute for one-shot brilliance.
Its deeper idea is the generate-and-verify asymmetry taken to an extreme. Generating a correct competitive-programming solution is very hard; checking whether a program passes tests is trivial. AlphaCode leaned all the way into that gap: generate absurdly many, let cheap execution filter, and let behavioral agreement rank. When you can verify far more cheaply than you can produce, flooding the problem with attempts and sieving them is a startlingly effective strategy — one AlphaCode proved could reach human-competitive performance on a task that seemed to demand genius.
Clustering needs generated test inputs to probe behavior, so AlphaCode trains a separate model just to invent plausible inputs — a small piece that's essential, since without extra inputs many wrong programs would look identical on the sparse public examples.
Questions people ask about AlphaCode
What does the n@k metric mean in AlphaCode?
n@k is the percentage of problems solved when the system generates k samples per problem but may submit only n of them, with a problem counted as solved if any submitted program passes all the hidden tests. AlphaCode's headline metric is 10@k, matching a budget of ten submissions per problem, with k ranging up to about a million. The more familiar pass@k is the special case n = k, where every sample could be submitted, so it is an upper bound on 10@k at the same k. The difference between the two measures the selection step: how well filtering and clustering pick ten programs out of a huge pile of candidates.
What architecture does AlphaCode use?
An encoder-decoder transformer, unlike the decoder-only Codex. The encoder reads the problem statement, up to 1,536 tokens, and the decoder writes the program, up to 768 tokens. The two halves are deliberately unequal: a shallow encoder and a deep decoder, which keeps training and sampling efficient for long descriptions and shorter programs. Attention uses multi-query attention, with one shared set of keys and values for all heads, to cut the memory traffic of sampling, which matters when you sample a million programs per problem. Models came in sizes from 300M to 41B parameters with an 8,000-token SentencePiece vocabulary.
How does AlphaCode choose its 10 submissions?
After sampling, every program runs on the example tests in the problem statement, which removes about 99 percent of them. The survivors still number in the thousands, so AlphaCode clusters them by behavior. A separate model, trained to write test inputs from problem descriptions, generates new inputs; every survivor runs on them, and programs that produce identical outputs on all of them go into the same cluster. AlphaCode then submits one program from each cluster, largest cluster first, until it has used its ten submissions. Clustering removes duplicates, so ten submissions are ten different attempts, and cluster size acts as a vote for the behavior many independent samples agree on.
What are GOLD, tempering and value conditioning in AlphaCode?
They are fine-tuning techniques the paper adds on top of ordinary training. Value conditioning includes incorrect human submissions in training, tagged as incorrect, and always asks for a correct solution at sampling time, so the model learns from failures without imitating them. GOLD is an off-policy objective that weights each token's loss by the model's own probability of it, focusing learning on the correct solutions the model already finds plausible, since a contest needs one correct program rather than coverage of all of them. Tempering divides the logits by 0.2 during training, smoothing the learned distribution. Each technique raised solve rates in the paper's ablations, at least at large sample budgets.
How does AlphaCode 2 differ from AlphaCode?
AlphaCode 2, which DeepMind described in a 2023 technical report, replaces the original models with fine-tuned versions of Gemini but keeps the overall skeleton: sample a very large number of programs, filter them on the example tests, and cluster them by behavior on generated inputs. Its main addition is a learned scoring model that ranks candidates before submission. The report places it above roughly 85 percent of contest participants, against about the median for the original AlphaCode. It remains a search-heavy system rather than a model that solves problems in a single attempt, which is the direction later reasoning models took instead.
What is the CodeContests dataset?
It is the competitive-programming dataset DeepMind released with AlphaCode. It gathers problems from Codeforces and other sources together with correct and incorrect human solutions in several languages, plus test cases. Two design choices make it useful for evaluation. A strict temporal split places all validation and test problems after the training data cutoff, so the model cannot have seen them during training. And because the few tests that come with a problem let many wrong programs pass, the authors generated extra tests by mutating existing inputs and keeping those on which known-correct solutions agree, which brought the false-positive rate down to a few percent.
4 questions to test what you just read
Work each one out before you open it — a number, a prediction or a reason, not a definition. Producing the answer is what makes it stick. Your progress is kept on this device.
Suppose one sample in 10,000 is correct for a hard problem. How many correct programs do you expect among a million samples, and why does that still not guarantee a solve under 10@k?
Show answer
About 100. But they sit among the thousands of samples that also pass the example tests, many of them wrong. If wrong programs share common behaviors and form bigger clusters, all ten submissions can go to wrong clusters, so coverage only helps when selection surfaces a correct one.
Why does clustering need a separate model that writes new test inputs, instead of using the problem's example tests?
Show answer
Every survivor of filtering already passes the example tests, so on those inputs all of them produce the same outputs and would land in one cluster. Only new inputs can separate programs that agree on the examples but differ elsewhere, and the new inputs need no correct outputs, because clustering compares programs only with one another.
Why is pass@k an upper bound on 10@k at the same k, and what does the gap between them measure?
Show answer
pass@k counts a problem as solved if any of the k samples is correct, as if all could be submitted; 10@k must commit to ten of them. Any problem 10@k solves, pass@k also solves. The gap is the cost of choosing: how often a correct program existed in the pile but filtering and clustering did not pick it.
If solve rate grows log-linearly with the number of samples, how does the gain from 100,000 to 1,000,000 samples compare with the gain from 10,000 to 100,000, and what does that imply about cost?
Show answer
Roughly the same absolute gain, because each tenfold increase adds about the same amount. The second step costs ten times the compute of the first for that same increment, so returns per unit of compute fall off steeply, which is why sample-and-filter alone was later overtaken by models that reason before answering.
Models that write code
Completion, then competition, then a benchmark made of real GitHub issues — the point at which "can it code?" got an answer you could audit.
- 1Codex2021
- 2AlphaCode2022
- 3SWE-bench & SWE-agent2023
Explore the topic
See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.
More Paper Breakdowns
- Attention Is All You NeedThe paper that introduced the Transformer — the architecture underneath GPT, BERT, Claude, and Gemini. Self-attention, Query/Key/Value, multi-head attention, positional encoding, and the real BLEU results, explained in depth with analogies and animated visuals, not just equations.Read →
- BERTThe paper that made "pre-train once, fine-tune anywhere" the default for NLP. Bidirectional context, masked language modeling, next-sentence prediction, the [CLS]/[SEP] tokens, and the GLUE sweep — explained with analogies, not just equations.Read →
- Chain-of-Thought PromptingShow a model a few worked examples with their reasoning and it starts solving problems it used to fail. Why reasoning emerges only at scale, the GSM8K jump, zero-shot "Let's think step by step", and how CoT seeded modern reasoning models.Read →
- LoRAThe paper that made fine-tuning affordable. Freeze the giant pretrained model and train two tiny low-rank matrices instead — up to 10,000x fewer trainable parameters, no extra inference latency, and swappable per-task adapters. The road to QLoRA and PEFT.Read →
- Direct Preference OptimizationRLHF without the RL. Align a model to human preference pairs with one simple classification-style loss — no separate reward model, no unstable reinforcement learning. Why "your LM is secretly a reward model", and how DPO became the default alignment method.Read →
- ChinchillaThe compute-optimal scaling law that said models were too big. Parameters and training tokens should scale together — ~20 tokens per parameter — so a 70B model trained on 1.4T tokens beat the 280B giants. Why every model since trains on trillions of tokens.Read →