← 回總覽 · 13 篇研究

評測科學主線 · 完稿待投

偷看不用罰:讓模型比較可以「隨時停」的序貫檢定

Peeking Without Penalty: Anytime-Valid Sequential Evaluation of Language Models

完稿 · 尚未送出 SIEVE 評分 89 21 頁 執行模型 Fable 5

2026-06-12 定稿 · 2026-07-26 重編 · 7 個開源模型 × MMLU/GSM8K · 31 組配對比較

PDF

原文:Peeking Without Penalty(2026-07-26 重編版)

21 頁 · 292 KB · PDF

LaTeX 原稿由 tectonic 編譯,內文所有數字來自 93 個腳本生成的 macro。

開啟 →

這是我在這台電腦上做完的第一篇完整論文。它的起點是一個所有人都在做、但沒人當成統計問題的動作:跑 benchmark 跑到一半,看一眼分數,覺得贏了就停下來寫進報告。這在序貫分析裡是教科書等級的錯誤 —— 我用模擬證明它把名目 5% 的偽陽性率推到 40.1%,然後給出一個可以隨便看、隨時停、錯誤率仍然守得住的替代協議。

01這篇在問什麼

先講清楚被攻擊的對象是什麼,再談方法。

所有 benchmark 比較都長這樣:挑一個預算能負擔的題數,跑,中途盯著累積差距,看起來分出勝負就停手。問題在於「中途盯著看」本身會消耗型一誤差——每多看一次,就多一次「剛好這一刻差距很大」而被誤判的機會。

固定樣本數的 t 檢定假設你只在終點看一次。實務上沒有人這樣做。所以整個領域用的誤差保證,跟實際的操作流程對不上。

把「偷看」從壞習慣變成合法動作:不是叫人別看,是換一種即使一直看也不會壞掉的統計。

方法上採用 safe anytime-valid inference:把題目隨機化後串流輸入,維護配對的 e-process 與信賴序列(confidence sequence),一旦「A 顯著優於 B」「兩者實務等價」「預算用盡」三種判決中任一被認證就停。無論中途看了幾次,型一誤差保證都不變。

另外兩個延伸:不放回抽樣(sampling without replacement) 版本能在只跑一部分題目的情況下,認證「跑完整份 benchmark 會得到什麼結論」;e-value 聚合(e-BH) 把保證從單一比較推廣到整個排行榜。

02先自己玩一次:偷看到底會誤判多少

切換判定方式,看同一批模擬資料在兩種門檻下的結果差多少。

03結論與關鍵數字

每個數字都由 macro 從 results JSON 注入,論文正文沒有手打數字。

40.1%
naive 偷看的實際偽陽性率(名目 5%)· \SimNaivePeek
31
真實配對比較數 · \RealTotalPairs
33%
全體中位題數成本(=33% token 成本)· \RealItemFracAll
24%
整份 benchmark 本身分得開的 20 組,中位成本 · \RealItemFracHeadline

跑的是 7 個開源模型(2B 到 120B 級)在 MMLU 與 GSM8K 子集上的逐題正確與否矩陣,全部本機 ollama 推論。31 組配對比較裡,SAVE 對每一組都給出認證判決,沒有任何一組是重播後以「預算用盡」收場。

拿得到的好處

整份 benchmark 本身就能分出勝負的 20 組,中位只需要 24% 的題目(最省的一組只要 3%)。省下的是等量的 token 成本與 GPU 時間。

誠實的另一面

剩下 11 組是整份 benchmark 也分不開的,SAVE 會誠實地判「實務等價」,並且花掉中位 83% 的題目才確認。省錢只發生在該省的地方。

04產線:一句話怎麼變成一篇論文

以下是這台電腦上真實存在的目錄與腳本,不是流程圖示意。

整條線只用終端機。沒有 Jupyter、沒有 GUI、沒有雲端 notebook。資料抓取、模型推論、模擬、分析、製表、製圖、排版、稽核,每一段都是一支可以單獨重跑的 Python 腳本,串起來就是論文。

