AIAny. ← Back to AIAny

Lesson notes · one prompt · eight samples · one honest number

Codex: Evaluating LLMs Trained on Code

Codex is GPT with a GitHub diet, and it writes working Python. But the tool this paper handed the field is its grading scheme: sample completions, run the unit tests, count what passes — without fooling yourself. We'll build that scheme on one real problem, eight real model samples included, until pass@k is something you can compute with a pencil.

Subject Code generation, graded by execution Date Jul 7, 2021 Venue arXiv 2107.03374 · OpenAI Benchmark HumanEval · 164 problems Model Codex · 12M → 12B params Data 159 GB of GitHub Python

Mark Chen · Jerry Tworek · Heewoo Jun · Qiming Yuan · Henrique Ponde de Oliveira Pinto (equal contribution) and 50+ co-authors — OpenAI.

The core idea

Don't read the code — run it.

By 2021 it was clear a big language model could produce plausible Python: GPT-3 already did, straight from a docstring. The awkward part was scoring it. The field's habit was to grade generated text by how much it looks like a reference answer (metrics like BLEU) — and code is the one domain where looking right means nothing. A function can share nearly all of its characters with a correct solution and still return the wrong value on the first edge case.

This paper's lasting move is a measurement decision. Execute the generated function against hand-written unit tests, and count. It ships the benchmark (HumanEval, 164 problems), the metric (pass@k) and an unbiased way to estimate it — then trains the model worth measuring: Codex, GPT fine-tuned on 159 GB of GitHub Python, whose production descendant became GitHub Copilot.

The model was deprecated within a few years. The yardstick still grades its successors.

PART A

The task and the yardstick

Docstring in, function out — and why text similarity can't grade it.

Step 1 · Docstring in, function out

Codex is GPT-3's recipe with a new diet: 159 GB of Python.

If you've been through our GPT-3 page, you already own the only moving part here: a Transformer trained to predict the next token will continue any prompt you give it. A function signature plus a docstring — the quoted description at the top of a Python function — is just another prompt. The model's "answer" is whatever body it types next.

Codex changes the diet, not the recipe. Same GPT architecture, fine-tuned on 159 GB of Python collected in May 2020 from 54 million public GitHub repositories, for roughly 100 billion tokens. Two details from the paper worth keeping: starting from a pretrained GPT-3 did not improve the final result (the code corpus is that large) — it only made training converge faster — and the tokenizer got extra tokens for runs of whitespace, which cuts a code file's token count by about 30%.

def is_prime(n): """docstring…""" the prompt — all Codex sees CODEX GPT, fine-tuned on Python if n < 2: return False a candidate body
The whole pipeline, first pass. The amber card is the prompt; amber means "prompt / docstring" in every figure on this page.

Let's pick the specimen we'll keep for the rest of the lesson. HumanEval problem is_prime asks for a primality check, and its docstring carries worked examples — read the last one in the card below, because a lot will hinge on it:

def is_prime(n):
    """Return true if a given number is prime,
    and false otherwise.
    >>> is_prime(6)      False
    >>> is_prime(101)    True
    >>> is_prime(11)     True
    >>> is_prime(4)      False
    >>> is_prime(1)      False
    """
    ▮ Codex types from here, until a stop marker like \ndef
Our specimen for the whole page

Every mechanism from here on — sampling, unit-test grading, the pass@k arithmetic — happens to completions of this one prompt. The paper's appendix publishes eight real Codex-12B attempts at it; we'll meet all eight in Step 3.

Data details (§3.1–3.2): 179 GB of unique Python files under 1 MB, filtered of likely auto-generated code, files with average line length > 100 or any line > 1000 characters → 159 GB. Docstring layout abridged here; the original lists seven doctest examples, each result on its own line.

Step 2 · The grading problem

Two answers that look like twins — and only one of them works.

We handed Codex the is_prime prompt and it typed a body. Ask again and it types a different one. Before we collect a whole batch, we need a way to score a single attempt — and the field's usual way fails exactly here.

The usual way is a match-based metric like BLEU: compare the generated text to a reference solution and reward overlapping fragments. Below are two of Codex's actual attempts at is_prime, side by side. Cover the verdict tags and try to grade them by eye first.

Codex sample #1 fails

for i in range(2, n):
    if n % i == 0:
        return False
return True

Codex sample #6 passes

prime = True
if n == 1:
    return False
