怎麼做 LLM 微調
學會用 SFT、LoRA、RLHF 或 DPO 微調大型語言模型,建立可訓練、可對齊、可部署的完整流程。

這篇教你用 SFT、LoRA 和偏好對齊方法微調大型語言模型。
這篇給剛開始做模型適配的開發者看。照著做完,你會得到一份可訓練的資料集、可重現的 SFT 基線、LoRA 適配器流程,以及一條通往 RLHF 或 DPO 的實作路線。
開始之前
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
- Hugging Face 帳號,並可讀取 Transformers 文件與 Hugging Face Hub。
- GitHub 存取權,並可使用 PEFT repo 與 TRL repo。
- Python 3.10+。
- PyTorch 2.1+。
- CUDA 12+,如果你要在 NVIDIA GPU 上訓練。
- 至少 16 GB GPU VRAM,或等效雲端 GPU。
- 已整理好的 instruction 資料集,格式為 JSONL 或 CSV。
Step 1: 整理訓練資料集
這一步的產出是「可直接餵給訓練器的監督式資料集」。如果你做指令微調,每筆資料要有 prompt 與 target response;如果你做偏好訓練,還要保留 chosen 與 rejected 兩個答案。

import json
with open("train.jsonl") as f:
rows = [json.loads(line) for line in f]
print(rows[0])你應該看到結構完整的樣本,欄位像是 prompt、response,或 preference labels。若第一筆資料格式不對,先修正 schema,再進入訓練,否則 tokenizer 和 trainer 很容易在後面報錯。
Step 2: 建立 SFT 基線模型
這一步的產出是「可比較的監督式微調基線」。先做 SFT,因為它能先告訴你模型是否真的學會任務,之後再加 LoRA 或對齊方法,才知道改善來自哪一段流程。

from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
model_name = "meta-llama/Llama-3.1-8B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
args = TrainingArguments(
output_dir="./sft-output",
per_device_train_batch_size=1,
num_train_epochs=1,
)
trainer = Trainer(model=model, args=args, train_dataset=rows)
trainer.train()你應該看到 loss 在前幾個 step 下降,並且 output 目錄裡出現 checkpoints。若 loss 持平或突然飆高,先檢查 prompt 格式,再確認 labels 是否和 target text 對齊。
Step 3: 套用 LoRA 適配器
這一步的產出是「只更新少量參數的 LoRA 訓練配置」。LoRA 適合 GPU 記憶體有限、又想快速迭代的情境,因為它不需要每次都重訓整個模型。
from peft import LoraConfig, get_peft_model, TaskType
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8,
lora_alpha=16,
lora_dropout=0.05,
)
model = get_peft_model(model, config)
model.print_trainable_parameters()你應該看到可訓練參數數量明顯小於 base model。若可訓練參數仍然太多,請確認 PEFT 包到正確模組,並檢查你沒有把整個網路意外解凍。
Step 4: 執行偏好對齊訓練
這一步的產出是「更符合人類偏好的對齊模型」。RLHF 類工作流的重點,是讓模型不只模仿標註答案,還要學會在多個候選回應中偏向更好的那個;若你已經有 preference pairs,DPO 通常是更直接的做法。
from trl import DPOTrainer, DPOConfig
config = DPOConfig(output_dir="./dpo-output")
trainer = DPOTrainer(
model=model,
ref_model=None,
args=config,
train_dataset=rows,
)
trainer.train()你應該看到 preference optimization 的 log,並且輸出一份對齊後的 checkpoint。若模型開始產生更短、較保守或更穩定的回答,通常代表偏好目標已經開始生效。
Step 5: 評估並封裝模型
這一步的產出是「可部署的最終模型資產」。先用一小組測試題檢查指令遵循、拒答行為與領域正確率,再把 adapter 或合併後的權重存成可部署格式。
model.save_pretrained("./final-adapter")
tokenizer.save_pretrained("./final-adapter")你應該看到一個模型資料夾,裡面有 adapter 權重或 merged weights,還有 tokenizer 檔案。若資料夾內容不完整,請確認 model 和 tokenizer 都有寫出,並且部署 runtime 使用的是同一個 base model 版本。
| 指標 | 基準/優化前 | 結果/優化後 |
|---|---|---|
| 可訓練參數 | 完整模型 | 只更新 LoRA adapters |
| GPU 記憶體占用 | 全量微調較高 | 參數高效微調較低 |
| 輸出品質 | Base model 原始行為 | 更貼近任務且更符合偏好 |
常見錯誤
- 直接拿原始聊天紀錄訓練。修法:先整理成一致的 prompt-response,或 chosen-rejected pair 格式,再開始訓練。
- 明明 LoRA 就夠,卻整個模型全量微調。修法:先用 adapter 跑通流程,只有在任務確實需要時,再考慮 full fine-tuning。
- 做完對齊卻沒做同題比較。修法:把 base、SFT、DPO 的輸出放在同一組測試 prompt 上比對,及早抓回歸。
接下來可以看什麼
如果這套流程已經穩定,下一步可以看多輪對話格式化、你的領域資料清理,以及當工作場景包含圖片時的多模態微調。