252 的正因數中,有多少個是偶數?Qwen3-0.6B 模型第一次只回答了 12,相當簡潔,而且答對了。接著我們讓同一個模型檢查這份答案,它列出一串正因數,也把 21 與 63 也放進偶數名單,最後很有自信地得到 13;修正版再忠實採納這段批評,交出 \boxed{13}。看到了嗎?原本答對的題目,經過一次自我反省,反而改錯了。
讓我們來複習一下國中數學,252 可以分解為 2^2 × 3^2 × 7。偶數因數至少要取一個 2,因此 2 的次方有兩種選擇,3 的次方有三種,7 的次方有兩種,總數是 2 × 3 × 2 = 12。修正後的答案沒有提到這樣的推理流程,乍看之下堆疊很多答案,數學內容卻更糟。這正是今天要檢查的問題:模型會生成一段 critique,和它真的有能力判斷對錯,是無法混為一談。
Self-Refine 在 2023 年被提出的一個直觀想法:先讓模型產生初稿,再由同一模型提供 feedback,最後根據 feedback 重寫。它不必更新權重,也不需要另外訓練 critic;在推論階段多走幾步,就可能發現首答漏掉的問題。Sebastian Raschka 的推理模型實作脈絡也把這類 inference-time refinement 放在訓練以前,因為它先問的是現有模型能否更有效地使用計算,而不是先假定權重一定要改。
這次實驗沿用前面凍結的 64 題 validation subset,以及公開 Day 12 的 greedy 首答。每一題再由同一個 Qwen3-0.6B-Base 模型依序生成 critique 與 revision,兩個階段都在 RTX 3090 Ti 上執行 deterministic greedy decoding:
first answer:沿用已保存的首答
critique:只能看到 problem + first answer
revision:只能看到 problem + first answer + critique
reference answer:生成完成後才交給 verifier
新增生成:64 critiques + 64 revisions = 128
tool calls:0
sealed-test inference:0
Revision prompt 有特別提示模型,critique 本身也可能有錯,要求它重新解題,最後以 \boxed{ANSWER} 收尾。第一次正式啟動甚至在生成前就被這個字串絆倒:Python str.format 把 {ANSWER} 當成不存在的欄位,留下 KeyError: 'ANSWER'。當時 heartbeat 仍是 0/64,也沒有寫入半套 chain;renderer 改成只替換 problem、first_answer 與 critique 後,正式 GPU run 才從頭開始。模型還沒來得及反省,程式先替自己做了一次 refinement。
64 題全部跑完後,結果如下:
首答 修正版
答對題數 6/64 8/64
符合 strict format 2/64 20/64
錯 → 對:4 題
對 → 錯:2 題
沒有可抽取答案的 revision:26 題
新增 critique + revision tokens:45,508
只看答對題數,修正版多了兩題。不過,同題配對 bootstrap 的 95% interval 是 [-0.046875, 0.109375],跨過 0;這批 validation 結果只能留下小幅正向點估計,還無法支持穩定改善。更何況,四個「救回」也不全是模型重新想通數學。
其中一題問五個 X、O 圖塊排成 XOXOX 的機率。首答已經寫出 1/10,只是沒有依 contract 放進方框,答案擷取器把最後的數字讀成 10,正式評分因此判錯。Critique 說原答案正確,revision 改寫成 \boxed{\frac{1}{10}},這才通過 verifier。這個題目確實由錯變對,主要修復的是機器可讀格式,而不是數學能力。
開頭的 252 因數題則有不同的發展,第一次回答的 12 原本通過 verifier,critique 卻自己製造錯誤,revision 還把它包成更華而不實的 \boxed{13}。另一題的首次回答也從正確的 4 被改成 \frac{1}{2}。Self-refinement 多給模型一次修正機會,也多給它一次覆蓋正解的機會;當 solver 與 critic 是同一個 0.6B 模型,兩者的錯誤很可能一起移動。
格式數字也出現類似的問題,strict-format answers 從 2 題增加到 20 題,另外有 26 份 revision 完全找不到可抽取答案;修正版輸出的中位數只有 7 tokens,只有 3 題碰到 256-token 上限。大量缺失並非模型想太久,而是它很快停下,沒有交出答案。Critique 則有 19/64 直接用滿 192 tokens。批評可以很長,修正也可以很短,篇幅依然沒有替正確性提供保證。
這兩個額外階段一共花了 45,508 tokens,換來 4 題修正正確與 2 題修正錯誤;我們在 validation 上,讓同一組權重多生成兩次,再用凍結的 verifier 評估最後答案。
回到最初那個 12,模型第一次沒有解釋,卻答對了;第二次寫出一段更像分析的批評,最後留下更工整的錯誤答案。Self-refinement 真正增加的是另一個生成後的解題思考方式,至於這個想法是否有價值或正確,仍得看題目、成本,以及我們手上有沒有比模型自我肯定更可靠的回饋。既然每題固定多跑兩次不一定划算,下一步自然要問:哪些題目值得多花這些計算?我們如何定義哪些題目容易、哪些困難?哪些可以少想、哪些應該多想?
看完最有感的是那句「模型會生成一段 critique,和它真的有能力判斷對錯,是無法混為一談」。252 因數題的例子太精準了——首答只寫 12、完全沒解釋,卻是對的;第二輪產出一段看起來更像分析的批評,最後留下更工整的錯誤。輸出的形式跟推理的可靠度,確實是兩件事。
特別欣賞你把 4 題「錯→對」拆開來檢查。XOXOX 那題其實是 answer extraction 把 1/10 讀成 10,revision 修好的是機器可讀格式而不是數學能力;少了這段拆解,只看 6/64 → 8/64 很容易就寫成「self-refine 有效」。再加上同題配對 bootstrap 的 95% CI 是 [-0.047, 0.109] 跨過 0,你選擇只留下「小幅正向點估計」,這種克制在鐵人賽裡真的不多見。
另外 critique 有 19/64 用滿 192 tokens、revision 中位數卻只有 7 tokens,這組對比很有意思:批評可以很長,修正可以很短,篇幅完全沒有替正確性背書。
我這屆剛好在隔壁棚做 self-consistency 的投票聚合(TACT),踩到的坑跟你同源:模型的信心跟正確性不一定同向,一旦方向反過來,「高信心加權」就會放大錯誤——就像 self-refinement 多給一次修正機會,也多給一次覆蓋正解的機會。我後來的處理是先在開發資料上估一個 γ,判斷信心到底有沒有預測力,證據不足就進入死區、退回無加權多數決,寧可不動也不要動錯。你文末問「哪些題目值得多花這些計算」,我覺得 gating 條件可能是同一件事:先問這題上,我們手上有沒有比模型自我肯定更可靠的訊號。
Day 4 我寫過「同樣是 0.9,為什麼不能直接拿來比」,做法是只在同一題內把信心轉成 rank 再標準化,刻意不去相信模型的絕對校準——跟你這篇「不要把 critique 的自信當成回饋」,大概是同一個直覺的兩種寫法。
期待 Adaptive compute 那篇,先追蹤了。
我的系列:從多數決到可信投票:30 天打造 TACT 大語言模型推理聚合方法
方法的完整推導與實驗:TACT: Trust-Anchored Confidence Tempering for Self-Consistency Voting in Large Language Models