先看 Boss:鐵鎚看什麼都像釘子
學會 fine-tune 之後,最容易發生的事情是:每個問題都想拿 LLM 來解。這一關的 Boss 就是這種心態。
在醫療領域,「用 LLM」本身不是目的。合理的問法是:這個任務的輸入長什麼樣子?有沒有固定格式?有沒有現成而穩定的工具?錯誤的代價是什麼?以下用三組反指標案例,加上一個動手對照,練習這種判斷。
負面對照 1:CT 報告匿名化,規則式勝出
PMID 39480533(Eur Radiol 2025,美國 MGH 與 Cologne 合作)用 100 份胸部 CT 報告,比較規則式 spaCy 流程與離線的 LLaMa-2(提示詞法,沒有 fine-tune)做 PHI 匿名化。數字依摘要:
- 規則式流程對日期、病歷號、檢查號全部移除,F1 為 1.00。
- LLM 的日期 recall 為 0.52(F1 0.68),檢查號 recall 為 0.96。
- 姓名完全或大致移除的比例:規則式 100%,LLM 90%。
- LLM 在 10 份報告中誤刪了醫療資訊,規則式沒有這個問題。
這篇研究的結論並不是「LLM 做不了匿名化」,而是在這個任務、這個設定下,格式固定的識別碼用規則式更穩。同一篇研究的 LLM 沒有經過 fine-tune,也沒有針對報告格式調整,所以不宜直接推論到「fine-tune 過的模型一定也輸」。
負面對照 2:台灣 ASA-PS,LoRA 有效但不是最佳
PMID 42013456(JMIR 2026,遠東聯合醫院與台科大等團隊)用 24,491 位病人的術前麻醉病歷判讀 ASA-PS 分級(I 到 V)。數字依摘要:
- 未微調的 LLaMA-3-8B,micro-F1 為 0.073;LoRA 微調後為 0.780(95% CI 0.769 到 0.792)。
- BioBERT 0.762、ClinicalBERT 0.757、fastText 0.762。
- XGBoost 為 0.815,數值仍較高;摘要未載與 LoRA 之間的正式檢定,所以只能說「數值較高」。
- macro-F1 為 0.316,低於其他語言模型(0.349 到 0.372),表示在較少見的類別上表現較弱。
這是一個很好的台灣在地案例:它同時告訴你 fine-tune 的效果很大(0.073 到 0.780),也告訴你它不是萬靈丹,因為結構化較強的任務,傳統機器學習可能更高。要提醒的是,這是回溯性的研究開發驗證,並非臨床部署;論文對運算環境的敘述(雲平台與內部基礎設施)並存,引用時宜保守。
國考 QA:為什麼不值得本地 fine-tune
本站的主線不是國考題,國考題只用來當作對照。原因可以從「為什麼要本地」與「為什麼要 fine-tune」兩個問題拆解:
- 為什麼要本地? 通常是因為資料是病人資料,不宜外流。國考題是公開性質的考試題目,不含病人資料,沒有這個動機。
- 為什麼要 fine-tune? 通常是因為任務窄且固定、現成模型表現不夠好。PMID 40465748(PLoS One 2025)以 2021-07 到 2024-02 的國考第一階段題目(排除圖片題,共 1,188 題)評估,GPT-3.5 正確率 65.74%,GPT-4 為 95.71%,GPT-4o 為 96.72%;GPT-4 與 GPT-4o 之間無統計顯著差異。
換句話說,雲端大模型在這個任務上已經很高,自己 fine-tune 的邊際效益有限。有兩點要補充。第一,國考的選擇題正確率高,不等於能做臨床推理,更不是任何臨床部署的證據。第二,題目是公開的,模型是否在訓練階段見過,本站無法確認【推論】。
Colab 版本若想做對照,可以用 TMMLU+ 的醫學相關科目(作者查證:這份資料集沒有「醫師」科目,只有基礎醫學、藥理等)抽 50 題,比較 fine-tune 前後的正確率,用來檢查一般能力有沒有退化,而不是當作主線。
能耗與規模:小模型不一定比較差
PMID 39189909(Radiology 2024,美國 University of Maryland)在 3,665 份 CXR 報告上比較通用的 Llama 2(7B、13B、70B)與專用微調的 Vicuna 1.5。數字依摘要:Vicuna 1.5 7B 的準確率為 93.83%,Llama 2 70B 為 92.70%;Llama 2 70B 耗電 4.16 kWh,約為 7B 的 0.59 kWh 的 7 倍。這個結果提醒我們:任務固定時,專用的小模型可能在準確度與能耗上更划算。
怎麼讀一篇 LLM 醫學論文
讀論文時,可以自問下面五個問題:
| 問題 | 為什麼重要 |
|---|---|
| 比較對象是誰? | 只和未微調的模型比,進步幅度會顯得很大 |
| 有沒有傳統方法的 baseline? | 如 XGBoost、規則式;沒有 baseline 就不知道 LLM 是否值得 |
| 有沒有正式檢定與信賴區間? | 只比點估計,差距可能只是隨機變異 |
| 是回溯研究,還是已進入臨床流程? | 本站目前找到的案例都是研究階段 |
| 結果是不是同一團隊重複出現? | 同一團隊的多篇論文不是獨立證據 |
Hybrid 設計:讓規則與模型各做擅長的事
主線專案的 PHI 有八種類型:NAME、DOCTOR、MRN、IDNO、DATE、PHONE、ADDRESS、HOSPITAL。有些有固定格式(病歷號是 7 到 8 位數字、手機號碼是 09xx-xxx-xxx),有些需要上下文(人名、自由文字描述的日期如「上週三」)。hybrid 的做法是:regex 先處理格式固定的類型,LLM 處理需要理解上下文的類型,最後合併。
一個小實驗:regex 與 LLM 的對照
主線專案的 experiments/synth/evaluate.py 已經內建 --regex 模式,可以用同一份 gold 與同一套評分函式比較 regex 與模型。以下是作者在冒煙資料(29 份筆記,非正式數字)上的觀察,regex 的部分不依賴硬體:
| 方法 | span recall | 觀察 |
|---|---|---|
regex(--regex) | 0.3744(95% CI 0.2989 到 0.4545) | HOSPITAL 與 PHONE 為 1.0,MRN 0.619、DATE 0.583、IDNO 0.40,NAME、DOCTOR、ADDRESS 為 0 |
| Gemma 4 E2B 提示詞法(關閉 thinking,未微調) | 0.3695 | valid JSON 率 45%;人名 recall 0.446 |
兩者的總 recall 看似接近,但分布完全不同:regex 抓不到人名,模型對格式固定的號碼反而不穩。注意:冒煙資料中,LoRA 微調版的 0.995 是因為訓練與測試共用相同骨架(資料洩漏),不可引用。正式實驗需要以骨架為單位切分資料,見 LV14。
🍎 Mac:跑 regex 基準,再試 hybrid
python synth/evaluate.py --gold data/sft/test.gold.jsonl --regex --out results/regex.json
python synth/evaluate.py --gold data/sft/test.gold.jsonl \
--model models/gemma-4-E2B-it-MLX-4bit --adapter adapters/phi-lora \
--out results/lora.json
第一行用 regex 跑;第二行用微調後的模型跑,輸出會同時存成 results/lora.preds.jsonl(每行有 id 與 pred)。接下來寫一個合併腳本,讓 regex 負責日期與號碼類型,模型負責其餘:
import json
import sys
sys.path.insert(0, "synth")
from evaluate import regex_predict, score
REGEX_OWNS = {"DATE", "MRN", "PHONE", "IDNO"} # types handled by regex
golds = [json.loads(l) for l in open(sys.argv[1], encoding="utf-8")]
llm = {}
for line in open(sys.argv[2], encoding="utf-8"):
r = json.loads(line)
llm[r["id"]] = r["pred"] or []
def merge(g):
rx = [p for p in regex_predict(g["text"]) if p["type"] in REGEX_OWNS]
keep = [p for p in llm.get(g["id"], []) if p.get("type") not in REGEX_OWNS]
return rx + keep
for name, preds in [("llm", [llm.get(g["id"], []) for g in golds]),
("hybrid", [merge(g) for g in golds])]:
res = score(golds, preds)
print(name, res["span_recall"], res["precision_unique"], res["recall_by_type"])
逐段解釋:REGEX_OWNS 是「交給 regex 負責」的類型集合。merge 對每份筆記做兩件事:取 regex 預測中屬於這些類型的結果,再加上模型預測中不屬於這些類型的結果,兩者相加就是 hybrid 的預測。最後用和 evaluate.py 相同的 score 函式比較 llm 與 hybrid 的 recall,分數可以直接對照。
作者用同一個腳本跑在冒煙資料的「提示詞法」預測上(非正式,n=29):span recall 由 0.3695 升到 0.4926,DATE 由 0.389 到 0.583,MRN 由 0.190 到 0.619,PHONE 由 0.45 到 1.0;但 IDNO 由 0.80 降到 0.40,因為 regex 在這個類型的表現不如模型。教訓是:哪一類交給 regex,要看驗證集上每個類型的結果決定,不要直接用 test 集挑,否則 test 集就不再是獨立的了。
正式實驗的 hybrid 結果(公開資料集 v1.0,test 200 份、1,349 個 PHI span;作者在 M5 32GB 的實測,數字與 LV14 同一份評估):
| 組合 | span recall | precision |
|---|---|---|
| prompt-only | 0.439 | 0.959 |
| prompt-only + regex | 0.750 | 0.916 |
| LoRA | 0.978 | 0.995 |
| LoRA + regex | 0.994 | 0.947 |
取捨要看清楚:兩組 hybrid 的 recall 都上升,precision 都下降(LoRA 組由 0.995 降到 0.947)。原因是 regex 會多報一些不是 PHI 的字串。在去識別化任務中,漏掉 PHI 的代價通常高於多遮蔽一些非 PHI 的字,因此 recall 優先的 hybrid 往往是合理的選擇;但多遮蔽會降低文本的可用性,要依你的用途權衡。以上為合成資料上的結果,不代表真實病歷的表現。
☁️ Colab:同一套評分,換預測來源
regex 的部分是純 Python,在 Colab 的 CPU 即可執行。LLM 的預測由 LV13 的 Colab notebook 產生,輸出成同樣格式的 preds.jsonl(每行 id、pred),上傳後用上面的合併腳本比較即可。Colab 版的正式分數:【實測數據待補】。
什麼時候不該用 LLM:判斷清單
下列情境,建議先評估規則式或傳統模型:
- 輸入有固定格式,且錯誤代價高(例如病歷號、檢查號、日期)。
- 已有穩定的結構化資料,任務是預測一個分類或分數(例如 ASA-PS 這類,XGBoost 可能更好)。
- 任務有現成的雲端大模型能做得很好,且資料不含病人資訊(例如國考 QA)。
- 需要完全可重現、可稽核的結果,不能接受偶發的幻覺或誤刪。
- 對延遲、能耗或硬體有嚴格限制。
反過來,下列情境較適合考慮 LLM:輸入是自由文字、需要理解上下文(如人名、縮寫混雜的筆記),而且你有合成或已核准的資料可以評估。
本關重點
- 在固定格式的識別碼(日期、病歷號)上,規則式常常更穩;MGH 的 CT 報告研究中,規則式 F1 為 1.00,LLM 的日期 recall 為 0.52。
- 台灣 ASA-PS 研究顯示 LoRA 效果很大(0.073 到 0.780),但 XGBoost(0.815)數值仍較高,LLM 不是唯一選項。
- 國考 QA 沒有「資料需留在本地」的動機,雲端大模型表現已高,只當作對照,不當主線。
- hybrid 的核心是依類型分工並用驗證集決定分工,不是預設誰比較好。
- 讀論文時檢查:比較對象、傳統 baseline、檢定與信賴區間、是否已進入臨床、是否為獨立證據。