0. 系列闭环
| 本篇位置 | 上游 | 本篇产出 | 下游 |
|---|---|---|---|
| 第 6/10 篇 | 第 05 篇 Dataset 就绪 | final_lora/、15 个 checkpoint |
第 07 篇读日志 · 第 08 篇 verify |
本篇是唯一会改 LoRA 权重的代码段。跑完应看到:
1 | |
(与 all_logs.log 最后一行一致,路径略有措辞差异)
1. 要解决的实际问题
Step 5–7 负责:
- 把 HuggingFace
TrainingArguments与 TRL 特有项(dataset_text_field、max_length)合并进 SFTConfig - 创建 SFTTrainer,在此刻注入 LoRA
- train() 750 步,save_pretrained 只存 adapter
很多人卡在 TRL 1.x API 变更:processing_class 替代 tokenizer,max_length 替代 max_seq_length。
2. 实现位置
| 代码块 | 行号 |
|---|---|
SFTConfig(...) |
204–221 |
SFTTrainer(...) |
226–233 |
trainer.train() |
240 |
save_pretrained |
244–246 |
TrainingProgressCallback |
82–99 |
产出目录结构:
1 | |
3. SFTConfig 逐项说明
1 | |
| 参数 | 值 | 原理 |
|---|---|---|
per_device_train_batch_size=2 |
micro-batch | 每次 forward 2 条 |
gradient_accumulation_steps=2 |
累积 | 2×2=4 才 optimizer.step |
learning_rate=2e-4 |
LoRA 常用 | 线性衰减到 ~0 |
bf16=True |
混合精度 | 与加载 dtype 配合 |
logging_steps=1 |
逐步 log | 配合 Callback 打印 |
save_steps=50 |
checkpoint | 750/50=15 个 |
optim="paged_adamw_8bit" |
8bit Adam | 优化器状态省显存 |
dataset_text_field="text" |
字段名 | 对应 load_jsonl_data |
max_length=512 |
截断 | 超长样本切尾 |
report_to="none" |
不上传 | 无 W&B |
未设置 eval_strategy:无验证集,日志里没有 eval_loss(第 07 篇)。
4. SFTTrainer 构造与 train()
1 | |
4.1 注入时机
SFTTrainer 内部调用 PEFT,把 LoRA 层挂到 target_modules。此时打印:
1 | |
4.2 训练循环内发生了什么(概念)
1 | |
基座 (W) 无梯度;只有 (A,B) 更新。
4.3 日志双轨
同一步会有:
- tqdm 进度条(
3.31s/it) - Callback 行:
[进度 33.3%] Step 250/750 | Epoch 1.00 | loss=0.2402 - Transformers JSON log:
{'loss': '0.24', 'mean_token_accuracy': '0.957', ...}
写复盘时以 Callback 行 + 汇总行 为准。
5. Step 7:保存
1 | |
保存的是 PeftModel 的 adapter,不是合并后的全量。推理:
1 | |
vLLM 则 --lora-modules elderly=./output/.../final_lora(第 10 篇)。
6. checkpoint 与 resume
checkpoint-750/trainer_state.json 含:
global_step: 750log_history: 每步 loss- optimizer / scheduler 状态(用于
--resume_from_checkpoint)
日常验证用 final_lora;只有中断续训才需要中间 checkpoint。
7. OOM 应急(按优先级)
1 | |
改参数后 750 step 数会变(若改 batch 或 epochs),不要与旧日志直接对比。
8. 踩坑
坑 1:TRL 0.x 教程的 max_seq_length 写在 SFTConfig
TRL 1.x 用 max_length。写错参数名会 silently 用默认值,你以为训 512 实际可能是 1024。
坑 2:重复 get_peft_model
见第 05 篇,trainable% 异常。
坑 3:save_steps 太小
每 10 step 存一次,磁盘爆满 + IO 拖慢。50 步对本项目合理。
坑 4:训练完只复制 checkpoint-750 forgetting final_loratrainer.train() 结束后 save_pretrained(final_lora) 才是干净 adapter;checkpoint 带 optimizer 体积大。
9. 小结
- SFTConfig 管超参 +
max_length+dataset_text_field。 - SFTTrainer + peft_config 是唯一 LoRA 注入点。
- 750 step / 41min / train_loss 0.2587 为 V100 实测。
- final_lora 是部署与验证路径;checkpoint 用于续训与 loss 曲线。
- 无验证集,效果靠第 08 篇推理验证。
附录:TrainingProgressCallback.on_log
1 | |
系列导航
| 篇目 | 链接 |
|---|---|
| 上一篇 | 05 · SFT 实战(上) |
| 下一篇 | 07 · 训练曲线 |
| 索引 | README |