第 3 章 · 用 Twinkle-Eval 評測選擇題¶
本章你會學到
- 為什麼要評測、為什麼常用選擇題
- 選擇題評測的三大陷阱:位置偏好、答案不穩定、答案難抽取
- Twinkle-Eval(APMIC × Twinkle AI 開發)如何一一破解
- 動手做:從安裝到看懂分數的完整流程,含真實指令與設定檔
關於本章的工具
本章所有指令、設定檔與參數都取自 Twinkle-Eval 官方 repo(MIT 授權)。它由 Twinkle AI 與 APMIC 共同開發。
3.1 為什麼要評測?為什麼用選擇題?¶
模型訓練完(第 1、2 章),老闆一定會問:「所以,它到底行不行?」
要回答這題,不能靠感覺,得靠評測(Evaluation)——給模型一張標準考卷,量化打分,讓不同模型能在同一把尺上比較。
選擇題是最常用的考法,因為它:
-
好自動改
答案只有一個字母(A/B/C/D),電腦一比就知道對錯,不需要人工評分。
-
好比較
大家考同一份卷(如 TMMLU+),分數可直接橫向比較、排行榜。
-
覆蓋廣
一份卷可涵蓋醫學、法律、數學……幾十個科目,一次量出「知識廣度」。
選擇題長這樣
題目:水在標準大氣壓下的沸點是幾度? (A) 0°C (B) 50°C (C) 100°C (D) 200°C
正確答案:C
看起來很單純——把題目丟給模型,看它選什麼,對就得分。但魔鬼藏在細節裡。
3.2 選擇題評測的三大陷阱¶
如果評測工具做得太天真,分數會被灌水或失真。這是本章最重要的觀念,跨部門同事一定要懂:看到一個評測分數,先問它有沒有避開這三個坑。
陷阱一:位置偏好(Position Bias)¶
LLM 有個怪毛病:會偏愛某個「位置」的選項,例如不管內容是什麼,都比較容易選 (A),或傾向選最長的那個。
後果
如果一份考卷的正確答案剛好大多放在 (A),一個「愛選 A」的爛模型也能考出假高分——它根本不是真的懂,只是賭對了位置。
陷阱二:答案不穩定(Instability)¶
LLM 是機率性的,同一題問兩次,可能給不同答案。尤其 2025 年後的推理模型,每次「思考路徑」都不同。
後果
只考一次得到的分數,可能是運氣。今天考 85 分,明天可能 79 分。單次分數不可靠,你需要知道它的「穩定度」。
陷阱三:答案難抽取(Answer Extraction)¶
模型不會乖乖只回一個字母,它可能回一整段:
「這題我認為應該選 C,因為水的沸點……」
工具得從這段話裡準確抽出「C」。抽錯了,明明答對也被判錯。
3.3 Twinkle-Eval 如何破解這三個坑¶
這正是 Twinkle-Eval 的設計重點。它用四個機制回應上述問題:
flowchart TD
subgraph 陷阱
T1["① 位置偏好"]
T2["② 答案不穩定"]
T3["③ 答案難抽取"]
T4["⏳ 評測太慢"]
end
subgraph Twinkle-Eval 的對策
S1["🔀 隨機打亂選項順序<br/>shuffle_options"]
S2["🔁 重複執行多次 + 算標準差<br/>repeat_runs"]
S3["🎯 三種答案抽取法<br/>pattern / box / logit"]
S4["⚡ 並行呼叫 API<br/>比逐題快 9–17 倍"]
end
T1 --> S1
T2 --> S2
T3 --> S3
T4 --> S4
style S1 fill:#e8f5e9,stroke:#2e7d32
style S2 fill:#e8f5e9,stroke:#2e7d32
style S3 fill:#e8f5e9,stroke:#2e7d32
style S4 fill:#e8f5e9,stroke:#2e7d32
| 機制 | 設定 | 解決什麼 |
|---|---|---|
| 選項隨機排列 | shuffle_options: true |
打亂 A/B/C/D 順序,讓「愛選某位置」的模型現形,消除位置偏好 |
| 多次執行 + 標準差 | repeat_runs: 3 |
同一份卷考多次,回報平均分與標準差,量化穩定度 |
| 三種答案抽取法 | evaluation_method |
針對不同回答格式,用對的方法精準抽答案 |
| 並行 API 呼叫 | 內建 | 用 ThreadPoolExecutor 同時送多題,實測比逐題的 ievals 快 9–17 倍 |
標準差在講什麼?(給非統計背景的同事)
重複考 3 次,若分數是 84、85、83(標準差小)→ 模型很穩,這個分數可信。 若是 78、86、72(標準差大)→ 模型很飄,這個分數要打折看。 「平均分高」還不夠,「標準差小」才代表真的可靠。 這是 Twinkle-Eval 特別強調的價值。
3.4 三種答案抽取法怎麼選?¶
Twinkle-Eval 的選擇題評測提供三種 evaluation_method:
要求模型把答案包在 \boxed{} 裡,例如回答 \boxed{C},工具再從中抽出 C。
- 優點:格式明確、好抽、最不容易誤判。
- 做法:在
system_prompt裡要求模型「以\box{選項}格式回答」。
用正則表達式從模型的自由回答裡比對出答案字母。
- 優點:不強制模型用特定格式。
- 缺點:模型回答格式一亂就可能抽錯。
不看模型「寫」什麼,而是直接比較各選項 token 的對數機率(log probability),機率最高的就是模型的選擇。
- 優點:完全免抽取、免解析,最客觀。
- 限制:需要模型端點支援回傳 logit 的 completions API。
怎麼選?
- 剛上手、用一般 Chat API → 用
box。 - 想要最嚴謹、端點支援 logit → 用
logit。
3.5 動手做:完整評測流程¶
flowchart LR
A["1️⃣ 安裝<br/>pip install"] --> B["2️⃣ 部署模型端點<br/>OpenAI 相容 API"]
B --> C["3️⃣ 產生設定範本<br/>--init"]
C --> D["4️⃣ 下載資料集<br/>--download-dataset"]
D --> E["5️⃣ 編輯 config.yaml"]
E --> F["6️⃣ 試跑<br/>--dry-run"]
F --> G["7️⃣ 正式評測<br/>--config"]
G --> H["8️⃣ 看懂結果"]
style A fill:#e3f2fd,stroke:#1565c0
style H fill:#e8f5e9,stroke:#2e7d32
步驟 1:安裝¶
不需要 GPU
Twinkle-Eval 本身只負責「出題、收答案、算分」,運算都在模型端點那邊。它透過 API 呼叫模型,所以在一般筆電上就能跑。
步驟 2:準備一個「OpenAI 相容」的模型端點¶
Twinkle-Eval 透過標準的 OpenAI 相容 API 去呼叫你的模型。你的模型可以是:
- 本機用 vLLM / SGLang / Ollama 等部署的自架端點(例如
http://localhost:8000/v1)。 - 或任何提供 OpenAI 相容 API 的雲端服務。
你需要拿到兩個東西:端點網址(base_url) 和 API 金鑰(api_key)。
步驟 3:產生設定範本¶
這會生出一份 config.yaml 範本讓你填。
步驟 4:下載評測資料集¶
# 看有哪些資料集可下載
twinkle-eval --download-dataset list
# 下載繁體中文的 TMMLU+(台灣最常用的中文選擇題 benchmark)
twinkle-eval --download-dataset tmmluplus
# 也可以一次下載多個
twinkle-eval --download-dataset mmlu tmmluplus
TMMLU+ 是什麼?
TMMLU+ 是繁體中文版的大規模多任務選擇題測驗,涵蓋數十個科目(基礎醫學、法律、數學……),是評測中文模型知識廣度的常用考卷。Twinkle-Eval 也支援台灣在地化的 Formosa-bench、國際通用的 MMLU / MMLU-Pro / GPQA 等,共內建 20 多個資料集。
步驟 5:編輯 config.yaml¶
這是整個流程的核心。以下是官方的選擇題最小設定,逐行加註解:
llm_api:
base_url: "http://localhost:8000/v1" # (1)! 你的模型端點
api_key: "your-api-key" # (2)! API 金鑰
api_rate_limit: -1 # (3)! 每秒請求上限,-1 為不限制
max_retries: 5 # 失敗自動重試次數
timeout: 600 # 單次請求逾時(秒)
model:
name: "your-model-name" # (4)! 要評測的模型名稱
temperature: 0.0 # (5)! 溫度設 0,讓輸出盡量穩定
max_tokens: 4096 # 模型單次回answer的最長 token
evaluation:
dataset_paths: # (6)! 要考哪些卷(可多個)
- "datasets/tmmluplus/"
evaluation_method: "box" # (7)! 答案抽取法:box / pattern / logit
system_prompt: # (8)! 給模型的作答指示
zh: |
使用者將提供一個題目,並附上選項。
請選出最正確的選項,以 \box{選項} 格式回答。
en: |
Select the best option and answer in \box{Option} format.
datasets_prompt_map: # (9)! 指定某資料集用哪種語言的 prompt
"datasets/mmlu/": "en"
repeat_runs: 3 # (10)! 重複考 3 次,算平均與標準差
shuffle_options: true # (11)! 打亂選項順序,消除位置偏好
logging:
level: "INFO"
- 指向你部署好的 OpenAI 相容端點;本機常見是
http://localhost:8000/v1。 - 端點需要的金鑰;自架端點可自訂。
- 控制送太快被端點擋下;
-1表示不設限,火力全開。 - 端點上註冊的模型名稱,要和端點一致。
0.0讓模型盡量給出最有把握的答案,減少隨機性——但推理模型仍會有變異,所以還需要repeat_runs。- 資料夾路徑,就是步驟 4 下載下來的卷;可以同時放多份。
- 本章 3.4 的三種抽取法,入門建議
box。 - 作答指示。用
box法時,這裡會要求模型「以\box{}格式作答」,方便抽答案。 - 不同卷可用不同語言的 prompt(例如英文卷用英文指示)。
- 破解「陷阱二」:重複考多次並回報標準差,量化穩定度。
- 破解「陷阱一」:每次都打亂選項順序,讓位置偏好無所遁形。
步驟 6:先試跑(不花錢、不呼叫模型)¶
# 驗證設定檔格式對不對
twinkle-eval --validate --config config.yaml
# 預覽評測計畫,但不真的呼叫 API(確認一切就緒)
twinkle-eval --dry-run --config config.yaml
步驟 7:正式評測¶
跑到一半斷線了?可以續跑
大型評測動輒上萬題。萬一中斷,用時間戳從斷點續跑,不必從頭來:
3.6 看懂結果¶
評測完,結果存在 results/ 目錄,主要兩個檔案:
| 檔案 | 內容 | 你要看什麼 |
|---|---|---|
results_{timestamp}.json |
整體摘要:設定、各資料集正確率、執行時間 | 平均正確率與標準差 |
eval_results_{timestamp}_run{N}.jsonl |
逐題明細:題目、正確答案、模型答案、對錯 | 模型錯在哪些題、哪類科目最弱 |
怎麼解讀一個分數
假設 TMMLU+ 結果是:正確率 82.3% ± 1.4%。
- 82.3%:平均答對率——模型的知識水準。
- ± 1.4%:3 次重跑的標準差——很小,代表分數穩、可信。
- 若標準差是 ± 6%,就算平均一樣是 82.3%,也代表這模型時好時壞,這個分數要保守看待。
再翻開逐題明細(jsonl),你還能看出「它法律科很強,但基礎醫學一直錯」——這才是能回饋給訓練團隊、改進資料的可行動洞察。
排行榜
想看各家模型在繁中評測上的實際分數,可參考 Twinkle AI 的 TW Eval Leaderboard。
3.7 呼應前兩章:評測公平的前提是「去污染」¶
還記得第 1、2 章不斷強調的去污染嗎?這裡就是它的意義所在:
如果考題混進了訓練資料……
模型會在 TMMLU+ 上考出虛高的分數——它不是真懂,只是背過考卷。這種分數會誤導所有決策。
所以:乾淨的訓練資料(第 1、2 章)+ 嚴謹的評測工具(本章)= 可信的分數。 兩者缺一不可。
本章 checklist¶
拿到一份評測報告,這樣檢查它可不可信:
- 選項有隨機排列嗎?(沒有的話,小心位置偏好灌水)
- 有重複多次並回報標準差嗎?(單次分數不可靠)
- 答案抽取方法合適嗎?(box / pattern / logit)
- 訓練資料有去污染嗎?(否則分數是作弊來的)
- 有沒有看逐題明細,找出模型的強弱科目?