Hugging Face微调实战2026:TRL+PEFT完成SFT和DPO
微调听起来复杂,实际要解决两个问题:让模型学会一种格式或领域知识(SFT),让模型更偏好某类回答(DPO)。Hugging Face 生态里,PEFT 负责参数高效训练,TRL 提供这两类训练器,两个库配起来就够。
Hugging Face 微调实战 2026:用 TRL + PEFT 完成 SFT 和 DPO
微调听起来复杂,实际要解决两个问题:让模型学会一种格式或领域知识(SFT),让模型更偏好某类回答(DPO)。Hugging Face 生态里,PEFT 负责参数高效训练,TRL 提供这两类训练器,两个库配起来就够。
一、分工与数据格式
| 库 | 作用 |
|---|---|
| transformers | 加载基座模型与分词器 |
| PEFT | LoRA / QLoRA 适配器,只训练少量参数 |
| TRL | SFTTrainer、DPOTrainer 两个训练流程 |
| bitsandbytes | 4bit 量化,QLoRA 省显存 |
| datasets | 统一数据加载格式 |
环境大致需要 Python 3.10 以上和按显卡版本装好的 PyTorch。显存 8GB 可以走 QLoRA 路线,16GB 以上可以尝试常规 LoRA。
数据格式先定下来:
| 流程 | 必需字段 | 说明 |
|---|---|---|
| SFT | instruction / response(或 messages) | 指令与理想回答成对 |
| DPO | prompt / chosen / rejected | 同题的好答案与坏答案成对 |
数据质量比数量重要得多。几百条干净、格式统一的样本,通常好过几千条混杂样本。坏样本的典型特征是回答过长、格式不一致、夹带与任务无关的客套话。
二、流程一:SFT 监督微调
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig
lora = LoraConfig(r=16, lora_alpha=32, lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
task_type="CAUSAL_LM")
trainer = SFTTrainer(
model=model, tokenizer=tok, train_dataset=dataset, peft_config=lora,
args=SFTConfig(output_dir="./sft", num_train_epochs=2,
learning_rate=1e-4, per_device_train_batch_size=2,
gradient_accumulation_steps=8, max_length=2048),
)
trainer.train()
关键参数怎么定:
| 参数 | 作用 | 起手值 |
|---|---|---|
| r | 适配器秩,越大容量越强 | 8–16,小任务用 8 |
| lora_alpha | 缩放系数 | 通常为 r 的 2 倍 |
| target_modules | 挂载位置 | 注意力四个投影层足够 |
| learning_rate | 学习率 | 1e-4 量级,比全量微调高 |
| num_train_epochs | 轮数 | 1–3,多轮容易过拟合 |
QLoRA 变体:加载模型时加 4bit 量化配置(load_in_4bit=True,量化类型用 nf4),显存占用明显下降,代价是训练速度慢一些。
三、流程二:DPO 偏好对齐
DPO 不需要单独训练奖励模型,这正是它在开源界取代大部分 RLHF 的原因。数据只要三列。
from trl import DPOTrainer, DPOConfig
dpo = DPOTrainer(
model=model, train_dataset=dpo_data, peft_config=lora,
args=DPOConfig(output_dir="./dpo", num_train_epochs=1,
learning_rate=5e-5, beta=0.1),
)
dpo.train()
参数里 beta 控制模型偏离参考模型的程度:偏大更保守,偏小更容易跑偏。DPO 数据几百到几千对就够,重点是 chosen 与 rejected 的差距要明确。训练完得到的是独立的小体积适配器,推理前用 model.merge_and_unload() 合并进基座权重再保存;保留未合并的适配器也有价值,换任务时切换适配器即可,不必存多份完整权重。
四、评估:别只看 loss
loss 下降不等于模型变好,这是微调最常见的坑。SFT 或 DPO 之后,至少要在留出集上看三件事:
- 格式合规率:要求输出 JSON 或固定结构时,合规比例是多少
- 拒答率:会不会把正常问题当成敏感问题拒掉
- 人工偏好对比:同一批问题让基座和微调模型各答一遍,人工盲评
跑完如果人工偏好没有提升,先怀疑数据,而不是继续加轮数或加大 r。
常见问题
Q:SFT 和 DPO 的顺序能换吗? 一般先 SFT 再 DPO。SFT 让模型学会格式,DPO 再调偏好。直接做 DPO 也可以,但收敛更慢。
Q:需要多少数据? 格式类任务几百条起步,领域知识类通常要几千条。先跑一版小数据看趋势再决定要不要扩。
Q:显存不够怎么办? 依次试:QLoRA 4bit、降低 max_length、减小 batch 并增大梯度累积、换更小的基座模型。
Q:微调会不会让模型变笨? 会,这叫灾难性遗忘。缓解办法是数据里混入少量通用语料,并保留基座模型做对照,不要一路只喂单一任务数据。
注:库的 API 名称和参数默认值随版本变化,具体以官方文档为准。
相关文章
本站文章由编辑人工撰写,收录的工具均经过实测或公开资料核验。文中链接指向工具官网或 GitHub 仓库,仅作信息参考,不构成付费推广。