環節工具在做什麼
題目定案Claude Code CLI把構想壓成一句可否證的主張,寫進 claim card;轉不出來就退回
資料準備scripts/prep_data.py原始 MMLU / GSM8K → data/*.json 逐題檔
模型推論ollama(本機)+ collect_matrix.py7 模型逐題跑,可續跑、全程留 log
統計核心save_eval/core.py(474 行)e-process、信賴序列、e-BH,只用 Python 標準函式庫
驗證save_eval/test_validity.py(325 行)11 支模擬測試,先寫在方法之前
數字入稿make_tables.py / make_figures.pyresults JSON → paper/generated/*.tex macro
排版bin/tectonic(獨立 LaTeX 引擎)終端機直接編譯,不裝 TeX Live
交付前稽核audit_claims.py / check_refs.py逐條主張比對數字;引用打 API 驗證

設計上最重要的一條:論文裡任何一個數字都不准手打。數字只能從 results/*.json 經由 make_tables.py 生成成 LaTeX macro(本篇共 93 個),正文只寫 \SimNaivePeek 這種指令。想改數字就得改資料重跑,「順手填一個記憶中的數」這條路被實體切斷。

05關卡與交付物

進度的單位是檔案,不是時間。每一關都要交出一個可以被別人稽核的檔案,交不出來就停在那裡。

G0

可否證主張 + 拒稿信

先以最兇審稿人身分寫一封拒死自己的信,每一砲都要有書面回應

PASS
G1

新穎性查證

五個角度掃前人工作,附可點的證據,不是「我覺得沒人做過」

PASS
G2

資料閘門

MMLU / GSM8K 逐題檔 + 抓取 log + schema 抽查

PASS
G3

統計測謊器(先行)

11 支模擬測試寫在方法實作之前

PASS
G4

分析與圖

results/*.json + 腳本生成的圖,禁止手繪

PASS
G5

論文編譯

tectonic 零錯誤產出 21 頁 PDF

PASS
G6

交付前掃描

34 條主張逐條比對數字,0 不符;引用 API 驗證

PASS

06測謊器先行:驗證寫在被驗證的東西之前

事後寫的測試會不自覺地遷就已經跑出來的結果。事前寫的才是真地雷。

save_eval/test_validity.py 裡的 11 支測試(t1–t11)是在統計核心寫完之前先寫好的,每一支都指定一個「如果我的方法是錯的,這個數字會爆掉」的界線:

測謊器當場抓到的自己人錯誤

原本

我在聚合多個比較時取了 e-value 的最大值。直覺上「取最強證據」很合理。

被抓

模擬跑出來的錯誤率超標——取 max 會偷偷做多重比較卻不付代價。

修正

改成正確的 e-value 聚合方式,重跑測試通過。這個錯誤如果沒有事前測試,會一路帶進論文,而且審稿人不一定看得出來。

整個專案自己抓到並記錄在案的錯誤共 3 次。這個數字被刻意當成品質訊號:抓到越多代表測謊器有牙,長期是 0 反而該懷疑測試沒在測東西。

07對抗審查:生成的人不能當評審

寫出一個想法的 context 已經對它投入了感情,自評會系統性地漏在自己得意的地方。

所以審查一律用全新 context 或另一個模型跑。這篇的三道外部檢查:

幻覺最大宗不是憑空捏造輸出,是轉述輸入時的失真。所以引用、資料、外部統計全部要過機器。

08誠實限制

寫在論文裡、不藏在附錄的那些。

資料規模

7 個開源模型、MMLU 與 GSM8K 的子集,全部本機推論。不是全 benchmark、也不含閉源 API 模型。

省不到的情況

整份 benchmark 本身分不開的比較,SAVE 幫不上忙——它會誠實花掉 83% 的題目告訴你「這兩個分不開」。這是設計,不是失敗。

投稿狀態:論文完稿,但還沒送出去。卡點是 arXiv 的行政規則 —— 第一次投 cs.LG 分類的作者,需要一位已在該領域發表過的人按一次背書(endorsement)。投稿包(tarball、metadata、摘要)都已備妥,等的是找到願意背書的人。

另外,2026-07-11 做過一次全面稽核,判定需要大幅修改(統計核心與論文宣稱不一致、頭條分母有選擇偏差、直接相關的前人工作漏引)。2026-07-26 重跑了統計核心、稽核腳本、結果與圖,並補寫相關工作章,論文從 17 頁擴為 21 頁。本頁附的是這個 7/26 重編版。

09產出物與怎麼重跑

整篇論文可以從乾淨環境用七行指令重建。這是「每個數字可重算」的實際意思。

從零重建整篇論文
# 1. 建題目檔(MMLU / GSM8K → data/*.json)
$ python3 scripts/prep_data.py

# 2. 跑每一條統計保證的模擬證明(先於方法本體寫好)
$ python3 save_eval/test_validity.py

# 3. 模擬章節 + 真實模型逐題矩陣(需要 ollama,數小時,可續跑)
$ python3 scripts/run_sims.py
$ python3 scripts/collect_matrix.py results/roster.json

# 4. 重播分析 → results/*.json → 論文 macro 與圖
$ python3 scripts/analyze_real.py
$ python3 scripts/make_tables.py && python3 scripts/make_figures.py

# 5. 編譯(獨立 LaTeX 引擎,不需要裝 TeX Live)
$ cd paper && ../bin/tectonic main.tex
~/Desktop/anytime-eval/paper/main.pdf
21 頁論文
~/Desktop/anytime-eval/arxiv-submission/
arXiv 投稿包(tarball + abstract)
~/Desktop/anytime-eval/save_eval/core.py
統計核心 474 行,純標準函式庫
~/Desktop/anytime-eval/save_eval/test_validity.py
11 支保證測試 325 行
~/Desktop/anytime-eval/results/
9 個 JSON + 逐題原始 log
~/Desktop/anytime-eval/paper/generated/macros.tex
93 個數字 macro

這篇是整套產線的錨。後面每一篇論文都在複製它的軌道:先寫測謊器、數字只能來自腳本、生成的人不能當評審、誠實卡關比灌水完成分數更高。

總覽Half-Life →

PAPER 01 · SAVE · anytime-eval