689 字
3 分钟
【科研】模型训练加速
我自己修改了一下num_workers,从1改为4,速度提高了3倍(4卡12h/epoch -> 6卡3h/epoch),说明有效突破瓶颈。
如何加速训练?
我们可以从数据加载、模型计算和训练策略三个层面来提速。
1. 优化数据加载(最直接、最容易)
- 增加
num_workers
:这是DataLoader
中一个至关重要的参数,它决定了用多少个子进程来预加载数据。如果设为1(如您当前的run.py
所示),意味着数据加载和模型计算是在“你等我,我等你”的模式下进行的。- 修改建议:在
run.py
中创建train_dataloader
时,将num_workers
的值调高。# run.py train_dataloader = torch.utils.data.DataLoader( train_dataset, num_workers=4, # <-- ✨ 从1增加到4或更高 pin_memory=True, # ... a_o_t_h_e_r p_a_r_a_m_e_t_e_r_s ... )
- 效果:这可以让CPU在GPU进行当前批次计算的同时,并行地准备好接下来几个批次的数据,从而大大减少GPU的等待时间。您可以从
4
开始尝试,根据您服务器CPU核心数逐步增加。
- 修改建议:在
2. 启用混合精度训练(最有效)
使用bfloat16
或float16
可以在不严重影响模型精度的情况下,将模型占用的显存减半,并利用现代GPU(如A100)的Tensor Cores进行矩阵运算加速,通常能带来1.5倍到2倍的训练速度提升。
- 修改建议:在您的
args/gsm_coconut.yaml
配置文件中,将bf16
设置为True
。# args/gsm_coconut.yaml seed: 0 resume: 0 bf16: True # <-- ✨ 从 False 改为 True
- 注意:这需要在您的
run.py
中配合PyTorch的autocast
上下文管理器使用,FSDP通常有专门的配置项来支持混合精度训练。
3. 编译模型(PyTorch 2.0+ 功能)
如果您的PyTorch版本是2.0或更高,可以使用torch.compile
来优化您的模型,它会将模型的部分计算图编译成更高效的底层代码。
- 修改建议:在
run.py
中,将FSDP包裹的模型再用torch.compile
包裹一次。# run.py parallel_model = FSDP(...) parallel_model = torch.compile(parallel_model) # <-- ✨ 新增这一行
4. 使用梯度累积(Gradient Accumulation)
这个技巧让您可以在不增加显存占用的情况下,实现与大批量(batch size)训练相同的效果。
作用:不再是每个小批次都更新一次模型权重,而是在多个小批次之间累积梯度,然后进行一次统一的更新。
如何实现:在您的args/gsm_coconut.yaml中,减小实际的批次大小,同时增加累积步数。
# args/gsm_coconut.yaml
...
batch_size_training: 4 # <-- ✨ 从8降低到4
gradient_accumulation_steps: 2 # <-- ✨ 从1增加到2
...
这个设置的等效批次大小仍然是 4 * 2 = 8,但任何时刻的峰值显存占用都会低得多。