for i in range(2, n):
    if n % i == 0:
        prime = False
return prime

Both are trial division, near-identical as text. The teal lines on the right are the entire semantic difference: sample #1 never checks n = 1. Call is_prime(1) and its loop over range(2, 1) is empty, so it happily returns True — flatly contradicting the docstring's own last example. A text-overlap score barely separates these two; a unit test separates them instantly.

The paper checks that this isn't a cherry-picked anecdote. Across all of Codex-12B's HumanEval samples, the BLEU-score distributions of correct and incorrect solutions overlap heavily (Figure 8) — wrong programs, guaranteed functionally different from the reference, often score higher than right ones. Pushing BLEU up is not the same job as making code work.

The measurement decision

Grade by functional correctness: a sample counts as right if and only if it passes a set of unit tests. That's also how human engineers judge code — write the tests, then trust whatever passes them.

Samples #1 and #6 are verbatim from Appendix B of the paper (completions 1 and 6 for is_prime, temperature 0.8). We've kept their numbering — the full batch of eight arrives next step.

Step 3 · HumanEval & the sandbox

164 hand-written problems, ~7.7 tests each, run inside a padded cell.

Unit tests can tell our twins apart when text overlap can't. So the benchmark gets built around execution — which raises two practical problems: where do fresh test problems come from, and how do you dare run the code?

First problem: contamination. Codex trained on a huge slice of GitHub, and GitHub already contains solutions to every public problem set — the paper notes ten-plus repositories with solutions to Codeforces problems alone. So the authors wrote all 164 HumanEval problems by hand: docstring, function signature, on average 7.7 unit tests each. Difficulty sits around language comprehension, simple algorithms and simple math — easy-interview territory.

Second problem: safety. Model-generated code is untrusted by construction, and a GitHub-trained model has seen malware. Every sample runs inside a gVisor container with network access blocked by firewall rules — a sandbox that can execute millions of strangers' functions without letting one of them phone home.

Now the batch. The paper's appendix shows eight real Codex-12B samples for is_prime, drawn at temperature 0.8 — for now, "temperature 0.8" just means let the samples differ; Step 7 pays that IOU. Follow the figure left to right: one prompt fans out into eight candidate bodies, and the unit tests sort them into teal and coral.

is_prime prompt CODEX 12B ×8 1 3 5 7 2 4 6 8 UNIT TESTS run in a sandbox 3 pass · 5 fail
The Step-1 pipeline, zoomed in: sampling fans out, tests sort. Teal = passes all tests, coral = fails at least one — this coloring holds for the rest of the page.

#1 fail

trial division, no n = 1 guard

#2 fail

same loop, same missing guard

#3 fail

# TODO: implement — then pass

#4 pass

handles n < 2, checks odd divisors to √n

#5 fail

√n helper — but 1 still slips through

#6 pass

flag loop with the n = 1 guard

#7 fail

the guardless loop, a third time

#8 pass

full 6k±1 primality check

Notice what the tests caught: three of the five failures are the same plausible-looking loop, each missing only the n = 1 edge case, and one "attempt" is literally a TODO comment. Our scoreboard for this problem reads 3 passes out of 8 samples — hold on to those two numbers, because Part B is built entirely out of them.

HumanEval problems span a wide difficulty range: for the three example problems in the paper's Figure 2, a single Codex-12B sample passes with probability about 0.9, 0.17 and 0.005. The benchmark and harness are public at github.com/openai/human-eval.

PART B

pass@k, counted honestly

One number for "does it work" — built from subsets, not wishful powers.

Step 4 · What pass@k asks

"Solved" depends on the budget: k submissions, and any single pass counts.

HumanEval just graded our batch — 3 of 8 samples pass. But "three of eight on one problem" isn't a benchmark score. We need one number across all 164 problems, and before that, a rule for how many tries the model gets.

The rule is pass@k: for each problem the model may submit k samples, and the problem counts as solved if any one of them passes all the tests; pass@k is the fraction of problems solved. Why a budget at all? Because different deployments get different budgets: an autocomplete tool ships one suggestion (k = 1), while an offline solver can afford a hundred attempts (k = 100).

So, concretely: if we let the model submit 3 of our 8 is_prime samples, chosen at random — what's the chance at least one passes? Let's not reach for a formula. With five samples we can count every case by hand, so shrink the batch to samples #1–#5 for a moment; among those five, only #4 passes. There are exactly ten ways to pick 3 out of 5, and here are all ten:

