返回 AICAP-180
B12 · Day 114RLVR + 模型策略 memo

实验设计基础

前三天(111-113)把奖励侧(RLVR / reward hacking / GRPO)讲透了。今天换轨到评测侧的因果地基:base-vs-tuned 不是「跑两次比大小」,而是一个因果实验——要先定假设、控变量、算最小样本量。这是 B1→B18 曲线上「会跑 eval」走向「会设计能下结论的 eval」的一跳。本日的杀手锏是直接吸取一个已落地的真实教训:A/B(V4-Pro vs V4-Fl

阶段: B12 · RLVR + 模型策略 memo(Day 111-120) 标签: #experiment-design #sequential-testing #power-analysis #ab-test

今日导引(由浅入深)

前三天(111-113)把奖励侧(RLVR / reward hacking / GRPO)讲透了。今天换轨到评测侧的因果地基:base-vs-tuned 不是「跑两次比大小」,而是一个因果实验——要先定假设、控变量、算最小样本量。这是 B1→B18 曲线上「会跑 eval」走向「会设计能下结论的 eval」的一跳。本日的杀手锏是直接吸取一个已落地的真实教训:A/B(V4-Pro vs V4-Flash)在 N=29 时 Δ+10.3pp、95% CI [0.0, 20.7] 跨 0,功效不足——把这个 N 写进协议,估算需 ~70 任务才有把握。最小可判定产出:一份 exp-protocol.md,含 H0/H1、唯一变量、n≈70、Δ 判定阈值。

1. 机理精读

base-vs-tuned 是因果实验。 我们想回答的因果问题是:「调优(处理)是否导致准确率提升(结果)」。要让 Δ 能干净归因到「模型」这一个原因,必须把实验设计成:唯一变量 = 模型权重,其余全固定。

假设检验框架。

  • H0(零假设):两模型准确率无差(Δ = 0)。这是「默认无效」立场——除非证据足够强,否则不能宣称 tuned 更好。
  • H1(备择假设):tuned 更优(Δ > 0,单侧)或 Δ ≠ 0(双侧)。单侧检验功效更高(只关心一个方向),但前提是你事先确定只关心「tuned 是否更优」,不能跑完看方向再决定单双侧(那是 p-hacking)。
  • 实验的产出是「在给定显著性水平 α(假阳率,常 0.05)和功效 1−β(真阳检出率,常 0.8)下,是否有足够证据拒绝 H0」。
  • 两类错误:Type I(α,把无差异误判为有差异)和 Type II(β,把有差异误判为无差异)。N=29 的教训是典型的 Type II——真有 +10.3pp 差异,但样本不够检不出来。

控制唯一变量。 除「模型」外,所有可能影响结果的因子都要固定:

  • seed:采样随机种子,固定才能复现。
  • 温度:建议 0,关掉采样噪声。
  • prompt 模板:同一套 system/user。
  • grader 版本:codeCheck + judge prompt + 任务集。
  • 任务集:base 与 tuned 必须跑同一批 tasks.ts(配对设计的前提)。

任何一个变了,Δ 就被混杂变量污染——你以为测的是模型差异,实际测的是「模型 + 温度 + prompt」的混合效应。这也是明天 Day 115(base 基线复现性纪律)和 Day 116(tuned 对照只换权重)的核心约束。实验设计的第一性原理就一句话:让因(模型)和果(Δ 准确率)之间,除了你要研究的那个变量,没有别的通路。

最小样本量(power analysis)。 N 太小会导致即使真有差异也测不出来(功效不足),表现为 CI 跨 0、p 值不显著。给定要检测的效应量 Δ 和配对差的标准差 sd_diff,所需配对样本量(α=.05 双侧、power=.8)近似为:

n = ((z_{α/2} + z_β) · sd_diff / |Δ|)²

其中 z_{α/2}=1.96(双侧 α=.05)、z_β=0.842(power=.8)。本仓 src/agent/eval/stats.tsrequiredNForDelta(delta, sdDiff) 就是这个公式的实现——这正是「N=29 → 需 ~70」估算的来源。

固定样本 vs 序贯检验。

维度固定样本检验序贯检验(always-valid p)
何时看结果跑满 n 后只看一次任意时刻可看
偷看(peeking)会膨胀假阳率p 值任意停止时刻都有效
单位样本功效较高略低(为换取随时可停)
适用离线一次跑批(b12-base/tuned)线上持续 A/B、要随时决策
  • 固定样本检验:先定死 n,跑满 n 个样本后只看一次结果。优点:统计性质干净。缺点:不能边跑边看——中途偷看并据此停止(peeking)会膨胀假阳性率。
  • 序贯检验(always-valid p-value):允许在任意时刻查看并据此停止,p 值在任何停止时刻都保持有效(不膨胀 α)。优点:能边跑边看、提前停止省成本;代价是单位样本的功效略低于固定检验。Statsig(2026-01)的 Sequential Testing 是现役 online-eval 方法。
  • 取舍:离线一次性评测(如 b12-base/tuned 跑批)用固定样本即可;线上持续 A/B(要随时看、随时可能上线决策)用序贯。本批次的 b12 base-vs-tuned 是离线一次跑批,所以协议默认固定样本 + 预算 n≈70。

N=29 教训的本质。 已落地 A/B 在 N=29 时 Δ+10.3pp 看似可观,但 95% CI [0.0, 20.7] 触 0 → 不能拒绝 H0 → 不显著。拆解原因:

  • 效应量 Δ=+10.3pp(约 0.103);
  • 配对差方差不小(3 wins / 0 losses / 26 ties,差值分布稀疏但有方差);
  • 在这个效应量与方差下,29 个任务的功效远低于 0.8;
  • requiredNForDelta 估算约需 ~70 任务才有 80% 把握检出该效应。

这就是为什么协议必须把 n≈70 写死——先算 N,再跑实验,而不是跑完发现不显著再补样(补样本身就是 peeking)。这条教训直接来自真实 pnpm eval:ab 的产出,不是教科书假设。

2. 推导 / 手算 / 代码走读

src/agent/eval/stats.ts 走读(实验设计的数学底座):

  • requiredNForDelta(delta, sdDiff)(第 59-65 行):实现上面的功效公式。zAlpha=1.959963985(双侧 α=.05)、zBeta=0.841621234(power=.8);返回 Math.max(2, Math.ceil(((zAlpha+zBeta)*sdDiff/|delta|)²))delta=0 返回 Infinity(无差异不可能检出),sdDiff<=0 返回 2(无方差则平凡可检)。→ 把 N=29 实测的 sd_diff 和 Δ=10.3pp 代入,得出 ~70 这个数。
  • pairedBootstrap(a, b, opts)(第 36-55 行):配对 bootstrap,diffs = a.map((x,i)=>x-b[i]),重采样 iters(默认 2000)次估 deltaMeanci95=[percentile(means,2.5), percentile(means,97.5)]。→ 这是产出「Δ+10.3pp、CI[0.0,20.7]」的同款算法(abCompare.ts 调它)。
  • mean/sd(第 5-15 行):sdn-1 分母(样本标准差),n<2 返回 0。

手算示例(为什么 N=29 测不出 +10.3pp): 设配对差的标准差 sd_diff ≈ 0.27(与「3 wins/0 losses/26 ties、Δ=0.103」量级一致:26 个 0、3 个 1,均值≈0.103,样本 sd≈0.31 量级)。代入:

  • n = ((1.96 + 0.842) × 0.31 / 0.103)² = (2.802 × 0.31 / 0.103)² = (8.43)² ≈ 71
  • → 约需 71 个配对任务才有 80% 功效,而我们只有 29 个 → 功效严重不足 → CI 触 0。这与 seed 里「~70 任务」估算吻合。(注:精确值取决于实测 sd_diff,此处为说明量级的手算。)

为什么配对设计更省样本。 pairedBootstrap同一批任务的 base/tuned 求逐任务差值 a[i]-b[i],消除了「任务本身难易」这个方差来源——比独立两样本(base 一组任务、tuned 另一组任务)功效高得多。所以 base 和 tuned 必须跑同一个 tasks.ts 任务集(明天 Day 116 的对照纪律)。

3. 今日实战

  1. exp-protocol.md,骨架如下:
# b12 base-vs-tuned 实验协议
- H0: base 与 tuned 准确率无差 (Δ=0)
- H1: tuned 更优 (Δ>0, 单侧)
- 唯一变量: 模型权重
- 固定: seed / 温度=0 / prompt 模板 / grader 版本 / tasks.ts 任务集
- 设计: 配对 (同一批任务跑 base 与 tuned), pairedBootstrap 求 Δ±CI
- 最小样本量 n: requiredNForDelta(Δ=0.103, sd_diff≈实测) → n≈70
- 判定阈值: 95% CI 不跨 0 且 Δ ≥ 阈值 → 拒绝 H0
- 检验方式: 离线一次跑批 → 固定样本 (非序贯)
- 防 peeking: 跑满 n 再看, 不中途加样
  • 最小样本量 n:用 requiredNForDelta 代入 N=29 实测的 sd_diff 与目标 Δ,写入 n≈70
  • Δ 判定阈值:声明「CI 不跨 0 且 Δ ≥ 阈值」才算显著提升(阈值数字按 power 估算写入)。
  1. 真实输入:src/agent/eval/abCompare.ts + scripts/ab-compare.tspnpm eval:ab)已产出的 N=29 结果(Δ+10.3pp、CI[0.0,20.7]、3 wins/0 losses/26 ties)。
  2. 把 N 扩到 ~70 = 待跑(需 key 跑更大任务集),协议先把目标 n 写死。

