HumanEval › Code Implementation
Language AI HandbookAll chapters HumanEval › Code ImplementationOne section · Sections in this chapter8 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Let us implement the pass@k calculation and examine the HumanEval dataset structure. We will use the math library for exact combinatorial calculations and implement the metric from scratch to ensure understanding.
import math
# Mock dataset for demonstration: 164 problems, each with required fields
heval = [
{
"task_id": f"HumanEval/{i}",
"prompt": 'def example():\n """Example function."""\n pass\n',
"canonical_solution": " return True",
"test": "def check(func):\n assert func() is True\n",
"entry_point": "example",
}
for i in range(164)
]
def calculate_pass_at_k(n, c, k):
"""
Calculate pass@k given n total samples and c correct samples.
Uses the exact hypergeometric formula:
pass@k = 1 - C(n-c, k) / C(n, k)
Args:
n: Total number of samples generated per problem
c: Number of correct samples (passing all tests)
k: The k in pass@k
Returns:
float: pass@k score between 0 and 1
"""
if n < k:
raise ValueError(f"n ({n}) must be >= k ({k})")
if c > n:
raise ValueError(f"c ({c}) cannot be > n ({n})")
if c == 0:
return 0.0
if c == n:
return 1.0
# When n - c < k, all k selections must include at least one correct
if n - c < k:
return 1.0
return 1.0 - math.comb(n - c, k) / math.comb(n, k)
def pass_at_k_approximation(n, c, k):
"""
Approximate pass@k using the independence assumption.
Valid when n >> k.
pass@k ≈ 1 - (1 - c/n)^k
"""
if n == 0:
return 0.0
return 1.0 - (1 - c / n) ** kHumanEval contains 164 problems Keys in each example: ['task_id', 'prompt', 'canonical_solution', 'test', 'entry_point']
The dataset contains 164 programming problems. Let us examine the structure of a specific example.
# Examine the first problem
example = heval[0]
task_id = example["task_id"]
prompt = example["prompt"]
canonical = example["canonical_solution"]
test_code = example["test"]
entry_point = example["entry_point"]Task ID: HumanEval/0
Entry point (function to implement): example
--- PROMPT ---
def example():
"""Example function."""
pass
--- CANONICAL SOLUTION ---
return True
--- TEST CODE ---
def check(func):
assert func() is TrueThe prompt gives the function signature and docstring describing what the function should do. The canonical solution shows one correct implementation, and the test code contains assertions that any correct implementation must satisfy. A model under evaluation receives only the prompt and must generate the body of the function.
Now let us verify the metric calculation matches our worked example.
Exact pass@k calculations for n=5, c=2: pass@1: exact=0.400 approx=0.400 pass@2: exact=0.700 approx=0.640 pass@3: exact=0.900 approx=0.784 pass@4: exact=1.000 approx=0.870 pass@5: exact=1.000 approx=0.922 Boundary condition checks: pass@5 with c=2 (guaranteed hit all in 5 draws): 1.000 pass@1 with c=0 (no correct samples): 0.000 pass@1 with c=5 (all samples correct): 1.000




The calculations match our manual worked example. Notice how the approximation diverges slightly as approaches , which is expected since the approximation assumes . The exact calculation properly handles the saturation at pass@k = 1 when exceeds the number of incorrect samples.
Simulating a Multi-Problem Benchmark Evaluation
Now let us show how pass@k is aggregated across multiple problems with varying difficulty. We will simulate generating samples per problem with varying underlying success rates.
num_problems = 10
n_samples = 20 # Number of samples generated per problem
# Simulate c (number correct) for each problem
# Beta distribution models varying difficulty: Beta(2, 5) skews toward low success rates
underlying_rates = np.random.beta(2, 5, num_problems)
c_vals_sim = np.random.binomial(n_samples, p=underlying_rates)
problem_results = [
{
"problem_id": f"problem_{i}",
"n": n_samples,
"c": int(c_vals_sim[i]),
"true_rate": float(underlying_rates[i]),
}
for i in range(num_problems)
]Simulated evaluation results: Problem ID | n | c | pass@1 | pass@5 | pass@10 ---------------------------------------------------------------------- problem_0 | 20 | 6 | 0.30 | 0.87 | 0.99 problem_1 | 20 | 6 | 0.30 | 0.87 | 0.99 problem_2 | 20 | 7 | 0.35 | 0.92 | 1.00 problem_3 | 20 | 3 | 0.15 | 0.60 | 0.89 problem_4 | 20 | 11 | 0.55 | 0.99 | 1.00 problem_5 | 20 | 1 | 0.05 | 0.25 | 0.50 problem_6 | 20 | 6 | 0.30 | 0.87 | 0.99 problem_7 | 20 | 5 | 0.25 | 0.81 | 0.98 problem_8 | 20 | 7 | 0.35 | 0.92 | 1.00 problem_9 | 20 | 10 | 0.50 | 0.98 | 1.00

The simulated results reveal large variation in problem difficulty, with easier problems showing high pass rates even at k=1 while harder problems benefit materially from increased sampling budgets. Notice how pass@k consistently increases with k for every problem. This shows the value of generating multiple candidate solutions. This pattern mirrors practical development workflows where we iterate through several attempts before finding a working solution. The diminishing returns become apparent as well: increasing k from 1 to 5 often yields large improvements, while increasing from 5 to 10 gives smaller gains for problems with few correct samples.
Aggregating Across the Benchmark
Finally, we aggregate across all problems to get the overall benchmark score. This is the number reported in papers as the model's pass@k performance on HumanEval.
from collections import defaultdict
import numpy as np
def evaluate_benchmark(problem_results, k_values=[1, 10, 100]):
"""
Calculate aggregate pass@k across all problems.
"""
scores = defaultdict(list)
for result in problem_results:
n_r = result["n"]
c_r = result["c"]
for k in k_values:
if k <= n_r:
p = calculate_pass_at_k(n_r, c_r, k)
scores[k].append(p)
# Macro-average across problems
aggregated = {k: np.mean(scores[k]) for k in scores}
return aggregatedAggregate pass@k scores across benchmark: pass@1: 0.310 pass@5: 0.808 pass@10: 0.936 pass@20: 1.000

The aggregate curve shows how letting multiple attempts substantially increases the effective capability of the model. With a pass@1 of approximately 28%, the model solves roughly a quarter of problems on the first attempt, but increasing the sample budget to 10 attempts can raise performance substantially. This shows how generation diversity compensates for individual sample uncertainty. This exponential improvement curve helps practitioners decide how many samples to generate based on their latency and compute budgets versus accuracy requirements.