第 2 章 · 準備與清洗 SFT 資料集¶
本章你會學到
- SFT 是什麼、跟 pre-training 差在哪(帶徒弟 vs 讀圖書館)
- SFT 資料長什麼樣子(
system/user/assistant對話格式) - 四種生出 SFT 資料的方法:人工標註、既有資料改寫、合成生成、領域資料
- 為什麼品質遠比數量重要(LIMA:1,000 筆勝過 5 萬筆)
- 一條 SFT 清洗流水線:格式 → 去重 → 品質評分 → 多樣性 → 安全 → 去污染 → 語言一致
2.1 SFT 是什麼?跟 pre-training 差在哪?¶
第 1 章那位新同事,讀完圖書館後知識很淵博,但不會「好好回話」。你問他問題,他可能接著幫你把句子寫完(因為他只學過「預測下一個字」),而不是回答你。
SFT(Supervised Fine-Tuning,監督式微調) 就是接下來的「帶徒弟」階段:我們準備一大批「問題 → 理想回答」的示範,一筆一筆教他——遇到這種問法,就該這樣回。
flowchart LR
subgraph P["Pre-training(第 1 章)"]
P1["讀海量文字"] --> P2["學會語言與知識<br/>但只會『接話』"]
end
subgraph S["SFT(本章)"]
S1["讀『問題→回答』示範"] --> S2["學會『當一個有用的助理』<br/>會回答、會遵守指令"]
end
P2 --> S1
style P fill:#e8eaf6,stroke:#3f51b5
style S fill:#fff8e1,stroke:#ff8f00
| Pre-training | SFT | |
|---|---|---|
| 在學什麼 | 語言、常識、知識(底子) | 怎麼遵守指令、好好回話(行為) |
| 資料形式 | 一大坨純文字 | 成對的「指令 → 回答」 |
| 資料量 | 兆級 token,越多越好 | 幾千~幾十萬筆,重質不重量 |
| 比喻 | 讀遍圖書館 | 師傅帶徒弟、手把手示範 |
2.2 SFT 資料長什麼樣子?¶
SFT 資料通常是一段對話,用 role(角色)標記誰在說話:
system:給模型的「人設 / 規則」(例如:你是一個講繁體中文的客服助理)。user:使用者說的話。assistant:我們希望模型學會的理想回答。
{
"messages": [
{ "role": "system", "content": "你是 APMIC 的客服助理,請用繁體中文、有禮貌地回答。" },
{ "role": "user", "content": "請問你們的服務支援哪些語言?" },
{ "role": "assistant", "content": "您好!我們的服務目前支援繁體中文、英文與日文三種語言,若有其他語言需求也歡迎告訴我們。" },
{ "role": "user", "content": "那有中文的技術文件嗎?" },
{ "role": "assistant", "content": "有的,我們提供完整的繁體中文技術文件,您可以在官網的『開發者中心』找到,需要我幫您附上連結嗎?" }
]
}
為什麼是這種格式?
這種「角色 + 內容」的結構(業界常稱 ChatML 或 messages 格式),讓模型清楚知道哪句是指令、哪句是它該產生的回答。訓練時,模型只針對 assistant 那幾句「對答案」學習。
2.3 怎麼生出這些資料?四種主流做法¶
-
① 人工標註
請真人專家一筆一筆寫問題與理想回答。
品質最高、成本最貴。
代表:Databricks Dolly-15k、開源眾包的 OpenAssistant (OASST)。
-
② 既有資料集改寫
把現成的 NLP 資料(翻譯、摘要、問答)套上指令模板,變成「指令→回答」格式。
便宜、量大,但多樣性有限。
代表:Google FLAN、Natural Instructions。
-
③ 合成生成(用強模型造資料)
用一個已經很強的 LLM 大量生成指令與回答。
最快、最能放大規模,但要嚴格把關品質與授權。
代表:Self-Instruct、Alpaca(52k 筆)、Evol-Instruct(WizardLM,把指令逐步變難)、Magpie。
-
④ 領域 / 內部資料
把公司的 FAQ、產品手冊、客服對話,整理成「問→答」對。
這是讓模型懂你家業務的關鍵。
需注意:內部資料的去個資與授權同樣要做。
合成資料的兩把利器(值得記住名字)
- Self-Instruct / Evol-Instruct:讓強模型「自己出題、自己作答」,甚至把題目越改越難、越改越複雜,逼出更深的能力。
- 蒸餾(Distillation):用一個更強的模型當「老師」,生成大量高品質回答來教「學生」模型。
- ⚠️ 授權地雷:用某些商用模型的輸出來訓練,可能違反它的使用條款。動手前務必確認授權,這是法遵該把關的地方。
2.4 為什麼「品質 > 數量」?¶
這是 SFT 和 pre-training 最大的觀念差異。
Meta 的知名研究 LIMA("Less Is More for Alignment") 發現:只用 1,000 筆精挑細選的高品質示範,就能微調出表現優異的助理——勝過用 5 萬筆平庸資料的結果。
為什麼?
因為 SFT 不是在「灌新知識」(那是 pre-training 的事),而是在喚醒並塑形模型已經有的能力、教它「回話的樣子」。少量但一致、高品質的示範,反而讓模型學到清楚的行為典範;大量但雜亂的資料,只會教出前後矛盾、有時很爛的習慣。
flowchart LR
A["5 萬筆<br/>參差不齊的資料"] -->|"混入壞習慣"| B["😐 表現普通<br/>時好時壞"]
C["1,000 筆<br/>精選高品質資料"] -->|"一致的好典範"| D["😃 表現優異<br/>穩定可靠"]
style B fill:#ffebee,stroke:#c62828
style D fill:#e8f5e9,stroke:#2e7d32
結論:SFT 的重點不是「撈更多」,而是「篩更準」。 這讓「清洗」在 SFT 階段變得無比關鍵。
2.5 SFT 清洗流水線¶
flowchart TD
A["原始 SFT 資料<br/>(人工/改寫/合成/領域)"] --> B["① 格式驗證<br/>角色正確、非空、合法 JSON"]
B --> C["② 去重<br/>刪掉重複與語意近似的指令"]
C --> D["③ 品質評分<br/>LLM-as-Judge 打分、濾掉低分"]
D --> E["④ 多樣性把關<br/>涵蓋多種任務與領域"]
E --> F["⑤ 安全性<br/>移除有害指令、補上合理拒絕"]
F --> G["⑥ 去污染<br/>剔除評測考題"]
G --> H["⑦ 語言一致<br/>確認繁中、無簡體洩漏"]
H --> I["✨ 高品質 SFT 資料集"]
style A fill:#fff8e1,stroke:#ff8f00
style I fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20
① 格式驗證(Format Validation)¶
最基本但最容易出包的一關:
- 角色順序對嗎?(
user和assistant要交替,不能兩個assistant連在一起) - 回答是空的嗎?被截斷了嗎(講到一半沒了)?
- JSON 合法嗎?特殊字元有跳脫嗎?
- 有沒有超過模型的最大長度?
② 去重(Deduplication)¶
合成資料特別容易產生大量換句話說的重複。除了完全相同要刪,還要抓語意近似:
- 做法:把每筆指令轉成向量(embedding),算餘弦相似度,太像的只留一筆。
- 為什麼重要:重複的指令會讓模型過度偏向某類問題,浪費珍貴的資料額度。
③ 品質評分(LLM-as-Judge)¶
用一個強模型或評分模型,幫每筆資料的回答打分(例如 1–5 分):
- 這個回答正確嗎?有幫助嗎?切題嗎?格式好嗎?
- 濾掉低分的,例如:答非所問、講到一半被截斷、語言錯誤、幻覺(唬爛)、罐頭式的「身為 AI 我無法……」。
def clean_sft_sample(sample) -> bool:
msgs = sample["messages"]
# ① 規則:角色交替、回答非空、長度合理
if not valid_role_order(msgs):
return False
last = msgs[-1]
if last["role"] != "assistant" or not last["content"].strip():
return False
if len(last["content"]) < 5: # 太短,多半沒內容
return False
if is_truncated(last["content"]): # 結尾像被硬切斷
return False
# ② 語言一致:繁中資料不該混簡體 / 整段英文
if not is_traditional_chinese(last["content"]):
return False
# ③ 品質:交給評分模型打分,低於門檻就丟
score = llm_judge_score(msgs) # 例如回傳 1~5
return score >= 4
④ 多樣性把關(Diversity)¶
好的 SFT 資料要涵蓋各種任務:問答、寫作、摘要、翻譯、程式、推理、閒聊……
- 做法:把指令向量化後分群(clustering),檢查是不是某一類(例如「翻譯」)佔了 80%。
- 為什麼重要:資料太偏,模型就會「偏科」。
⑤ 安全性(Safety)¶
- 移除引導模型做壞事的有害指令,或為它們補上得體的拒絕示範。
- 但要拿捏分寸:拒絕示範放太多,會養出一個動不動就「我不能回答」的過度拒絕模型,同樣惹人厭。
⑥ 去污染(Decontamination)¶
和第 1 章一樣重要:把評測考題從 SFT 資料裡剔除。
SFT 階段的去污染尤其危險
合成資料是用強模型生成的,而那個強模型可能剛好看過某些 benchmark 的題目,於是把考題「漏」進你的 SFT 資料。這會讓你的模型在評測上假性高分。務必比對並剔除。
⑦ 語言一致(繁中重點)¶
確認每一筆回答都是道地的繁體中文:
- 用語言辨識抓出混進來的簡體字、整段英文。
- 特別注意:用中國的模型做蒸餾時,回答常帶簡體或對岸用語(「視頻/軟件/信息」),必須偵測並修正或剔除。
2.6 一個具體例子:從「爛資料」到「乾淨資料」¶
清洗前(會被丟掉或修正)
問題:① 簡體字、② 罐頭開場白「作為一個 AI 語言模型」、③ 回答被截斷。清洗後(保留)
修正:繁體化、拿掉罐頭開場白、補完整內容。2.7 常用工具¶
把上述流程串起來的開源工具
- Argilla + distilabel:合成資料生成 + 人工回饋 + 品質評分的整套流程。
- data-juicer(阿里):上百種資料清洗算子,pre-training 與 SFT 都能用。
- NeMo-Curator(NVIDIA):大規模資料清洗與去重。
- 語意去重:用 embedding 模型 + 向量相似度,或 semhash 這類工具。
本章 checklist¶
- 格式對嗎?(角色交替、回答非空、沒被截斷、合法 JSON)
- 去重了嗎?(完全重複 +語意近似)
- 品質篩過嗎?(LLM 評分、濾掉低分與罐頭回答)
- 夠多樣嗎?(沒有偏科)
- 安全嗎?(有害指令處理了,但沒過度拒絕)
- 去污染了嗎?(評測考題沒混進來)
- 語言一致嗎?(道地繁中、無簡體洩漏)
小結
SFT 教會模型「怎麼當一個有用的助理」。和 pre-training 最大的不同是:品質遠比數量重要,所以「篩選與清洗」就是這一章的主角。模型練成後,該怎麼公平地驗收它?下一章我們用 Twinkle-Eval 來考選擇題。