Custom AI models for the enterprise · New York · LondonSecurityResearchContact sales
Finetune the World
Research · Simulation

How many evaluation examples do you need to compare two LLMs?

Detecting a 3-point improvement at 85% accuracy takes about 2,000 examples, unless you use the structure of your data. A simulation of when pairing helps, and by how much.

The short answer#

At a baseline accuracy of 85%, two-sided and 80% power, the examples needed to detect an improvement of are:

Improvement ΔUnpaired (analytic)Paired, independent errorsPaired, moderately shared errorsPaired, strongly shared errors
+1 pts19,45720,71417,17010,409
+2 pts4,7214,9134,0722,628
+3 pts2,0332,1781,5931,165
+5 pts683704621426

Two lessons. First, small improvements are expensive to prove: a 1-point gain needs around 20,000 examples, which is why claims of “+1.2 points” on a few hundred items are noise. Second, evaluating both models on the same items and analysing the pairs cuts the requirement substantially — but only to the extent that the two models get the same items right and wrong.

The analytic baseline#

Treating the two models’ accuracies and as independent proportions, the required examples per model for a two-sided test are:

With , , and , that is 2,033. The dependence is the whole story of evaluation budgets: halving the effect you want to detect quadruples the data.

Why pairing helps#

In practice both models are scored on the same items, and items vary in difficulty. A hard item is likely wrong for both models; an easy one right for both. Those concordant items carry no information about which model is better. McNemar’s test uses only the discordant pairs — items where only A is right and where only B is right:

The variance of the paired difference is . The more the models’ errors coincide, the larger the covariance and the fewer examples you need.

Simulation design#

To quantify the effect we simulated items with latent difficulty. Item has logit ; model A answers correctly with probability and model B with , with and solved numerically so that mean accuracies are exactly 85% and . The spread controls how much the models share their errors: means independent errors; means a strong easy/hard split typical of real benchmarks. For each design and we ran 4,000 simulated evaluations and counted how often the test rejected at .

0%20%40%60%80%100%1001,00080% powerPaired, σ=3Paired, σ=1.5UnpairedEvaluation examples n (log scale)Power to detect +3 pts at 85%
Simulated power to detect a 3-point improvement. Pairing with strongly shared errors reaches 80% power at roughly half the examples of the unpaired design. Source: research/e4_power/power.py.

With independent errors () pairing gains nothing — the paired and unpaired requirements match within simulation resolution. At , a 3-point improvement needs 1,165 paired items versus 2,046 unpaired, a 43% reduction.

What to do with this#

  • Decide the minimum improvement worth detecting before building the set. If a 2-point gain would change your decision, you need thousands of items, not hundreds.
  • Always evaluate candidates on identical items and analyse paired differences. Report the paired bootstrap interval of the difference, not two separate intervals.
  • Measure your own error overlap. The fraction of items on which two models agree tells you which row of the table you are in. On extraction tasks we commonly see 85–95% agreement, firmly in the “strongly shared” regime.
  • Stratify. Per-segment claims need per-segment sample sizes; a 1,500-item set split into ten segments supports almost no segment-level conclusions.

The paired bootstrap, in code#

McNemar’s test answers “is there a difference?” For reporting, you want an interval for the size of the difference. The paired bootstrap resamples items, keeping each item’s two scores together:

import numpy as np
def paired_bootstrap(a: np.ndarray, b: np.ndarray, reps: int = 10_000, seed: int = 0):
    """a, b: per-item scores (0/1 or graded) for the same items. Returns (diff, lo, hi)."""
    rng = np.random.default_rng(seed)
    n = len(a); d = b - a
    idx = rng.integers(0, n, size=(reps, n))
    boot = d[idx].mean(axis=1)
    return d.mean(), *np.percentile(boot, [2.5, 97.5])

# Example: 1,500 items, candidate right on 52 items the incumbent missed, wrong on 18 it got
a = np.r_[np.ones(1300), np.ones(18), np.zeros(52), np.zeros(130)]
b = np.r_[np.ones(1300), np.zeros(18), np.ones(52), np.zeros(130)]
print(paired_bootstrap(a, b))   # ≈ (0.023, 0.012, 0.034)

Only the 70 discordant items move the estimate; the 1,430 items both systems agree on contribute nothing but stability. That is the pairing advantage in miniature.

Segment-level claims need segment-level samples#

A 1,500-item set may detect a 3-point overall gain, but split into ten equal segments it has 150 items per segment, enough to detect only differences of roughly 10–12 points within any one of them. If the business cares about the worst segment — handwritten forms, a minority language, a rare product line — over-sample it deliberately and report it separately. The relationship is the same law applied per segment:

Many checkpoints, many chances to fool yourself#

Fine-tuning projects compare dozens of checkpoints and configurations against the same evaluation set. Each comparison at carries a 5% false-positive risk; across independent comparisons the chance of at least one spurious “win” is

which is 40% at and 64% at . Two defences: hold out a confirmation slice that is used exactly once, on the final candidate; and, where you must make many formal comparisons, tighten the threshold (Bonferroni: ). Selection on the development set then becomes harmless, because the claim you report comes from data the selection never saw.

Limitations#

Binary correctness only; graded or rubric scores have different variance. The logit-normal difficulty model is a convenient assumption, not an empirical fit, and simulated required sizes were found by a geometric search with about 8% resolution. Multiple comparisons across many candidate checkpoints inflate false positives; correct for them or hold out a final confirmation set.

Method and reproducibility

Script: research/e4_power/power.py (NumPy/SciPy, seeded); output: research/results/e4_power.json. Runtime about 20 minutes on a laptop CPU.

References#

  1. McNemar, Q. (1947). Note on the sampling error of the difference between correlated proportions or percentages. Psychometrika 12(2), 153–157.

Frequently asked

Can’t find your question? Ask a senior engineer.

How many examples should an LLM evaluation set have?

Enough to detect the smallest improvement that would change your decision. At 85% accuracy, detecting a 3-point gain needs roughly 1,200–2,000 examples depending on how correlated the models’ errors are; a 5-point gain needs about 400–700.

Should I use a paired test to compare two models?

Yes, whenever both models are scored on the same items. McNemar’s test or a paired bootstrap uses only the items where the models disagree and can halve the examples needed when errors are shared.

Bring us one task. We’ll show you what a specialist model can do.

A 45-minute briefing with a senior research engineer. You leave with a feasibility read, a data plan and a fixed quote, whether or not you hire us.

Book a briefing →