这篇重点学什么
本篇重点:推导 pass@k 的组合估计,比较系统时按题目重新抽样并保留配对;事先固定采样预算和报告规则。
开始读正文 ↓学过相近内容?查看哪些可以跳过
两条路线有些基础相同。已经学会的部分可以跳过,另一条路线只用来补你当前需要的内容。
回归与统计评估
共同基础先约定实验方法,再用独立样本得到可以比较的结果。
另一条路线补充什么?
先列出发布必须通过的检查,校准评分器,再比较新旧版本有没有退步,决定能否发布。
读完这篇,你能做什么
Java稳定计算组合概率;Python枚举小集合校验公式,并生成按题目配对的bootstrap差值区间。
学习理由、准备要求与知识点
为什么学它
多试几次通常更容易找到一个成功答案,但不能因此声称单次就可靠。比较提升时,也要选对独立抽样和统计的单位。
先读这些内容
知识点清单
- pass@k定义与候选预算
- 无放回组合估计
- 独立同分布假设
- 数值稳定log1p与expm1
- 按题目宏平均
- 配对bootstrap
- 重复比较与选择偏差
- 统计与实际效果
运行前先确认2021年代码模型评估论文公式1、ACL2018统计指南;Java17与Python3.14标准库。未进行真实模型对比或GPU实验。
01先弄懂它是什么
一道题允许生成 k 个候选,只要至少一个通过验证,就记为该题 pass@k 成功。它衡量的是多次尝试中找到成功候选的机会,前提是能检查这些候选。例如生成十次里有一次正确,与系统一次回答就正确,是不同指标;从十份里找出正确那份也有成本。因此报告要同时写明 k、怎样采样,以及验证用了多少预算。
常见做法是先为每题采样 n 个候选,记录其中 c 个通过,再估计较小 k 的结果:1-C(n-c,k)/C(n,k),其中 k 必须在一到 n 之间,C 表示组合数。可以把它读成:从已有候选中均匀、无放回地选 k 个,先算全部失败的比例,再用一减去它。若原始候选是独立同分布采样,这也是目标 pass@k 的无偏估计;对会边试边调整的自适应搜索,不能直接套用同样解释。
跨题目时通常先计算每题分数,再对题目等权平均。把所有题的候选混在一起后算一个成功率,会让候选数多或容易的题权重失控,也把题目难度差异掩盖。比较两种方法时,同一道题的结果天然相关,应该保留配对关系,而不是把每个候选当作完全独立的任务。
文中这几个词,先认一认
- 无偏估计
- 在规定的抽样条件下,重复很多次实验,估计结果的平均值等于要估计的目标;单次结果仍可能有误差。
- 配对比较
- 让两种方法做相同题目,再逐题比较差值,减少两组题目难度不同带来的干扰。
- Bootstrap
- 从已经观察到的统计单位中有放回地重抽样,再重复计算指标,用来近似估计结果会怎样波动。
02看看它怎么工作
组合数可能很大,Java不用阶乘,而把全失败概率写成从i=0到k-1的乘积(1-c/(n-i))。先累加log1p(-c/(n-i)),再用-expm1返回补概率。若失败数小于k,直接返回一;没有成功候选则返回零。这些分支既表达数学边界,也避免对数零和巨大组合数溢出。
Python先枚举n不超过七的所有k子集,将“至少一个成功”的比例与组合公式逐一对照。接着给六道合成题构造两种方法的每题分数,用同一题目索引同时抽取两种方法,计算差值均值的百分位区间。固定随机种子使教学输出可核对,但六题区间只展示流程,不足以证明真实方法优劣。
按题目做 bootstrap,主要回答“换一批题,平均成绩会怎样波动”。但同一道题重新生成一批候选,也可能得到不同结果;如果只固定眼前这批候选再重抽题目,就没有充分计入这部分变化。可以用多个随机种子重复生成,或把题目抽样、候选生成分成不同层来分析,但要保留真实的数据关联。例如多道题都来自同一模板或仓库,它们可能一起变难或变易,应考虑按模板或仓库成组抽样,不能因为题目 ID 不同就认定彼此独立。
先跑通一个最小例子
Python3.14标准库执行experiment.py,枚举小集合并对六道合成题做2000次配对bootstrap。没有运行模型或不受信任程序。
展开收起代码 · experiment.py
长行可在代码区域内左右滚动,按 Tab 可把焦点移入代码区。
import itertools
import math
import random
def pass_k(n,c,k):
if not (type(n) is int and type(c) is int and type(k) is int and n>=1 and 0<=c<=n and 1<=k<=n): raise ValueError("counts")
return 1-math.comb(n-c,k)/math.comb(n,k) if n-c>=k else 1.
def paired_bootstrap(a,b,repeats=2000,seed=44):
if not a or len(a)!=len(b) or repeats<2: raise ValueError("pairs")
differences=[y-x for x,y in zip(a,b)]
rng=random.Random(seed);n=len(a);sample=[]
for _ in range(repeats):
# 同一个题目索引同时取两个方法,保留配对相关性。
sample.append(sum(differences[rng.randrange(n)] for _ in range(n))/n)
sample.sort()
return sum(differences)/n,(sample[int(.025*(repeats-1))],sample[int(.975*(repeats-1))])
for n in range(1,8):
for c in range(n+1):
for k in range(1,n+1):
subsets=list(itertools.combinations([1]*c+[0]*(n-c),k))
observed=sum(any(s) for s in subsets)/len(subsets)
assert math.isclose(pass_k(n,c,k),observed,abs_tol=1e-12)
a=[pass_k(10,c,2) for c in (1,2,3,4,2,1)]
b=[pass_k(10,c,2) for c in (2,2,4,3,3,1)]
mean,interval=paired_bootstrap(a,b)
assert interval[0]<=mean<=interval[1]
assert paired_bootstrap(a,b)==paired_bootstrap(a,b)
assert paired_bootstrap(a,a)==(0.,(0.,0.))
assert math.isclose(pass_k(10,2,1),.2)
try: pass_k(2,1,3)
except ValueError: pass
else: raise AssertionError("k>n")
print(f"paired_delta={mean:.6f} percentile_interval={interval}")
print("PASS 6 check groups; tiny synthetic tasks, no general significance claim")
核对运行结果输出paired_delta及百分位区间,PASS 6 check groups;不从六题合成数据得出普遍显著性结论。
正在加载流程图…
查看流程图源码(Mermaid)
flowchart TD
N0["固定任务集采样规则与k"]
N1["每题记录候选总数和通过数"]
N2["稳定计算每题pass概率"]
N3["同题配对重采样差值"]
N4["连同区间预算和覆盖报告"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4按顺序看,每一步做了什么
- 固定任务集采样规则与k
- 每题记录候选总数和通过数
- 稳定计算每题pass概率
- 同题配对重采样差值
- 连同区间预算和覆盖报告
03对照实现代码
Evaluating Large Language Models Trained on Code,2021;公式1与附录A · 1-C(n-c,k)/C(n,k)
原创论文公式模型;不涉及任何商业模型API或当前产品规格。
import math
def estimate(n, c, k):
if not 0 <= c <= n or not 1 <= k <= n:
raise ValueError("counts") # 不为样本数不足的k外推结果。
if n-c < k:
return 1.0 # 全失败子集不存在。
return 1-math.comb(n-c,k)/math.comb(n,k) # 原创小整数公式模型,Java另做稳定浮点版。
原论文定义pass@k并讨论利用n个样本中c个正确结果的估计;附录通过二项分布假设说明无偏性。这里明确区分两层含义:给定有限池的无放回比例是组合恒等式,而把它解释成未来独立采样k次的成功概率估计还需要采样假设。
HumanEval作者实现estimate_pass_at_k使用乘积方式避免直接构造组合数,并在失败候选不足k时返回一。本文Java改写为对数与expm1累加,是同一组合表达的数值实现,不复制测试执行器,也不运行生成的任意代码。仓库master作为阅读入口,论文公式提供固定机制基线。
不能简单把这次观察到的 c/n 当成真实成功概率,再代入 1-(1-c/n)^k;它通常不同于前面的估计,n 小时偏差尤其值得注意。束搜索、看到反馈再重试、删除重复候选,也都会改变候选之间的关系。此时仍可计算当前候选池的组合比例,但若要把它解释为独立采样成功概率的无偏估计,就需要额外论证。
统计比较资料强调选择检验需匹配任务、指标和样本依赖。本文百分位bootstrap是明确的教学方案,不替所有基准规定唯一检验,也不把置信区间描述为“真值落入此区间的概率”。解释应回到重复抽样程序及其近似条件,尤其注意小样本与强依赖的局限。
代码先调用谁,再调用谁
- 为每题生成并验证n个候选
- 统计正确候选c
- 按目标k计算组合补概率
- 按任务单位聚合并比较方法
04动手写一个例子
稳定的有限候选pass@k
给定整数n、c、k,计算至少一次成功的无放回组合比例;非法计数拒绝,避免阶乘和相近浮点数直接相减。
- 输入 1
n=10,c=2,k=3- 输出 1
0.5333333333333333
- 输入 2
n=2000000000,c=1,k=1- 输出 2
5e-10
全失败概率的第i项分母是n-i,分子是n-c-i;两者比值等于1-c/(n-i)。乘k项即得到组合数比值。循环累积这些项的对数,最后还原补概率,因此不需要存储候选本身,也不需要任意精度阶乘。
第i次循环前logFailure等于前i项失败因子的对数和,添加当前项后保持不变量。若n-c小于k,全失败事件不可能发生;否则所有因子为正,log1p参数严格大于负一。c等于零独立处理,防止不必要计算,并使边界语义清楚。
有限双精度仍有舍入误差,但log1p和expm1对接近零的参数更稳定。测试包含极小成功概率并使用比普通容差更严格的断言,避免一个宽松绝对误差掩盖结果被算成零。循环时间O(k),空间O(1),不把验证候选的模型与测试运行成本算进本函数。
为什么这样写是对的完成i轮时logFailure是前i个无放回失败因子对数之和。
至多k次标量对数累加;提前返回分支为常数时间,固定字宽算术不构造组合整数。
保存为 Main.java,运行 javac --release 17 -encoding UTF-8 Main.java,再运行 java Main。程序包含固定输入自测,断言失败时会抛出错误。
import java.util.*;
public class Main {
static void near(double expected,double actual) {
if (!Double.isFinite(actual) || Math.abs(expected-actual)>1e-9*Math.max(1,Math.abs(expected)))
throw new AssertionError(expected+" != "+actual);
}
static void check(boolean ok) { if(!ok) throw new AssertionError(); }
static void bad(Runnable r) {
try { r.run(); } catch(IllegalArgumentException e) { return; }
throw new AssertionError("invalid input accepted");
}
static double passAtK(int n,int c,int k) {
if(n<1||c<0||c>n||k<1||k>n) throw new IllegalArgumentException("counts");
if(c==0) return 0;
if(n-c<k) return 1; // 失败候选不足k个,任何无放回子集都含成功项。
double logFailure=0;
for(int i=0;i<k;i++) logFailure+=Math.log1p(-(double)c/(n-i)); // 累加对数乘积,避免组合数与阶乘溢出。
return -Math.expm1(logFailure); // 失败概率接近一时,避免直接一减exp的消减误差。
}
public static void main(String[] args) {
near(1-56.0/120,passAtK(10,2,3));
near(0,passAtK(10,0,3));
near(1,passAtK(10,10,3));
near(1,passAtK(10,2,9));
near(.2,passAtK(10,2,1));
check(Math.abs(passAtK(2_000_000_000,1,1)-5e-10)<1e-22);
bad(()->passAtK(10,2,0));
bad(()->passAtK(10,11,2));
System.out.println("PASS 8 cases");
}
}
这些特殊情况也要试一试
- c零直接返回零
- 失败数不足k直接返回一
- 极小成功概率使用expm1
- k大于n或零拒绝
进阶选读 · 多层随机性的研究比较
场景题目来自不同仓库,候选又由多个随机种子生成。
做法预注册主指标与比较方法,按真实独立层次重采样,保留同题配对;额外报告单次成功、调用成本和选择器准确率。
复杂度B次重采样、N题的均值统计O(BN),若每次还重采候选则另乘每题样本规模。
好处与代价更完整方差模型提高解释力但需要更多数据;探索很多配置再选最好者仍产生选择偏差。
05项目里怎么用
评估配置应固定温度、候选数、超时和判定器版本。增加k通常增加预算,方法A的pass@10不能直接与B的pass@1称作同成本提升。若实际服务只有一次机会,主指标应包含pass@1或真实选择策略的成功率;能够事后知道哪个候选通过是一项额外能力假设。
报告效果时区分统计可检测差异与实际价值。一个很小但稳定的提升可能抵不过成倍延迟,某些关键类别退化也可能被总体平均掩盖。应给差值、区间、样本数和任务分层,并记录是否因看过结果而修改k或筛选题目,避免用事后挑选制造优势。
对同一保留集反复试很多方案,会逐渐把它变成开发集,即使每次都计算区间也无法修复选择偏差。最终结论需在冻结方案后确认,必要时保留新的测试集或校正多重比较。本文合成六题没有真实语言模型候选,所得区间只是统计代码证据,不是新方法有效性的实验结果。
容易踩的坑
- pass@k被写成单次可靠性
- 把c
/n直接代入非线性式称无偏 - 同题候选被当独立任务
- k超过n仍外推
- 只报告最佳种子与显著结果
几种做法,怎么选
表格有四列,窄屏可左右滑动查看代价和适用条件。
| 方案 | 优势 | 代价与限制 | 适用条件 |
|---|---|---|---|
| pass@1 | 接近一次尝试能力 | 忽略多样候选潜力 | 单次调用产品基线 |
| pass@k | 衡量多候选可解性 | 依赖更多预算与验证 | 程序生成及可验证搜索 |
| 配对任务区间 | 利用共同题目难度 | 仍依赖抽样单位和样本覆盖 | 固定题集方法比较 |
06检验是否读懂了
先自己想、自己写,再展开答案核对。场景题是假设的练习情境;遇到还没学过的内容,可以做完基础后再回来。
先用自己的话解释
01给定池比例与总体估计区别?
展开参考答案与推导
前者是组合计数事实,后者还依赖原始候选的抽样假设。
02为什么用配对bootstrap?
展开参考答案与推导
同一题的两方法结果相关,应共同抽取以保留题目难度关系。
03置信区间包含零说明相同吗?
展开参考答案与推导
不能证明相同,只说明此数据与方法下未排除零差异,仍需看区间宽度和实际阈值。
换个情况,还会处理吗
01pass@10提高但线上没变?
展开参考答案与推导
检查服务是否能生成十个候选并正确选择,比较同预算实际成功。
02很多题共享同一模板?
展开参考答案与推导
考虑按模板聚类抽样,避免夸大独立样本数。
03只某个种子明显领先?
展开参考答案与推导
报告预定多个种子分布,检查训练与采样方差,不挑最好一次。
写代码试一试
01计算组合比例。
- 输入 / 条件
n10,c2,k3- 输出 / 预期
1-56/120
提示 先数全失败子集
展开参考答案与推导
总子集C10,3,失败子集C8,3,取补。
02改进极小概率精度。
- 输入 / 条件
失败概率接近一- 输出 / 预期
保持非零小成功概率
提示 log1p与expm1
展开参考答案与推导
累加失败对数后用-expm1计算补值。
03构造配对重采样。
- 输入 / 条件
两方法每题结果数组- 输出 / 预期
差值均值分布
提示 共同抽索引
展开参考答案与推导
每个抽中的题同时取A和B,再计算该次均值。
读完之后,独立完成
课后作业:自己做一遍
本篇共 12 道作业,先完成 9 道基础与综合任务,再按前置知识挑战进阶题。其中包含 2 道思维拓展,试着换个条件,看看原来的办法是否还管用。不附参考答案。
Java稳定计算组合概率;Python枚举小集合校验公式,并生成按题目配对的bootstrap差值区间。
本篇重点加练
候选预算、采样依赖和结果选择共同决定 pass@k 的含义,需要额外检查高分来源。
- pass@k定义与候选预算
- 独立同分布假设
- 重复比较与选择偏差
重点内容会多练几次。先说清楚怎么做,再试试空数据、出错或条件改变时会发生什么。
先自己做,卡住时记下问题,再回来查。问答题写清“为什么、什么时候适用”;动手题留下输入、输出和运行步骤,方便下次重做。
基础必做
- 作业 01原理问答
区分“固定候选池至少一个成功的组合比例”与“采样策略生成 k 次的总体成功概率”,列出将二者联系起来所需的假设。
- 提交内容
- 估计对象与假设表
- 怎样算完成
- 候选预算明确
- 相关采样限制说明充分
练到的知识点pass@k定义与候选预算 · 无放回组合估计 · 独立同分布假设
- 作业 02代码推演
某题采样 n=8 个候选,其中 c=3 个成功,分别讨论 k=1、3、8 的组合计算;再审查 n<k 和 c=0 的输入契约。
- 提交内容
- 手算记录与边界表
- 怎样算完成
- 组合定义完整
- 非法与合法极端分开
练到的知识点无放回组合估计 · 数值稳定log1p与expm1
- 作业 03原理问答
某系统把同一个候选复制十次并称为十次生成。定义固定候选池统计和生成过程成功概率,审查重复样本分别影响什么。
- 提交内容
- 两个估计对象与依赖图
- 怎样算完成
- 候选身份与调用次数分开
- 独立性假设显式
练到的知识点pass@k定义与候选预算 · 独立同分布假设
综合应用
- 作业 04编程实践
实现 CPU pass@k 汇总器,支持逐题不同 n 并拒绝不合法 k;对小候选池使用穷举子集独立核对。
- 提交内容
- 实现及穷举检验
- 怎样算完成
- 每题有效性检查完整
- 宏平均分母可追踪
练到的知识点无放回组合估计 · 数值稳定log1p与expm1 · 按题目宏平均
- 作业 05排错实验
生成共享模板的相关题目,比较逐题与按模板配对重采样的差值区间;固定方法 A
/B的逐题配对身份。- 提交内容
- 模拟数据与区间报告
- 怎样算完成
- 方法配对关系保留
- 推断单位与相关结构一致
练到的知识点独立同分布假设 · 配对bootstrap
- 作业 06面试场景
某模型只在 pass@20 上提升,但用户每次只使用一个答案。设计评价与决策报告,列出候选选择成本和实际使用条件。
- 提交内容
- 指标与使用场景映射
- 怎样算完成
- 预算可比
- 统计变化与实用价值分开
练到的知识点pass@k定义与候选预算 · 重复比较与选择偏差 · 统计与实际效果
- 作业 07编程实践
CPU 模拟相同单次成功率但不同候选相关性的两种采样过程,重复 300 个任务,比较至少一次成功的频率与独立采样预测。
- 提交内容
- 模拟器与频率报告
- 怎样算完成
- 边际成功率受控
- 相关结构可复现
练到的知识点pass@k定义与候选预算 · 独立同分布假设
- 作业 08设计评审
系统为容易题生成二个候选、困难题生成二十个,报告总体 pass@5 时又删除候选不足的题。制定完整任务账本和合法比较协议。
- 提交内容
- 预算及缺失样本审计
- 怎样算完成
- 预定任务都有去向
- 条件选择不被隐去
练到的知识点pass@k定义与候选预算 · 重复比较与选择偏差
- 作业 09排错实验
对相同真效果模拟二十组配置,只保留观察最好的一组;比较选择数据上的结果与独立新样本上的结果,不改变选择规则。
- 提交内容
- CPU 选择偏差实验
- 怎样算完成
- 筛选过程固定
- 独立评价真实隔离
练到的知识点重复比较与选择偏差
进阶挑战 · 掌握前置后选做
- 作业 10设计评审
预注册两个方法、两个 k 和多个种子的比较计划,规定主指标、探索指标、重采样单位及停止规则;用合成数据跑通分析。
- 提交内容
- 分析计划与 CPU 演练
- 怎样算完成
- 选择偏差受约束
- 演练结果不当真实模型结论
练到的知识点配对bootstrap · 重复比较与选择偏差 · 统计与实际效果
思维拓展
先写出你的猜想,再用例子或实验验证。答案可以不同,但要说清依据、适用情况,以及还有什么没弄懂。
- 作业 11思维拓展 · 跨域迁移
将 pass@k 迁移到多个解题者协作:各人准确率相同但错误高度相关时,增加人数的收益能否由单人准确率决定?构造两种联合结果分布。
- 提交内容
- 联合分布与收益比较
- 怎样算完成
- 分布边际一致
- 相关性而非人数被单独检验
练到的知识点pass@k定义与候选预算 · 独立同分布假设
- 作业 12思维拓展 · 开放探究
在固定总生成 token 预算下,选择更多短候选还是更少长候选?提出可证伪研究问题,预先定义候选可执行性、选择规则和保留任务。
- 提交内容
- 研究预注册与成本表
- 怎样算完成
- 总预算可对账
- 试验前明确主比较
练到的知识点pass@k定义与候选预算 · 重复比较与选择偏差
完成后,再检验一次
给每题标记“独立完成 / 查阅后完成 / 尚未完成”。查过资料或没做出的题,记下卡在哪里。隔一天换一组输入再试,能解释结果和出错原因,再把这个知识点标为掌握。
继续阅读
先看能帮你完成当前练习的部分。例子跑通后,再读更深入的解释。
- 必读参考文档英文
pass@k原论文 (新标签页)↗
阅读公式一和附录A的无偏估计假设。
- 实践参考文档英文
HumanEval估计实现 (新标签页)↗
对照
estimate_pass_at_k的乘积及边界处理。 - 深入参考文档英文
统计显著性检验指南 (新标签页)↗
学习检验选择与指标、样本结构之间的关系。