今天聊聊数据并行(DP)和分布式数据并行(DDP)这两个常用的方法。

如果你有2个GPU,那你就可以简单的通过DP和DDP实现更快的训练速度。

Pytorch已经内置这两种方法,官方建议使用DDP。

数据并行(DP)

数据并行是一种简单且常见的方法,它让我们可以在多个GPU上同时进行模型训练。

这个方法的核心思想就是:把一个大批量的数据分成几个小批量,然后让每个GPU处理一个小批量数据。处理完成后,我们把各个GPU计算出来的梯度汇总,然后更新模型权重。

优点

  1. 实现简单:数据并行很容易理解和实现。
  2. 加速训练:因为数据是在多个GPU上同时处理的,所以训练速度会比单个GPU快很多。

缺点

  1. 扩展性有限:当GPU数量增加时,通信和同步开销也会增加,这会限制训练速度的提升。
  2. 只适用于较小模型:如果模型太大,无法放入单个GPU的内存中,那么数据并行就不适用了。

分布式数据并行(DDP)

分布式数据并行是对数据并行的一种改进。在这个方法中,我们不仅把数据切分成小批量,而且还把模型参数在各个GPU上分片存储。这样一来,每个GPU都处理一部分数据,同时也只更新模型的一部分参数。

这种方法的关键在于,我们需要在所有GPU之间同步梯度和模型参数。

优点

  1. 更好的扩展性:DDP的通信和同步开销相对较小,因此在大量GPU上训练时,它能提供更好的扩展性。
  2. 支持更大模型:由于模型参数在各个GPU上分片存储,DDP可以支持无法放入单个GPU内存的大型模型。

缺点

  1. 实现更复杂:与数据并行相比,DDP需要更多的设置和细节处理。
  2. 依赖高速网络:DDP需要在各个GPU之间同步梯度和模型参数,这要求有高速的网络连接。

DP与DDP的区别

通常,DDP比DP更快,但并非总是如此,比如显卡之间不支持 nv-link 的时候。

  • DP基于Python线程,而DDP基于多进程,因此DDP没有诸如全局解释器锁(GIL)之类的Python线程限制。
  • 在GPU卡之间的连接速度较慢时,DDP的实际运行速度可能会更慢。

以下是两种模式之间的主要差异:

DDP

  • 在开始时,主进程将模型从GPU 0复制到其它GPU
  • 然后,对于每个批次:
    • 每个GPU直接计算自己的小批量数据
    • 在反向传播过程中,一旦本地梯度计算好了,它们就会在所有进程之间取平均值

DP

  • 对于每个批次:

    • GPU 0读取数据,然后将一个小批量发送给每个GPU
    • 从GPU 0将最新的模型复制到每个GPU
    • 执行推理并将结果从每个GPU发送到GPU 0,计算loss
    • 将loss从GPU 0分散到所有GPU,进行反向传播
    • 将梯度从每个GPU发送到GPU 0并取平均值

    因此,DDP每个批次只需要进行梯度发送,而DP需要进行5次不同的数据交换。

    DP通过Python线程在进程内复制数据,而DDP通过torch.distributed复制数据。

    在DP下,GPU 0的工作量远大于其他GPU,导致GPU的利用率降低。

    DDP可以在多台机器上使用,但DP则不行。虽然DP和DDP之间还有其他差异,但它们与本讨论无关。

结论

数据并行(DP)和分布式数据并行(DDP)是在深度学习中实现多GPU训练的两种有效方法。通常情况下,DDP比DP更快,但具体差异取决于GPU之间需要同步的数据量。当需要同步的数据越多时,慢速连接可能导致整体运行速度变慢。

在选择使用哪种方法时,要考虑你的硬件条件和实际需求。希望这篇文章能帮助你更好地了解DP和DDP的概念、优缺点以及区别,从而为你的深度学习项目选择合适的多GPU训练策略。

参考

Efficient Training on Multiple GPUs (huggingface.co)