训练经验与最佳实践
概述
大模型训练往往需要数周甚至数月,训练稳定性、效率和容错能力直接影响项目进度和成本。业界积累了很多经过实践检验的最佳实践,能帮助你少踩坑。
训练稳定性保障
弹性容错与自动重启
大模型训练周期长,可能遇到机器故障、网络问题等导致训练中断。弹性容错能在故障后自动重启训练,节省大量人工干预时间。
关键点:
- 配置自动重启机制,训练中断后能立刻恢复
- 大模型时代,时间就是金钱,稳定比什么都重要
- 使用框架原生支持的容错机制,如DeepSpeed的断点恢复
定期保存Checkpoint
实践:每隔固定步数保存一次checkpoint,训练中断后能从最近断点恢复,避免从头开始。
经验:
- 不要只保留最新checkpoint,保留最近3-5个,防止最新checkpoint损坏
- 根据训练速度和存储容量设置保存间隔,通常每500-3000步保存一次
- 训练时间越长,越需要频繁保存
训练前明确目标
训练一次大模型成本很高,开始训练前想清楚:
- 这次训练的目标是什么
- 记录所有训练参数和中间结果
- 避免重复实验,浪费时间和金钱
- 先小模型验证,再大模型训练
GPU利用率优化
正确评估GPU利用率
nvidia-smi显示的100%利用率不代表真的满负载,实际可能因为数据加载瓶颈、通信瓶颈导致利用率不高。
更好的评估指标:
- TFLOPS:每秒浮点运算次数
- 吞吐量:每秒处理多少tokens
- DeepSpeed等框架已经整合了这些监控
为什么增加GPU但速度没提升?
可能原因:
- 多机多节点训练中,通信瓶颈限制了加速
- 数据加载瓶颈,GPU等数据
- 框架选择不当,不同框架对同一模型资源消耗差异显著
解决方案:
- 检查数据流水线,预处理并行化
- 使用更快的通信网络(如RDMA)
- 选择合适的并行策略
模型大小选择策略
实践经验:
- 先在小规模模型(如2.7B、7B)上验证想法,调试参数,发现问题
- 确认方案可行后,再扩大到13B、30B等更大规模
- 目前业界优化主要集中在6B/7B/13B规模,13B指令微调后就能达到GPT-4约90%效果,性价比很高
加速卡选择
现状:国产AI加速卡目前坑比较多,如果时间不充裕,优先选择Nvidia卡,生态完善,坑少。
训练框架选择
经验:
- 节点少的时候,框架影响不大
- 数百节点大规模训练,DeepSpeed优势明显,启动简便,性能分析方便,是工业界首选
- 同一模型,不同框架资源消耗差异显著,比如OPT-30B用HuggingFace+DeepSpeed比Alpa资源消耗低很多
- 优先选择生态好、社区活跃的框架
环境与依赖问题
分布式环境搭建
在现有环境搭建分布式训练:
- 注意python、pip、virtualenv、setuptools版本一致性
- 否则即使指定了正确Python版本,也会遇到很多依赖问题
- 推荐使用Docker,环境一致性更好,尤其GPU服务器外网可访问时
GLIBC升级问题
重要提醒:遇到需要升级GLIBC等底层库提示时,一定要慎重,不要轻易升级。升级失败可能导致系统宕机,很多命令无法使用。
常见训练问题与解决方案
增量预训练loss持续不下降怎么办?
可能原因和解决方案:
- 学习率不合适:太大导致不收敛,太小学习慢 → 调整学习率
- 数据质量问题:数据清洗不到去,有太多噪音 → 重新清洗数据
- 数据量不够:增量预训练需要至少几B tokens → 增加数据量
- warmup不够:学习率上升太快,模型训练不稳定 → 增加warmup比例
显存不够怎么办?
解决方案:
- ZeRO Offload:使用DeepSpeed ZeRO-2或ZeRO-3,将参数和优化器状态offload到CPU
- 梯度累积:增加梯度累积步数,减小每个step的batch size
- LoRA/QLoRA:只训练低秩矩阵,显存占用大幅降低
- 激活检查点:用时间换空间,节省显存
- 混合精度训练:使用FP16/BF16,减少显存占用
训练发散怎么办?
常见原因和解决方案:
- 学习率太大 → 减小学习率
- batch size太小 → 增大batch size,或者梯度累积
- 初始化不好 → 从预训练checkpoint重新初始化,检查加载是否正确
- 数据异常 → 检查数据中是否有超长样本、异常值
- 梯度爆炸 → 增加梯度裁剪,减小学习率
训练中断恢复
Checkpoint恢复最佳实践
- 保存完整状态:不仅保存模型参数,还要保存优化器状态、学习率调度器状态、随机种子
- 恢复学习率:训练中断后重启,不要重新warmup,应该恢复学习率到中断前的状态
- 实验表明:重新warmup会损伤性能,学习率越大损伤越大
- 保持学习率和衰减节奏不变效果更好
- 验证Checkpoint:保存后验证checkpoint能正常加载,避免保存损坏
弹性训练
现代框架支持弹性训练,节点动态加入退出不影响训练,在不稳定集群环境下很有用。
训练效率优化
数据预处理优化
- 多进程预处理:使用多进程并行预处理数据,避免训练时数据IO瓶颈
- 缓存预处理结果:预处理后缓存,避免每次训练重新预处理
- 流式训练:大数据集使用流式加载,不需要一次性加载到内存
通信优化
多节点训练:
- NCCL:使用NCCL后端进行通信,比Gloo更快
- 网络带宽:保证节点间网络带宽足够,否则会成为瓶颈
- Zero冗余通信:ZeRO已经优化了通信,合理配置stage即可
混合精度训练
最佳实践:
- 大多数情况使用FP16训练,节省显存,加速计算,不影响精度
- 如果遇到梯度溢出,可以尝试BF16(需要GPU支持)
- 开启梯度缩放,处理FP16的下溢问题
Checkpoint策略
保存策略
- 按步数保存:固定步数间隔保存,不按epoch,因为大模型往往只训1个epoch
- 限制保留数量:设置save_total_limit,只保留最近几个checkpoint,节省存储空间
- 保留最佳checkpoint:根据验证ppl保留最佳checkpoint,不一定是最后一个
Checkpoint转换
不同框架checkpoint格式不同,需要转换:
- ZeRO → 合并为单FP32 → 转为FP16 → 转为HuggingFace格式
- 转换后一定要测试能正常加载,做简单推理验证
最佳实践总结
| 方面 | 最佳实践 |
|---|
| 起步 | 先小模型验证,再大规模训练 |
| 容错 | 开启弹性容错,定期保存checkpoint |
| 监控 | 监控TFLOPS和吞吐量,不止看nvidia-smi |
| 框架 | 大规模训练优先DeepSpeed,生态成熟 |
| 学习率 | 增量预训练用原学习率10%,根据batch size缩放 |
| warmup | 学习率越大warmup越大,中断恢复不要重新warmup |
| 数据 | 质量优先,去重和清洗比数量更重要 |
| 环境 | 推荐Docker,不要轻易升级GLIBC |
| 硬件 | 时间有限优先Nvidia,生态完善坑少 |
面试常见问题
-
**大模型训练怎么保证稳定性?
- 开启弹性容错和自动重启,定期保存checkpoint,训练前明确目标记录参数,使用成熟框架如DeepSpeed,监控GPU利用率和loss变化。
-
**为什么增加了GPU训练速度没提升?
- 可能是GPU利用率不高,多机通信瓶颈,或者数据加载瓶颈;需要检查TFLOPS和吞吐量,而不只是看nvidia-smi的利用率。
-
**训练中断后重新启动有什么注意事项?
- 需要恢复学习率到中断前的状态,包括数值和衰减率,不要重新进行warmup,因为实验表明重新warmup会损伤性能。
-
**大模型训练环境搭建有什么坑?
- 要注意各个节点python、pip版本一致性;遇到GLIBC升级要慎重,不要轻易升级;推荐使用Docker保证环境一致性。
-
**说说你知道的训练效率优化方法?
- 数据层面:多进程预处理,缓存结果,流式加载;显存层面:ZeRO offload、LoRA、激活检查点、混合精度;通信层面:使用NCCL后端,保证网络带宽;框架层面:选择DeepSpeed等成熟高效框架。
-
**显存不够怎么训练大模型?
- 可以使用DeepSpeed ZeRO Offload将参数offload到CPU;使用LoRA/QLoRA只训练低秩矩阵;梯度累积减小每个step的batch;激活检查点节省显存;混合精度训练减少显存占用。
-
**训练发散有哪些可能原因?怎么解决?
- 常见原因:学习率太大、batch size太小、数据质量差、初始化错误、梯度爆炸;对应解决:减小学习率、梯度累积增大有效batch、重新清洗数据、检查checkpoint加载、增加梯度裁剪。