算力平台:
在分布式设置中比较性能
评估和比较不同设置的性能可能会非常棘手,如果你不知道该关注什么。 例如,你不能在 TPU、多 GPU 和单 GPU 上使用相同的脚本和相同的批量大小运行,并期望结果一致。
但为什么呢?
本教程将涵盖三个原因:
- 设置正确的种子
- 观察到的批量大小
- 学习率
设置种子
虽然这个问题出现得不多,但请确保在所有分布式情况下使用 [utils.set_seed
] 完全设置种子,以确保训练的可重复性:
python
from accelerate.utils import set_seed
set_seed(42)
为什么这很重要?在底层,这将设置 5 个不同的随机种子:
python
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
# ^^ safe to call this function even if cuda is not available
if is_torch_xla_available():
xm.set_rng_state(seed)
随机状态、NumPy 的状态、Torch、Torch 的 CUDA 状态,以及如果 TPUs 可用,torch_xla 的 CUDA 状态。
观察到的批量大小
在使用 Accelerate 进行训练时,传递给数据加载器的批量大小是 每个 GPU 的批量大小。这意味着在两个 GPU 上的批量大小为 64 实际上是 128。因此,在单个 GPU 上进行测试时需要考虑这一点,TPUs 也是如此。
以下表格可以作为快速参考,尝试不同的批量大小:
GPU 数量 | 每个 GPU 的批量大小 | 实际批量大小 |
---|---|---|
1 | 64 | 64 |
2 | 64 | 128 |
4 | 64 | 256 |
8 | 64 | 512 |
Single GPU Batch Size | Multi-GPU Equivalent Batch Size | TPU Equivalent Batch Size |
---|---|---|
256 | 128 | 32 |
128 | 64 | 16 |
64 | 32 | 8 |
32 | 16 | 4 |
学习率
如多个来源所述[1][2],学习率应根据设备数量 线性 调整。以下代码片段展示了如何使用 Accelerate 进行调整:
python
# 假设 num_devices 是设备数量
learning_rate = base_learning_rate * num_devices
python
learning_rate = 1e-3
accelerator = Accelerator()
learning_rate *= accelerator.num_processes
optimizer = AdamW(params=model.parameters(), lr=learning_rate)
你还会发现 accelerate
会根据正在训练的进程数量来调整学习率。这是由于前面提到的观察到的批量大小。因此,在使用 2 个 GPU 的情况下,学习率的调整频率将是单个 GPU 的两倍,以适应批量大小是单个 GPU 的两倍(如果单个 GPU 实例的批量大小没有变化)。
梯度累积和混合精度
在使用梯度累积和混合精度时,由于梯度平均(累积)和精度损失(混合精度)的工作方式,性能下降是预期的。这将在比较不同计算设置的批量损失时明显看到。然而,训练结束时的整体损失、指标和总体性能应该 大致 相同。