123
missed
124
solved
125
missed
134
solved
135
missed
145
solved
234
solved
235
missed
245
solved
345
solved

Count the cards: six of the ten triples contain the teal #4, four don't. So on this five-sample pool, pass@3 = 6/10 = 0.6. And look at how we counted the misses — the four dashed cards are exactly the ways to choose 3 samples from the 4 failures, picking only from {1, 2, 3, 5}. That "choose only from the failures" count is the entire trick behind the next step.

Read it off the cards

P(miss) = (ways to pick k all-fail samples) ÷ (ways to pick k samples). pass@k is one minus that. No approximation anywhere — it's counting.

Step 5 · The unbiased estimator

Generate n, count c passes, then count subsets: pass@k = 1 − C(n−c, k)⁄C(n, k).

On five samples you listed all ten triples and found four duds, giving pass@3 = 0.6. Listing stops scaling immediately — but the count you did has a closed form, and it works for any batch.

The recipe: generate n ≥ k samples per problem (the paper uses n = 200), run the tests, count the c that pass. The number of ways to choose k of the n samples is C(n, k) — "n choose k" — and the number of all-fail choices is C(n−c, k), choosing only from the n−c failures. Let's redo is_prime with the full batch, n = 8 and c = 3, at k = 3:

a

Count every possible submission

Ways to choose which 3 of the 8 samples get submitted.

C(8, 3) = 56
b

Count the all-fail submissions

A miss must draw all 3 from the 5 failing samples {1, 2, 3, 5, 7}.

C(5, 3) = 10
c

Divide, then flip

Miss probability first, then its complement — the chance at least one submission passes.

P(miss) = 10/56 0.179 pass@3 = 1 − 0.179 0.82

That's a pencil-sized computation, and it's exactly what the paper's Equation (1) says — the line below is your three worksheet rows, wrapped in an average over the 164 problems:

n = samples generated · c = samples passing the tests · k = submission budget · Eq. (1), with C(·,·) the binomial coefficient

Now the trap this estimator exists to avoid — and honestly, the bias took us a couple of reads of Appendix A to see. Our first instinct was simpler: estimate the per-sample pass rate p̂ = c/n = 3/8, note that each of k tries fails with probability 1 − p̂, and write pass@k ≈ 1 − (1 − p̂)k. Run our numbers: 1 − (5/8)³ ≈ 0.756. The subset count said 0.821. The naive formula reads low — and not by accident.

Here's the picture that made it click for us. The plug-in treats your k picks as independent coin flips with a known bias p̂ — but p̂ is itself a noisy estimate, and 1 − (1 − p)k is a curve that bends downward as p grows. Feed a noisy p̂ through a downward-bending curve and the average lands below the true value, systematically. The subset count never estimates p at all: it computes the exact probability of drawing k duds without replacement from the n samples you actually have. Figure 13 of the paper shows the plug-in's gap refusing to close even at n > 5k.

Boundary of this walkthrough

We're waving at the bias with a picture; the two-line proof that Equation (1)'s expectation is exactly 1 − (1 − p)k lives in Appendix A of the paper, and we won't reproduce it here.

Sanity checks: at k = 1 the estimator collapses to c/n (1 − C(5,1)/C(8,1) = 3/8 — exactly the empirical pass rate). Computing giant binomials overflows, so the paper's Figure 3 evaluates the ratio term by term as ∏ (1 − k/i) for i = n−c+1 … n; with our numbers, (1−3/6)(1−3/7)(1−3/8) = 10/56. ✓

Step 6 · Try it — the estimator live

Three sliders, one lesson: more samples forgive a weak model.

You computed 1 − C(5,3)/C(8,3) ≈ 0.82 once with a pencil. The panel below is that identical subset count wired to three sliders — it opens at n = 8, c = 3, k = 3, so the first thing it shows you is your own answer.

Try it

Drag n, c and k — solid curve is the honest count, dashed is the naive plug-in

pass@k · subset count
82.1%
naive 1−(1−c/n)k
75.6% (−6.6 pts)
all-fail chance
17.9%
0% 50% 100% k — submissions allowed (log spacing, 1 … n)
subset count — Eq. (1) naive plug-in (biased low)
n — samples generated8
c — samples that pass3
k — submission budget3

