078在单个 GPU 上高效训练的方法和工具
在单个 GPU 上高效训练的方法和工具¶
本指南展示了实用的技术,用于通过优化内存利用、加速训练或两者来提高模型训练的效率。如果您想了解在训练过程中如何利用 GPU,请首先参考 模型训练解剖学 概念指南。本指南侧重于实用技术。
如果您有一台多 GPU 的机器,这些方法仍然有效,此外您还可以利用 多 GPU 部分 中列出的其他方法。
在训练大型模型时,需要同时考虑两个方面:
- 数据吞吐量/训练时间
- 模型性能
最大化吞吐量(每秒样本数)可以降低训练成本。这通常通过尽可能利用 GPU 并填满 GPU 内存来实现。如果所需的批量大小超过了 GPU 内存的限制,可以使用梯度累加等内存优化技术来帮助解决。
然而,如果首选的批量大小适合内存,就没有必要应用内存优化技术,因为它们可能会减慢训练速度。仅仅因为可以使用大批量,并不意味着应该这样做。在超参数调优过程中,您应该确定哪个批量大小效果最好,然后相应地优化资源。
本指南中涵盖的方法和工具可以根据它们对训练过程的影响进行分类:
| 方法/工具 | 提高训练速度 | 优化内存利用 |
|---|---|---|
| 批量大小选择 | 是 | 是 |
| 梯度累加 | 否 | 是 |
| 梯度检查点 | 否 | 是 |
| 混合精度训练 | 是 | 可能* |
| torch_empty_cache_steps | 否 | 是 |
| 优化器选择 | 是 | 是 |
| 数据预加载 | 是 | 否 |
| DeepSpeed ZeRO | 否 | 是 |
| torch.compile | 是 | 否 |
| 参数高效微调 (PEFT) | 否 | 是 |
* 注:当使用混合精度与小模型和大批量时,会有一定的内存节省;但对于大模型和小批量,内存使用会更大。
您可以结合上述方法以获得累积效果。无论您是使用 Trainer 进行模型训练,还是编写纯 PyTorch 循环,您都可以 使用 🤗 Accelerate 配置这些优化。
如果这些方法没有带来足够的收益,您可以探索以下选项:
最后,如果所有方法仍然不够,即使切换到服务器级 GPU(如 A100),也可以考虑转向多 GPU 设置。所有这些方法在多 GPU 设置中仍然有效,并且您可以利用 多 GPU 部分 中概述的额外并行技术。
批量大小选择¶
要实现最佳性能,首先要确定合适的批量大小。建议使用 2^N 大小的批量和输入/输出神经元数量。通常它是 8 的倍数,但具体取决于所使用的硬件和模型的数据类型。
参考 NVIDIA 推荐的 输入/输出神经元数量 和 批量大小,这些涉及完全连接层(参与 GEMMs(通用矩阵乘法))。
Tensor Core 要求 定义了基于数据类型和硬件的乘数。例如,对于 fp16 数据类型,建议使用 8 的倍数,除非是 A100 GPU,这种情况下使用 64 的倍数。
对于较小的参数,还应考虑 维度量化效应。这里会发生切片,合适的乘数可以显著加速。
梯度累加(Gradient Accumulation)¶
梯度累加 方法旨在分小批计算梯度,而不是一次性计算整个批量的梯度。这种方法通过多次前向和后向传递模型来迭代计算梯度,并在过程中积累梯度。一旦积累了足够数量的梯度,就执行模型的优化步骤。通过使用梯度累加,可以将 有效批量大小 增加到超过 GPU 内存容量的限制。然而,需要注意的是,梯度累加引入的额外前向和后向传递可能会减慢训练过程。
您可以通过在 TrainingArguments 中添加 gradient_accumulation_steps 参数来启用梯度累加: