加速文档

跨分布式设置比较性能

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)

随机状态、numpy 的状态、torch、torch 的设备状态,以及如果 TPU 可用,则为 torch_xla 的 cuda 状态。

观察到的批量大小

当使用 Accelerate 进行训练时,传递给数据加载器的批量大小是每个 GPU 的批量大小。这意味着在两个 GPU 上批量大小为 64 实际上是批量大小为 128。因此,在单 GPU 上进行测试时,需要考虑到这一点,TPU 也是如此。

下表可用作快速参考,以尝试不同的批量大小

在本例中,“多 GPU” 有两个 GPU,TPU Pod 有 8 个 worker

单 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 实例的两倍(如果在单 GPU 实例上未对批量大小进行任何更改)。

梯度累积和混合精度

当使用梯度累积和混合精度时,由于梯度平均的工作方式(累积)和精度损失(混合精度),预计性能会有所下降。在比较不同计算设置之间的逐批损失时,这将得到明确体现。但是,训练结束时的总体损失、指标和一般性能应该大致相同。

< > 在 GitHub 上更新