4. 今日实测 / 产出

  • 产出exp-protocol.md(含 n≈70 与 Δ≥? 阈值数字)。
  • 真实输入来自 src/agent/eval/abCompare.ts + scripts/ab-compare.tspnpm eval:ab已产出的 N=29 结果:Δ**+10.3pp**、95% CI [0.0, 20.7]、3 wins / 0 losses / 26 ties。
  • N 扩到 ~70 = 待跑(需 key 跑更大任务集)
  • requiredNForDelta / pairedBootstrap 为纯函数、已 built+tested;本日不引入新测量数字,n≈70 来自对已有 N=29 结果的功效估算。

5. 常见误区 / 陷阱

  1. 跑完不显著再补样本(peeking)。这正是 N=29 教训的根因——小 N 上用固定阈值 p 值反复偷看会膨胀假阳。要么先算 N、跑满再看(固定样本),要么用 always-valid p 值(序贯)。
  2. 报点估 Δ 不报 CI。+10.3pp 看着可观,但 CI[0.0,20.7] 触 0 就不能拒绝 H0。没有 CI 的 Δ 是无法下结论的数字。
  3. 混杂变量污染 Δ。温度/prompt/grader 任何一个跟着模型一起变,Δ 就不是「模型差异」而是混合效应。控制唯一变量是因果归因的前提。
  4. 用独立两样本而非配对。同一批任务做 base/tuned 配对能消除任务难易方差、大幅提功效;分两批任务跑会浪费样本。
  5. 把「不显著」当成「无差异」。N=29 不显著不代表 base=tuned,只代表样本不够下结论。「无证据 ≠ 证据无」——正确动作是扩 N 到功效足够,而非宣称两模型相同。
  6. 事后改单/双侧或改阈值。跑完看方向再选单侧、或看 Δ 再调阈值,都是 p-hacking。所有判定规则必须事先写进协议。

