Chapter 11
常见错误:reference 不冻、KL 爆炸
📌 commit 8221a9fRLHF 训练里能踩的坑都在这
RLHF 训练比 SFT 难调 10 倍。本章汇总在 TRL 上踩过的高频坑,按"现象 → 原因 → 处理"分类。
11.1SFT 阶段
| 现象 | 原因 | 处理 |
| loss 一直在 ln(vocab) 附近 | tokenizer EOS / pad 没对 | tok.pad_token = tok.eos_token |
| chat template 报错 | tokenizer 没 chat_template | 显式 tok.chat_template = "..." 或换支持的模型 |
| 训完模型不会 EOS | assistant_only_loss 没开,EOS 在 user 部分被 mask 了 | 开 assistant_only_loss=True |
| packing 后 loss 异常低 | 不同样本之间 attention 串了 | 开 padding_free=True 用 flash-attn 的 cu_seqlens |
| 多轮对话效果差 | 每个 assistant 都算 loss 时数据分布偏向短回复 | 只对最后一轮算或加 length normalize |
11.2DPO / KTO / IPO 阶段
| 现象 | 原因 | 处理 |
| 训完模型乱码 | lr 太大;DPO 应 1e-6 / LoRA 5e-6 | 降 lr 10× |
| chosen / rejected reward 都涨 | 跑偏;正常应只有 chosen 涨 | 降 lr;查偏好数据是否搞反 |
| 训完 hardly 改变 | policy 离 ref 太近;beta 太大 | beta 从 0.1 → 0.05 |
| 训完只回答短句 | length bias:长 sequence log-prob 求和值大 | SimPO(length norm)或减 max_length |
| 偏好准确率比训前还低 | 偏好数据噪声 >= 30% | 换数据;或开 label_smoothing=0.1 |
11.3PPO / GRPO 阶段
| 现象 | 原因 | 处理 |
| reward 飙升但答案质量崩 | 典型 reward hacking | 加大 KL(kl_coef ×2-5);或加 reward whitening |
| KL 散度一直涨 | KL 惩罚不够 | kl_coef 0.05 → 0.2 |
| policy collapse(只输出一种回答) | entropy 太低 | 加 entropy bonus(PPO 自带);或加大 KL |
| policy 训丢了 chat 格式 | 没用 SFT 模型初始化;reference 不是同一个 SFT | policy 和 ref 必须从同一 SFT ckpt 起 |
| rollout 训完吐空字符串 | EOS 立刻被采样 | 开 missing_eos_penalty;或调 sampling temperature |
| GRPO 的 advantage 全是 NaN | group 内 reward 完全一样 (std=0) | 提高 sampling temperature;或换 reward fn |
| RM 训完后 PPO 不收敛 | RM 输出范围太大 | RM 训时开 center_rewards_coefficient |
11.4显存类问题
| 现象 | 处理 |
| SFT OOM | gradient_checkpointing=True;改 LoRA / QLoRA |
| DPO OOM(双倍) | 用 LoRA + ref_model=None(自动用 disable_adapter) |
| PPO OOM(四倍) | LoRA + ref_model=None + ZeRO-3 |
| GRPO rollout OOM | 降 vllm_gpu_memory_utilization;降 num_generations |
11.5多卡 / 分布式
| 现象 | 处理 |
| accelerate 报"world_size mismatch" | accelerate config 设的 num_processes 跟 --nproc_per_node 不一致 |
| DeepSpeed ZeRO-3 + LoRA 报错 | 需要 transformers ≥ 4.45 + peft ≥ 0.10 |
| 多机训 RM 慢 | RM 内部 batch 翻倍;调 gradient_accumulation |
| 多机 GRPO vLLM 启动慢 | 每张卡都启一个 vLLM;用 server 模式集中起一份 |
11.6调试技巧
开 verbose 日志
export TRANSFORMERS_VERBOSITY=info
export ACCELERATE_DEBUG_MODE=1
export TORCH_DISTRIBUTED_DEBUG=DETAIL
看 trainer 状态
trainer.train()
print(trainer.state.log_history[-5:]) # 最近 5 条 metrics
Sanity check:1-step overfit
用 1 个样本反复训 50 step,loss 应该接近 0。如果不能 overfit,说明 trainer / data / model 有 bug。
11.7实用配方(按场景)
| 场景 | 建议起点 |
| SFT 7B 单卡 | LoRA r=16,bf16,packing,2e-4 |
| DPO 7B 单卡 | LoRA + ref_model=None,beta=0.1,5e-6 |
| GRPO 7B 4 卡 | vLLM colocate,G=8,beta=0.04,1e-6 |
| PPO 7B 8 卡 | LoRA,kl=0.1,cliprange=0.2,1e-6 |
11.8v0 → v1 升级常见坑
2026-03 发布的 TRL v1 带来一组静默默认值变更,老代码移植过来跑不出预期结果时先查这张表(完整列表见 repos/trl/MIGRATION.md):
| 症状 | 真实原因 | 修复 |
| GRPO 训练莫名占用一组 GPU 却不出现 vLLM 进程 | vllm_mode 默认从 "server" 改成 "colocate" | 显式写 vllm_mode="server" 多机场景 |
| RLOO 同上 | 同上 | 同上 |
SFT 训练 log 出现 packing="bfd-requeue" is deprecated | v0 字符串名 | 改成 packing="bfd_split"(或直接 True) |
| 训练 batch 出现莫名长度 0 / Tensor None 报错 | v0 自动剔除 dataset 里 None 值,v1 不剔了 | 预处理 dataset.map(trl.trainer.utils.remove_none_values) |
导入 from trl import PPOTrainer 报警 "experimental" | PPO 被挪到 trl/experimental/ppo/ | 正常,可 TRL_EXPERIMENTAL_SILENCE=1 关掉警告 |
| OnlineDPO / Nash-MD / XPO 也都报警 | 这几个 trainer 也在 experimental 区 | 同上 |
11.9trl env:报 issue 必贴
调试卡住时第一步:跑 trl env(trl/scripts/env.py)。它一次性吐出:
- OS、Python、PyTorch、CUDA 版本;
- transformers / accelerate / peft / trl / vllm / bitsandbytes / flash-attn 各自版本;
- GPU 数量与型号;
- accelerate 配置摘要;
- HF Hub token 是否设了。
GitHub issue / discord 提问都建议直接贴它的输出 —— 比手写"我的版本是 ..."准确 100%。
11.10v1 之后日常踩的几个新坑
| 现象 | 原因 | 修复 |
| colocate 模式启动几秒后 CUDA OOM | vLLM 占的 GPU 和训练抢同一张卡 | 错开 CUDA_VISIBLE_DEVICES 或调小 vllm_gpu_memory_utilization |
| 多 reward function 时 group advantage 全 0 | 所有 reward 在 group 内方差为 0(题目太简单 / 太难) | 过滤 dataset 或加扰动 |
| chat template 训练时 token 数对不上 generate 时 | 没用 *_training.jinja 训练模板 | SFT/GRPO 显式 chat_template_path |
| DPO loss=NaN 第一步 | ref / policy 完全相同(没传 ref,也没装 PEFT) | 必须二选一:传 ref_model 或传 peft_config |
| GRPO reward function 抛异常但训练没停 | 函数返回 None TRL 会跳过该样本,不报错 | 显式 try/except 打日志 |
11.11这章你需要带走的
- RLHF 调试黄金法则:lr 比 SFT 小 10-100 倍;
- 偏好类算法的"反向"通常是数据搞反或 lr 太大;
- 显存问题先上 LoRA + ref_model=None;
- 能 1-step overfit 是验证 trainer 正确性的关键 sanity check;
- reward hacking 加大 KL / reward whitening。