[RSCH] 6 分鐘閱讀OraCore 編輯部

怎麼做 LLM 微調

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

分享 LinkedIn
怎麼做 LLM 微調

這篇教你用 SFT、LoRA 和偏好對齊方法微調大型語言模型。

這篇給剛開始做模型適配的開發者看。照著做完,你會得到一份可訓練的資料集、可重現的 SFT 基線、LoRA 適配器流程,以及一條通往 RLHF 或 DPO 的實作路線。

開始之前

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

  • Hugging Face 帳號,並可讀取 Transformers 文件Hugging Face Hub
  • GitHub 存取權,並可使用 PEFT repoTRL 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 兩個答案。

怎麼做 LLM 微調
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 或對齊方法,才知道改善來自哪一段流程。

怎麼做 LLM 微調
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 上比對,及早抓回歸。

接下來可以看什麼

如果這套流程已經穩定,下一步可以看多輪對話格式化、你的領域資料清理,以及當工作場景包含圖片時的多模態微調。