多 GPU 中的人工智能:ZeRO 和 FSDP

了解零冗余优化器的工作原理、如何从头开始实现它以及如何在 PyTorch 中使用它多 GPU 中的人工智能后处理:ZeRO 和 FSDP 首先出现在《走向数据科学》上。

来源:走向数据科学

简介

在上一篇文章中,我们了解了分布式数据并行 (DDP) 如何通过在 GPU 之间拆分批次来加速训练。 DDP解决了吞吐量问题,但也带来了新的挑战:内存冗余。

在普通 DDP 中,每个 GPU 都保存模型参数、梯度和优化器状态的完整副本。对于像 GPT-3(175B 参数)这样的大型模型,这种冗余对宝贵的 VRAM 造成了极大的浪费。

ZeRO(零冗余优化器)解决了这个问题。共有三个级别:

  • ZeRO-1 仅对优化器状态进行分区
  • ZeRO-2 分区优化器状态 + 梯度
  • ZeRO-3 分区优化器状态 + 梯度 + 模型参数
  • ZeRO 不是一种并行技术,因为所有 GPU 仍然运行相同的前向和后向传递。这是一种内存优化策略,可以消除 GPU 之间的冗余,让您可以在相同的硬件上训练更大的模型。

    DDP 中的内存问题

    让我们分解一下训练期间实际消耗内存的内容。对于带有参数的模型:

  • 模型参数:值(神经网络的权重)
  • 渐变:值(每个参数一个渐变)
  • 优化器状态 (Adam):值(每个参数的第一时刻和第二时刻)
  • 激活:前向传递过程中存储的中间输出,用于后向传递
  • 前三个随模型大小缩放,并且在 DDP 中的 GPU 之间是冗余的。激活随着批量大小、序列长度和神经元数量而变化,并且每个 GPU 都是唯一的,因为每个 GPU 处理不同的数据。 ZeRO 不触及激活内存。

    让我们计算一下使用 Adam 和 FP32 的 7B 参数模型的内存使用情况:

  • 参数:70 亿 * 4 字节 = 28 GB
  • 渐变:70 亿 * 4 字节 = 28 GB
  • 优化器状态:70 亿 * 2 * 4 字节 = 56 GB
  • DDP 中每个 GPU 的内存:112 GB
  • 让我们从头开始实现 ZeRO 的工作原理,从 ZeRO-1 开始一直到 ZeRO-3。

    ZeRO-1:优化器状态分区

  • 向后传递:计算梯度