6. 学习资源(每条带 YYYY-MM)

  • Statsig《Sequential Testing》 — 2026-01(always-valid p-value、序贯 vs 固定样本取舍,现役 online-eval 方法)
  • Anthropic《Demystifying evals》— 2026-01(控变量、复现性、CI 报告纪律)
  • bootstrap 配对方法(经典统计)— 用于 pairedBootstrap 的 CI 估计
  • 本仓实现:src/agent/eval/stats.tsrequiredNForDelta 功效公式 + pairedBootstrap 配对 CI)、src/agent/eval/abCompare.ts + scripts/ab-compare.ts(N=29 真实 A/B 来源)

SOTA检查 (2026-06 更新)

  • 当前主流:always-valid / 序贯检验(Statsig 2026-01)为现役 online-eval 方法;离线一次性评测用固定样本 + power analysis 预算 N。配对 bootstrap CI 是当前报告 Δ 的标准形态。
  • 是否仍 SOTA:是。「先算 N、控唯一变量、报 Δ±CI」是 2026 严谨 A/B 的底线。
  • 过时黑名单
    • 不要在小 N 上用固定阈值 p 值反复偷看(peeking)——这是 N=29 不显著教训的根因;
    • 不要只报点估 Δ 不报 CI;
    • 不要把混杂变量当模型差异(温度/prompt/grader 必须锁死);
    • 不要把「不显著」误读为「无差异」(功效不足 ≠ 等价)。
  • 下次复查点:复查 Statsig Sequential Testing 文档版本(2026-01 之后是否有方法更新);待 key 跑出 ~70 任务集后,回填真实功效结果,验证 n≈70 估算是否准确。

衔接

  • 昨天:Day 113 — GRPO 奖励信号(组内归一化优势省 critic,5 任务奖励设计映射)
  • 今天:base-vs-tuned 是因果实验——定 H0/H1、控唯一变量、用 requiredNForDelta 算出 n≈70,吸取 N=29 不显著的真实教训。
  • 明天:Day 115 — Base 模型基线(复现性纪律:固定 seed/温度/prompt/模型 id/grader 版本,base 分先于一切调优固化存档)