5.1 SFTTrainer 是什么
Unsloth 复用 HuggingFace TRL 库的 SFTTrainer——它封装了监督微调(SFT)的完整训练循环:取 batch、前向、算 loss、反向、更新、记录日志、保存 checkpoint。你只需传入模型、分词器、数据集和一组超参(SFTConfig/TrainingArguments)。
- SFT(Supervised Fine-Tuning)
- 监督微调:用带标准答案的"问-答"对训练,让模型模仿期望输出。SFTTrainer 就是为它服务的。
- batch size(批大小)
- 一次前向/反向处理的样本数。越大越稳但越占显存。字段名
per_device_train_batch_size。 - gradient accumulation(梯度累积)
- 累计多个小 batch 的梯度再更新一次,等效放大 batch 而不增显存。有效 batch = batch × 累积步数。
- learning rate(学习率)
- 参数每步更新的幅度。LoRA 常用 1e-4 ~ 2e-4,太大训崩、太小学不动。
- warmup(预热)
- 训练初期让学习率从 0 线性升到目标值的若干步,避免一开始梯度剧烈震荡。
- bf16 / fp16
- 混合精度训练。bf16 数值范围大、更稳(Ampere+ 支持);老卡用 fp16。省显存、提速。
- gradient checkpointing(梯度检查点)
- 前向不存全部激活,反向时重算,用算力换显存。Unsloth 的
"unsloth"模式最省。 - optimizer(优化器)
- 更新参数的算法。推荐
adamw_8bit,用 8bit 存优化器状态,进一步省显存。
5.2 组装 SFTTrainer
from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = train_ds,
eval_dataset = eval_ds,
dataset_text_field = "text", # 第 4 章生成的字段
max_seq_length = 2048,
packing = False, # 短样本可设 True 提速
args = SFTConfig(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4, # 有效 batch = 2×4 = 8
warmup_steps = 5,
num_train_epochs = 1, # 或用 max_steps 控制
learning_rate = 2e-4,
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
bf16 = True, # 老卡改 fp16=True
output_dir = "outputs",
),
)
5.3 有效 batch 与显存的权衡
显存不够就把 per_device_train_batch_size 调小,同时把 gradient_accumulation_steps 调大,保持有效 batch 不变。二者乘积决定"每次真正更新看了多少样本"。
| 显存 | batch_size | grad_accum | 有效 batch |
|---|---|---|---|
| 8GB (T4) | 1 | 8 | 8 |
| 16GB | 2 | 4 | 8 |
| 24GB (3090) | 4 | 4 | 16 |
| 40GB (A100) | 8 | 2 | 16 |
5.4 epoch vs max_steps
控制训练时长有两种方式:num_train_epochs(跑几遍数据)或 max_steps(跑多少步)。快速验证流程时用 max_steps=60 之类的小值先跑通;正式训练用 1-3 个 epoch。SFT 一般 1-3 epoch 足够,太多轮容易过拟合。
学习率经验值
LoRA/QLoRA:1e-4 ~ 2e-4;继续预训练(第 9 章)用更小如 5e-5。配 linear 或 cosine 调度器都行,warmup 取总步数的 3%-5%。
5.5 只对回答计算 loss(可选进阶)
默认训练会对整段文本算 loss,包括用户的问题部分。若只想让模型学"回答"、不学"复述问题",可用 TRL 的 train_on_responses_only 屏蔽掉指令部分的 loss:
from unsloth.chat_templates import train_on_responses_only
trainer = train_on_responses_only(
trainer,
instruction_part = "<|im_start|>user\n",
response_part = "<|im_start|>assistant\n",
)
为什么这么做
只对 assistant 回答算 loss,模型把"学习预算"全花在生成好答案上,通常能提升指令跟随质量,尤其是多轮对话数据。
5.6 小结与下一步
SFTTrainer封装完整训练循环;核心旋钮是 batch × 梯度累积 = 有效 batch。- 学习率 LoRA 取 2e-4,SFT 1-3 epoch,优化器用 adamw_8bit,精度用 bf16。
- 梯度检查点用 Unsloth 模式最省显存;可选 train_on_responses_only 只学回答。
- 配置就绪,下一章正式 启动训练并监控 loss 与显存。