加速文档

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

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

入门

比较分布式设置的性能

如果你不知道要找什么,评估和比较来自不同设置的性能可能会很棘手。例如,你不能使用相同的批次大小在 TPU、多 GPU 和单个 GPU 上运行相同的脚本,并期望你的结果能对齐。

但为什么呢?

本教程将介绍以下三个原因。

  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)
    # ^^ 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 状态,以及如果有 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 上更新