Three things to try. ① Hold c low and push k up — the solid curve climbs steeply: a mediocre model plus many tries acts like a much better model, which is the entire Part C story. ② Push k past n − c and the honest value pins to 100%: every possible pick must include a pass. ③ Set k = 1 — the two estimators agree exactly (both are c/n); the naive one only drifts low as k grows.

The paper evaluates pass@k for k up to 100, always generating n = 200 samples per problem and applying Eq. (1) — never the plug-in.

Step 7 · The temperature knob

Diversity is an asset only when you hold several tickets.

The explorer took the batch as given — 3 passes in 8 samples, fixed. But how spread-out those samples are is itself a dial on the model, and the paper tunes it separately for every k.

Time to pay Step 3's IOU. Temperature (T) controls how adventurous each sampled token is. At T → 0 the model always takes its single most-likely token, so all eight of our samples would collapse into the same candidate written eight times; higher T spreads probability onto riskier choices, so samples genuinely differ — a few brilliant, more of them broken.

Whether that trade is worth it depends entirely on k. With one ticket (k = 1) you want the model's best guess — play it cold. With a hundred tickets, pass@k only rewards at least one success, so a diverse, risky batch beats a hundred copies of one safe guess. In the paper's sweep on a 679M-parameter Codex, the best temperature for pass@1 is 0.2, while the best for pass@100 is 0.8. Drag k below and watch the dot climb the staircase through the budgets in between.

Try it

Slide the budget k — the dot shows the temperature that maximizes pass@k

budget k
1
best temperature T*
0.2
0.2 0.4 0.6 0.8 1 10 100 k — submission budget (log scale)
k — submission budget (1 → 100)

Cold for one try, hot for a hundred. The staircase is the "upper hull" of the paper's Figure 5; we read the breakpoints off the plot approximately — trust the trend, treat the exact corners as sketch.

Why this matters for the scoreboard

Every headline number in Part C is quoted at its own best temperature — pass@1 measured cold, pass@100 measured hot. Skip that tuning and you understate one end or the other.

Sampling everywhere in the paper is nucleus sampling with top-p = 0.95. Codex-S (Step 9) prefers slightly higher temperatures at every k — it models a narrower distribution, so it can afford more heat.

PART C

The scoreboard and the cracks

What the new yardstick measured — including the model's own failures.

Step 8 · The scoreboard

Same architecture, new diet: 0% becomes 28.8% — and 100 tries make it 72.3%.

The yardstick is complete: hand-written problems, execution-based grading, an unbiased pass@k, temperature tuned per budget. Let's point it at the models — starting with the one that motivated the paper.

Predict first

GPT-3 writes plausible Python from docstrings — that observation started this project. Before you look: what's your guess for GPT-3 12B's pass@1 on HumanEval?

0% — not one of the 164 problems. Plausible-looking is not the same as passing 7.7 unit tests, and natural-language pretraining alone gets you plausible-looking. Every un-fine-tuned GPT lands near zero.

graded by unit tests

HumanEval · pass@1 · one sample per problem

GPT-3 12B · no code fine-tuning
0%
TabNine · leading autocomplete, 2021
2.6%
GPT-Neo 2.7B · The Pile (8% GitHub)
6.4%
GPT-J 6B · The Pile
11.6%
Codex-12B · this paper
28.8%
46.8% Codex-12B pass@10 — ten tickets, nearly half the benchmark.
72.3% Codex-12B pass@100 — the sampling lever from Step 6, at full pull.
≈ 20× parameter discount from code fine-tuning: GPT-J 6B scores like a Codex-300M.
(N/5.92×10⁷)−0.13 — code test loss still falls as a power law in model size, for readers coming from our scaling-laws page.

Two readings of this table. First, the diet is everything: identical architectures move from 0% to 28.8% on GitHub food alone. Second, sampling is a lever: the same 12B model is a 28.8% model with one ticket and a 72.3% model with a hundred — and the estimator you hand-computed in Step 5 is what makes that second number trustworthy. Pass rates rise smoothly with model size (an S-curve against log-parameters, Figure 6), so none of this is a lucky checkpoint.

All numbers from Table 1 and §3, each at its per-k optimal temperature. GPT-Neo and GPT-J see some code because The Pile is ~8% GitHub — which is exactly why they sit between GPT-3 and Codex.

Step 9 · Codex-S, and picking one of a hundred

Fine-tune on clean examples, then rank by confidence: 28.8 → 37.7 → 44.5.

