🐡多GPU计算
2021-11-20
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
 
 
 
 
 
12.5. 多GPU训练 - 动手学深度学习 2.0.0-beta0 documentation
到目前为止,我们讨论了如何在CPU和GPU上高效地训练模型,同时在 中展示了深度学习框架如何在CPU和GPU之间自动地并行化计算和通信,还在 中展示了如何使用命令列出计算机上所有可用的GPU。 但是我们没有讨论如何真正实现深度学习训练的并行化。 是否一种方法,以某种方式分割数据到多个设备上,并使其能够正常工作呢? 本节将详细介绍如何从零开始并行地训练网络, 这里需要运用小批量随机梯度下降算法(详见 )。 后面我还讲介绍如何使用高级API并行训练网络(请参阅 )。 我们从一个简单的计算机视觉问题和一个稍稍过时的网络开始。 这个网络有多个卷积层和汇聚层,最后可能有几个全连接的层,看起来非常类似于LeNet [LeCun et al., 1998]或AlexNet[Krizhevsky et al., 2012] 。 假设我们有多个GPU(如果是桌面服务器则有\(2\)个,AWS g4dn.12xlarge上有\(4\)个,p3.16xlarge上有\(8\)个,p2.16xlarge上有\(16\)个)。 我们希望以一种方式对训练进行拆分,为实现良好的加速比,还能同时受益于简单且可重复的设计选择。 毕竟,多个GPU同时增加了内存和计算能力。 简而言之,对于需要分类的小批量训练数据,我们有以下选择。 第一种方法,在多个GPU之间拆分网络。 也就是说,每个GPU将流入特定层的数据作为输入,跨多个后续层对数据进行处理,然后将数据发送到下一个GPU。 与单个GPU所能处理的数据相比,我们可以用更大的网络处理数据。 此外,每个GPU占用的 显存 (memory footprint)可以得到很好的控制,虽然它只是整个网络显存的一小部分。 然而,GPU的接口之间需要的密集同步可能是很难办的,特别是层之间计算的工作负载不能正确匹配的时候, 还有层之间的接口需要大量的数据传输的时候(例如:激活值和梯度,数据量可能会超出GPU总线的带宽)。 此外,计算密集型操作的顺序对于拆分来说也是非常重要的,这方面的最好研究可参见 [Mirhoseini et al., 2017] ,其本质仍然是一个困难的问题,目前还不清楚研究是否能在特定问题上实现良好的线性缩放。 综上所述,除非存框架或操作系统本身支持将多个GPU连接在一起,否则不建议这种方法。 第二种方法,拆分层内的工作。 例如,将问题分散到\(4\)个GPU,每个GPU生成\(16\)个通道的数据,而不是在单个GPU上计算\(64\)个通道。 对于全连接的层,同样可以拆分输出单元的数量。 描述了这种设计,其策略用于处理显存非常小(当时为2GB)的GPU。 当通道或单元的数量不太小时,使计算性能有良好的提升。 此外,由于可用的显存呈线性扩展,多个GPU能够处理不断变大的网络。 然而,我们需要大量的同步或 屏障操作 (barrier operation),因为每一层都依赖于所有其他层的结果。 此外,需要传输的数据量也可能比跨GPU拆分层时还要大。 因此,基于带宽的成本和复杂性,我们同样不推荐这种方法。 最后一种方法,跨多个GPU对数据进行拆分。 这种方式下,所有GPU尽管有不同的观测结果,但是执行着相同类型的工作。 在完成每个小批量数据的训练之后,梯度在GPU上聚合。 这种方法最简单,并可以应用于任何情况,同步只需要在每个小批量数据处理之后进行。 也就是说,当其他梯度参数仍在计算时,完成计算的梯度参数就可以开始交换。 而且,GPU的数量越多,小批量包含的数据量就越大,从而就能提高训练效率。 但是,添加更多的GPU并不能让我们训练更大的模型。 中比较了多个GPU上不同的并行方式。 总体而言,只要GPU的显存足够大,数据并行是最方便的。 有关分布式训练分区的详细描述,请参见 [Li et al., 2014] 。 在深度学习的早期,GPU的显存曾经是一个棘手的问题,然而如今除了非常特殊的情况,这个问题已经解决。 下面我们将重点讨论数据并行性。 假设一台机器有\(k\)个GPU。 给定需要训练的模型,虽然每个GPU上的参数值都是相同且同步的,但是每个GPU都将独立地维护一组完整的模型参数。 例如, 演示了在\(k=2\)时基于数据并行方法训练模型。 ...
 
  • PyTorch
  • 异步计算自动并行
    目录