Accelerate 文档

比较不同分布式设置下的性能

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

比较不同分布式设置下的性能

如果你不知道要关注什么,评估和比较不同设置下的性能可能会非常棘手。例如,你不能在 TPU、多 GPU 和单 GPU 上使用 Accelerate 运行具有相同批次大小的相同脚本,并期望结果一致。

但为什么会这样呢?

本教程将涵盖三个原因:

  1. 设置正确的种子
  2. 观察到的批次大小
  3. 学习率

设置种子

虽然这个问题不常出现,但请确保使用 utils.set_seed() 在所有分布式情况下完全设置种子,以确保训练是可复现的。

from accelerate.utils import set_seed

set_seed(42)

为什么这很重要?在底层,这会设置 5 个不同的种子设置:

    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed) # or torch.xpu.manual_seed_all, etc
    # ^^ safe to call this function even if cuda is not available
    if is_torch_xla_available():
        xm.set_rng_state(seed)

`random` 状态、numpy 状态、torch、torch 的设备状态,以及如果 TPU 可用,则还有 torch_xla 的 cuda 状态。

观察到的批次大小

当使用 Accelerate 进行训练时,传递给数据加载器(dataloader)的批次大小是 每个 GPU 的批次大小。这意味着在两个 GPU 上,批次大小为 64,实际上等同于总批次大小为 128。因此,在单 GPU 上测试时需要考虑到这一点,TPU 的情况也类似。

下表可作为快速参考,用于尝试不同的批次大小。

在本例中,“多 GPU” 指的是两个 GPU,而 TPU pod 有 8 个工作进程。

单 GPU 批次大小 等效的多 GPU 批次大小 等效的 TPU 批次大小
256 128 32
128 64 16
64 32 8
32 16 4

学习率

正如多个资料[1][2]所指出的,学习率应根据设备数量进行线性缩放。以下代码片段展示了如何使用 Accelerate 实现这一点。

由于用户可以定义自己的学习率调度器,我们把是否缩放学习率的决定权留给用户。

learning_rate = 1e-3
accelerator = Accelerator()
learning_rate *= accelerator.num_processes

optimizer = AdamW(params=model.parameters(), lr=learning_rate)

你还会发现,`accelerate` 会根据训练的进程数量来调整学习率的步进。这是因为前面提到的观察到的批次大小。因此,在 2 个 GPU 的情况下,学习率的步进频率将是单个 GPU 的两倍,以适应大两倍的批次大小(如果单 GPU 实例的批次大小没有改变)。

梯度累积和混合精度

在使用梯度累积和混合精度时,由于梯度平均的工作方式(累积)和精度损失(混合精度),预计性能会有所下降。在比较不同计算设置之间的逐批次损失时,这一点会很明显。然而,在训练结束时,总损失、评估指标和整体性能应该是大致相同的。

< > 在 GitHub 上更新