Comparing Model Performance Fairly
Suppose you have a model that writes code, and you want to know how good it is.
Judging Code by Whether It Works
Suppose you have a model that writes code, and you want to know how good it is. One option is to read each program and judge it by eye. That is slow, and two reviewers may disagree about the same program. A more reliable question is whether the program actually does its job. Each programming problem comes with test cases, and a solution either passes them or it does not. The metric this article covers, pass@k, is built on that idea of checking real behavior rather than comparing text.
The underlying principle is broader than code. Functional correctness evaluates AI outputs by measuring whether they achieve a measurable objective, such as a game score or energy savings. The common thread is a measurable objective. Tasks that have one can usually be evaluated this way, and pass@k is the version of this idea that applies to code generation, where the measurable objective is passing a problem's test cases.
Following One Problem Through Its Samples
The definition is easier to hold onto if you follow a single problem through its k samples. Picture one problem with a set of test cases. The model writes a first program, and the test cases run against it. If that program fails, the model writes a second program for the same problem, and the test cases run again. The problem is counted as solved the moment any one of these programs passes everything.
This diagram shows one possible path, where the second sample is the one that passes. The same counting rule applies whichever sample succeeds. What matters for pass@k is only whether a passing sample exists among the k generated for that problem. If the first sample passes, the problem is solved and the later samples do not change that result.
Counting Problems Instead of Samples
Notice that the score counts problems, not individual samples. A problem where only one of the k samples works still counts as solved. A problem where none of the k samples works counts as unsolved, no matter how close the failing attempts came. This is why the metric is read as a problem-level success rate.
pass@k is the fraction of problems solved, where a problem counts as solved if any of the k generated code samples passes all test cases.
In this formula, N is the number of problems in the set and S is the number of those problems that have at least one passing sample among their k generated samples. The result is always a fraction between 0 and 1.
Computing pass@1 and pass@3 for five problems
A model generates 3 samples for each of 5 problems. Each sample is marked pass or fail by the test cases. Compute pass@1 (using only the first sample of each problem) and pass@3 (using all three samples). Here pass means the sample passes all test cases.
- 1Write out the results
Problem A: fail, pass, fail. Problem B: fail, fail, pass. Problem C: pass, fail, fail. Problem D: fail, fail, fail. Problem E: fail, pass, pass.
- 2Compute pass@1
Only the first sample counts. Only problem C has a passing first sample, so S = 1 and N = 5, giving pass@1 = 1/5 = 0.2.
- 3Compute pass@3
All three samples count. Problems A, B, C and E each have at least one passing sample, so S = 4 and N = 5, giving pass@3 = 4/5 = 0.8.
- 4Check problem D
Problem D has three failing samples, so it stays unsolved at every k. It never contributes to S.
pass@1 = 0.2 and pass@3 = 0.8. Both are fractions of the same five problems, but they answer different questions, so they must not be compared against each other as if they measured the same thing.
Why More Samples Raise the Score
Because a problem is solved when any of its k samples passes, adding more samples gives the model more opportunities to succeed. Each extra sample can only help the chance of solving that problem. This is the reason the score tends to rise as k grows. Scores are therefore expected to rise as k increases, which is why they should be compared at the same k.
The diagram uses the same five problems as the worked example. Moving from k = 1 to k = 2 adds two newly solved problems, which is a gain of 0.4. Moving from k = 2 to k = 3 adds one more, a gain of 0.2. Each extra sample still helps, but the increase is smaller than the one before because the easiest-to-solve problems are often already counted. Problem D stays unsolved throughout, so no value of k can raise the score for it.
What do you think happens?
If you compare a model at pass@10 with another model at pass@1, which comparison is fair?
Reveal answer
Neither is fair unless both are reported at the same k.
The source states that a pass@10 score and a pass@1 score measure different things, even though both are fractions of solved problems. Scores should be compared at the same k.
Functional Correctness Versus Reference-Based Metrics
Not every task can be checked by running a program or reading a game score. When the task you care about cannot be evaluated through functional correctness, a common alternative is to compare the model's output against reference data. Each entry in reference data pairs an input with one or more reference responses. These references are also called ground truths or canonical responses.
| Question | Functional correctness | Reference-based metrics |
|---|---|---|
| What is checked? | Whether the output achieves a measurable objective, such as passing test cases | How the output relates to reference data |
| What is needed? | A way to run or measure the output automatically | A set of reference responses to compare against |
| Typical example | pass@k on programming problems | Comparison with human or AI-generated references |
| When is it the better choice? | When the output can be checked automatically through behavior | When automatic checking is not possible |
Choosing between the two families of metrics
Reference data is usually produced by people, and increasingly by AI systems. When humans create the references, the human answers become the standard that the model is measured against. In that setup, human performance is treated as the gold standard, and the model's performance is judged by how closely it matches it. The quality of any reference-based score therefore depends on how the reference data was generated and reviewed.
Human-written references are often expensive and slow to produce, which is the main limitation of this approach. The amount of reference data you can build is limited by how much and how fast it can be generated. This pressure is why many teams turn to AI to generate reference data. AI-generated references may still need human review, but reviewing them takes far less effort than writing every reference from scratch.
Mistakes When Comparing Scores
Common mistake Comparing a pass@10 score with a pass@1 score
What it looks likeA model reports pass@10 = 0.8 and a rival reports pass@1 = 0.5, and the first is declared the clear winner.
Why it failspass@k tends to rise as k increases, so the two numbers measure different things.
Do this insteadCompare models only at the same k.
Common mistake Counting a near-miss as partly solved
What it looks likeA problem where a sample fails only one of twenty tests is counted as half solved.
Why it failsA problem is counted as solved only when a sample passes all of its test cases.
Do this insteadCount a problem as solved or unsolved, based on whether a sample passes everything.
Common mistake Counting samples instead of problems
What it looks likeReporting that 6 of 15 generated samples passed and treating that as the score.
Why it failsThe metric is a problem-level success rate, so two passing samples on one problem still count as one solved problem.
Do this insteadCount each problem once if any of its k samples passes.
Common mistake Assuming reference data is always correct
What it looks likeTreating a reference answer as the gold standard without asking who wrote it or whether it was reviewed.
Why it failsReference quality depends on how the data was generated and reviewed.
Do this insteadCheck how the reference data was produced before trusting the comparison.
Practice Computing pass@k
A model generates 2 samples for each of 4 problems. The results are: Problem W: fail, pass. Problem X: pass, fail. Problem Y: fail, fail. Problem Z: fail, pass. Compute pass@1 and pass@2. Then say whether the score for pass@2 can be lower than the score for pass@1 for this same set, and explain why.
Hints
- For pass@1, only the first sample of each problem counts.
- For pass@2, a problem is solved if either of its two samples passes.
- Divide the number of solved problems by the total number of problems, which is 4 here.
Key Takeaways
- Functional correctness measures whether an AI output achieves a measurable objective; for code generation, that objective is passing a problem's test cases.
- pass@k is the fraction of problems in which at least one of k generated samples passes all test cases, so it is a problem-level success rate.
- pass@k is expected to rise as k increases because each extra sample can only add chances to solve a problem, so scores should be compared at the same k.
- When automatic checking is not possible, reference-based metrics compare outputs against reference data, and their quality depends on how that data was generated and reviewed.