That 72.3% carries an asterisk: someone had to spot which of the 100 samples was the good one, and on the benchmark the unit tests do the spotting. A deployed assistant has no tests — it must commit to one suggestion.

The paper closes the gap from both ends. From the training side: raw GitHub is mostly not shaped like "docstring → standalone function" (it's classes, configs, scripts), so the authors built a matched diet — roughly 10,000 problems from competitive-programming sites plus ~40,000 functions with test-verified behavior traced from open-source CI runs — and fine-tuned Codex on it. They even used Codex-12B itself as a filter: generate 100 samples per curated problem, and drop any problem none of them solves, treating it as ambiguous. The result, Codex-S, jumps to 37.7% pass@1 — a +6.5-point average gain across model sizes, +15.1 on pass@100.

From the selection side: without tests, rank the 100 samples by the model's own confidence — mean per-token log-probability — and submit the top one. That heuristic alone reaches 44.5%, against 77.5% for a test-oracle picking from the same batch. Follow the four bars down: the gap between 44.5 and 77.5 is precisely "solutions the model wrote but couldn't recognize."

Codex-S-12B ladder · how far each trick climbs

Codex-12B · pass@1
28.8%
Codex-S-12B · pass@1
37.7%
+ mean-logp pick · best of 100, no tests
44.5%
+ oracle pick · unit tests choose from 100
77.5%

This ladder is Copilot's daily physics: an editor plugin lives on the 44.5% rung (sample several, rank by confidence, show one), while any workflow that can run your tests gets to climb toward the teal bar.

§4 and Figures 7–10. Ranking notes: mean log-probability beats sum log-probability and random choice; ranking by back-translation (how well a docstring model reconstructs the prompt) underperforms mean-logp and overfits quickly.

Step 10 · Running the machine backwards

Codex-D writes the docstring from the code — graded by hand, built for safety.

Codex-S trains on (docstring → solution) pairs. Each pair reads just as well backwards — and the reverse direction turns out to matter for a different reason than score-chasing.

Rearrange each training example to signature → solution → docstring, and the same next-token training yields Codex-D, a model that explains code instead of writing it. Grading flips too: no unit test can check an English sentence, so the authors hand-graded ten samples per problem — 1,640 judgments — counting a docstring correct only if it uniquely and accurately specifies the function body.

signature passing solution CODEX-D """docstring…""" graded by a human, not a test
Same blocks as Step 1's pipeline, shuffled: the amber docstring moves to the output end.

Scores land lower but in the same league — Codex-D-12B at 20.3% pass@1 and 46.5% pass@10, versus Codex-S's 32.2% / 59.5% under the same grading. The failure modes are telling: dropping a load-bearing detail ("round to two decimal places"), or simply copying the code into the docstring. It also produces the occasional pure-GitHub artifact — docstrings like "I just found this function online."

Why bother? Safety, explicitly: a model that states what code does gives you a tool for describing the intent of generated code before you trust it — plus the back-translation ranker from Step 9's fineprint, even though that ranking trick lost to mean-logp.

Step 11 · Where it breaks

Every extra instruction in the docstring costs a factor of 2–3 in pass rate.

With 100 samples, Codex-S finds a working answer for 77.5% of HumanEval. The paper's own limitations section asks the sharper question: which problems stay unsolved no matter how many tickets you buy?

The authors built a probe. Take 13 trivial one-line string operations — "remove all vowels", "make every other character uppercase" — and write synthetic docstrings that chain 1, 2, 3, … of them in sequence. Each component is easy; only the chaining grows. A person who can do a chain of two can do a chain of ten. Codex can't: its pass rate falls by roughly a factor of 2–3 per added component — follow the coral dots from about 25% at one component down to nearly nothing by five.

0 .1 .2 ÷ 2–3 per added link chained components in the docstring (1 → 7)
The collapse in Figure 11, redrawn — point heights are approximate reads of the plot; the factor-of-2–3 decay rate is the paper's own statement.

A second failure is binding — attaching the right operation to the right variable when several float around. This prompt and completion are quoted directly from §6; the coral lines are where Codex-12B loses the thread:

def do_work(x, y, z, w):
    """ Add 3 to y, then subtract 4 from both x and w.
    Return the product of the four numbers. """
    t = y + 3
    u = x - 4
    v = z * w          ← w never gets its −4
    return v           ← returns z·w, not the product of all four

Add the third finding and the shape of the machine comes into focus: Codex is spectacularly sample-inefficient, trained on hundreds of millions of lines of code — more than a developer reads in a career — yet the paper grants that a strong student who finishes an intro CS course would out-solve Codex-12B on this benchmark. It isn't a junior developer in a box; it's a different kind of machine that pattern-matches its way to junior-developer output on short, well-specified tasks.

Step 12 · The honest appendix

Show it buggy code and it writes buggier code — capability is not intent.

Chained docstrings mapped what Codex can't do. The appendices probe something stranger — what it does worse than it can, and what deploying it would mean.

The experiment: prepend a few examples to the prompt — either clean solutions or ones seeded with subtle bugs — then ask for a new function. With buggy context, Codex's output quality drops well below what the same model produces with clean context, even when the prompt explicitly instructs it to write correct code. Look at the two bars below: the coral one isn't a weaker model, it's the same model matching your mistakes.

Codex-12B pass@1 · same problems, different context (≈ read from Fig. 12)

3 clean examples prepended
≈ 29%
3 subtly buggy examples prepended
≈ 22%

The paper names this an alignment failure, and draws a line worth memorizing: a system is misaligned if it's capable of doing what you want and doesn't; it's merely incompetent if it can't. Codex proves capability with clean context, so the buggy-context drop is misalignment — a next-token predictor faithfully continuing your distribution, bugs included. Worse, the gap grows with model size: a better distribution-matcher copies your flaws more faithfully. That observation, made before RLHF-tuned assistants existed, is one reason this section aged so well.

The rest of the hazard analysis reads like a checklist the field still works from: over-reliance (people accepting plausible wrong code), insecure suggestions, biased comments absorbed from GitHub, labor-market and energy questions — and one legal data point that anchored years of debate: generations matching training data nearly verbatim occur at a rate under 0.1%.

That's the whole paper. Before you leave, try these six against your own memory — each answer is a couple of sentences.

Why hand-write 164 new problems instead of scraping existing ones?

Contamination: Codex trained on GitHub, and GitHub already hosts solutions to public problem sets (ten-plus repos solve Codeforces problems). Fresh, hand-written tasks are the only ones the model can't have memorized.

Why is BLEU the wrong grader for code?

Text overlap ignores semantics: our sample #1 differs from a correct answer by one missing n = 1 guard yet fails, and across the benchmark the BLEU distributions of correct and wrong solutions overlap heavily (Figure 8).

Your model passes 3 of 8 samples on a problem. pass@3?

1 − C(5,3)/C(8,3) = 1 − 10/56 ≈ 0.82. Ten of the fifty-six possible triples draw only from the five failures; the other forty-six contain at least one pass.

Why not just compute 1 − (1 − c/n)ᵏ?

Because c/n is a noisy estimate and that formula bends downward in p, so on average it reads low — 0.756 versus the true 0.821 in our example. The subset count is the exact probability for the samples you actually drew.

Why does the best temperature depend on k?

pass@k pays for at-least-one success. With k = 1, diversity is pure risk (best T ≈ 0.2); with k = 100, a spread-out batch is more likely to contain one winner (best T ≈ 0.8).

Codex writes worse code when the prompt contains bugs. Why call that misalignment?

Because it demonstrably can do better — with clean context it does. It's matching the prompt's distribution rather than the user's intent, and that clean-vs-buggy gap widens as models grow (Figure 12).

Homework — the estimator is three lines of numpy (Figure 3 of the paper). Next time a release brags about pass@k, check two things: did they generate n > k samples, and did they use the subset count? You now know exactly why both matter.

"We find that repeated sampling from the model is a surprisingly effective strategy for producing working solutions to difficult prompts." — Chen, Tworek, Jun, Yuan et al., 2021 (abstract)
The profound impact

The yardstick outlived the model.

Codex the model is retired. What survives is everything this paper built to measure it — plus the product line it started.

2021 · the product

GitHub Copilot

A production descendant of these research models shipped inside editors the same year — the first mass-market LLM product, more than a year before ChatGPT.

2021 → now · the method

Execution is the grader

HumanEval and pass@k became the default protocol for code models; MBPP, MultiPL-E and today's agentic suites like SWE-bench all score by running code against tests.

2022 → now · the lever

Sampling as compute

"Draw many, keep the best" — 28.8% turning into 72.3% — grew into verifier-guided search and the test-time-compute playbook of the reasoning era.

Ask any code model a benchmark question today and the answer comes back in this paper's unit: pass@k.