亚马逊的分布式培训 SageMaker - Amazon SageMaker
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

亚马逊的分布式培训 SageMaker

SageMaker为计算机视觉 (CV) 和自然语言处理 (NLP) 等深度学习任务提供分布式训练库并支持各种分布式训练选项。借助SageMaker的分布式训练库,您可以运行高度可扩展且经济实惠的自定义数据parallel 建模并parallel 深度学习训练作业。您还可以使用其他分布式训练框架和包,例如 PyTorch DistributedDataParallel (DDP) torchrun、MPI (mpirun) 和参数服务器。在整个文档、说明和示例中,重点介绍如何使用 SageMaker Python SDK 为深度学习任务设置分布式训练选项。

提示

要了解机器学习 (ML) 训练和处理作业的分布式计算的总体最佳实践,请参阅采用 SageMaker 最佳实践的分布式计算

开始使用分布式训练

如果您熟悉分布式训练,请选择以下与您的首选策略或框架相匹配的选项之一开始训练。如果您想了解分布式训练的总体情况,请参阅基本的分布式训练概念

SageMaker分布式训练库针对SageMaker训练环境进行了优化,可帮助您的分布式训练作业适应SageMaker并提高训练速度和吞吐量。这些库既提供数据parallel 训练策略,也提供模型并parallel 训练策略。它们结合了软件和硬件技术,以改善 GPU 间和节点间通信,并通过内置选项扩展SageMaker训练能力,只需对训练脚本进行最少的代码更改。 

  • 要使用SageMaker数据并行库,请配置SageMaker框架估distribution算器的参数。支持的框架估算器是和。PyTorchTensorFlow以下代码示例显示如何使用数据并行库在两个实例上设置分布式训练的框架估计器。ml.p4d.24xlarge

    from sagemaker.framework import Framework estimator = Framework( ..., instance_count=2, instance_type="ml.p4d.24xlarge", distribution={"smdistributed" : {"dataparallel" : {"enabled" : True}}} )

    要了解如何准备训练脚本和启动分布式训练作业,请参阅SageMaker数据并行库(另请参阅 SageMaker Python S DK 文档中的分布式训练 API)。

  • 要使用SageMaker模型并行度库,请配置SageMaker框架估distribution算器的参数。支持的框架估算器是和。PyTorchTensorFlow以下代码示例演示了如何在两个实例上使用模型并行库构建具有的框架估计器。ml.p4d.24xlarge

    from sagemaker.framework import Framework distribution={ "smdistributed": { "modelparallel": { "enabled":True, "parameters": { ... # enter parameter key-value pairs here } }, }, "mpi": { "enabled" : True, ... # enter parameter key-value pairs here } } estimator = Framework( ..., instance_count=2, instance_type="ml.p4d.24xlarge", distribution=distribution )

    要了解如何准备训练脚本、配置分布参数和启动分布式训练作业,请参阅模型并行度库(另请参阅 SageMaker SageMaker Python S DK 文档中的分布式训练 API)。

SageMaker还支持以下操作mpiruntorchrun后端选项。

基本的分布式训练概念

SageMaker的分布式训练库使用以下分布式训练术语和功能。

数据集和批处理

  • 训练数据集:用于训练模型的所有数据。

  • 全局批处理大小:在每次迭代中从训练数据集中选择并发送到集群中 GPU 的记录数量。这是每次迭代时计算梯度的记录数。如果使用数据并行度,则等于模型副本的总数乘以每个副本的批次大小:。global batch size = (the number of model replicas) * (per-replica batch size)在机器学习文献中,全局批次大小的单个批次通常被称为小批次

  • 每个副本的批次大小:使用数据并行度时,这是发送到每个模型副本的记录数。每个模型副本都会对该批次进行向前和向后传递以计算权重更新。在处理下一组每副本批次之前,生成的权重更新将在所有副本之间同步(平均值)。

  • 微批次:小批处理的子集,或者,如果使用混合模型和数据并行,则它是每个副本大小的批次的子集。当您使用SageMaker分布式模型并行库时,每个微批处理都将输入到训练管道 o ne-by-one 并遵循库运行时定义的执行时间表

训练

  • Epoch:整个数据集中的一个训练周期。每个纪元有多次迭代是很常见的。在您的模型和用例中,您在训练中使用的 epoch 数量是独一无二的。

  • 迭代:使用全局批量大小的批次(小批次)训练数据执行的单次向前和向后传递。训练期间执行的迭代次数由全局批量大小和用于训练的时代数决定。例如,如果一个数据集包含 5,000 个样本,而您使用的全局批量大小为 500,则需要 10 次迭代才能完成单个纪元。

  • 学习率:一个变量,它会影响根据模型的计算误差而发生的权重变化量。学习率在模型的收敛能力以及收敛的速度和最优性中起着重要作用。

实例和 GPU

  • 实例:Amazon机器学习计算实例。它们也被称为节点

  • 集群大小:使用SageMaker分布式训练库时,这是实例数乘以每个实例中的 GPU 数量。例如,如果您在训练作业中使用两个 ml.p3.8xlarge 实例,每个实例有 4 个 GPU,则集群大小为 8。虽然增加集群大小可以缩短训练时间,但必须优化实例之间的通信;否则,节点之间的通信可能会增加开销并导致训练时间变慢。SageMaker分布式训练库旨在优化 Amazon EC2 ML 计算实例之间的通信,从而提高设备利用率和缩短训练时间。

分布式训练解决方案

  • 数据并行:分布式训练中的一种策略,其中训练数据集在由多个 Amazon EC2 ML 实例组成的计算集群中的多个 GPU 上拆分。每个 GPU 都包含模型的副本,接收不同批次的训练数据,执行向前和向后传递,并与其他节点共享权重更新以进行同步,然后进入下一个批次和最终进入另一个时期。

  • 模型并行性:分布式训练中的一种策略,其中模型在由多个 Amazon EC2 ML 实例组成的计算集群中的多个 GPU 上进行分区。该模型可能很复杂,有大量的隐藏层和权重,使其无法容纳到单个实例的内存中。每个 GPU 都带有模型的子集,通过该子集共享和编译数据流和转换。在 GPU 利用率和训练时间方面,模型并行性的效率在很大程度上取决于模型的分区方式以及用于执行向前和向后传递的执行时间表。

  • 流水线执行计划(流水线):流水线执行计划决定了模型训练期间进行计算(微批处理)和跨设备处理数据的顺序。流水线是一种在模型并行中实现真正的并行化的技术,通过让 GPU 同时对不同的数据样本进行计算,克服顺序计算造成的性能损失。要了解更多信息,请参阅流水线执行时间表

高级概念

Machine Learning (ML) 从业者在训练模型时通常面临两个扩展挑战:缩放模型大小和扩展训练数据。 虽然模型大小和复杂性可以提高精度,但单个 CPU 或 GPU 中可以容纳的模型大小是有限的。此外,缩放模型大小可能会导致更多的计算和更长的训练时间。

并非所有模型都能很好地处理训练数据扩展,因为它们需要将所有训练数据提取到内存中进行训练。它们只能垂直扩展,并且可以扩展到越来越大的实例类型。在大多数情况下,扩展训练数据会导致更长的训练时间。

深度学习 (DL) 是一系列特定的 ML 算法,由多层人工神经网络组成。最常见的训练方法是使用小批量随机梯度下降 (SGD)。在小批量 SGD 中,模型是通过在减少误差的方向上对其系数进行微小的迭代变化来训练的。这些迭代是在训练数据集的相同大小的子样本上进行的,这些子样本称为小批次。对于每个小批次,在小批次的每条记录中运行模型,测量其误差并估计误差梯度。然后测量小批量所有记录的平均梯度,并为每个模型系数提供更新方向。对训练数据集进行一次完整传递称为纪元。模型训练通常包含数十到数百个时代。mini-batch SGD 有几个好处:首先,它的迭代设计使训练时间在理论上与数据集大小呈线性。其次,在给定的小批次中,每条记录都由模型单独处理,除了最终的梯度平均值外,无需记录间通信。因此,小批处理特别适合并行化和分发。 

通过在不同的计算设备上分发小批处理的记录来并行化 SGD 训练称为数据parallel 分布式训练,也是最常用的 DL 分发范例。数据parallel 训练是一种相关的分配策略,用于扩展小批量大小并更快地处理每个小批次。但是,数据parallel 训练带来了额外的复杂性,那就是必须计算出来自所有工作线程的梯度平均值并将其传达给所有工作者。随着训练集群的扩展,这个名为 allreduce 的步骤可能会增加开销,如果实施不当或实施不当而导致硬件减去不当,也会严重影响训练时间。 

数据parallel SGD 仍然要求开发人员能够在计算设备(例如单个 CPU 或 GPU)中至少拟合模型和单个记录。在训练非常大的模型时,例如自然语言处理 (NLP) 中的大型变压器,或者在高分辨率图像上训练分割模型,在某些情况下这可能不可行。分解工作负载的另一种方法是将模型分割到多个计算设备上,这种方法称为模型parallel 分布式训练

策略

分布式训练通常分为两种方法:数据parallel 和模型parallel。数据p arallel 是分布式训练的最常见方法:你有大量数据,对其进行批处理,然后将数据块发送到多个 CPU 或 GPU(节点),由神经网络或 ML 算法处理,然后合并结果。每个节点上的神经网络都是一样的。模型par allel 方法用于无法容纳在一个节点内存中的大型模型;它会分解模型并将不同的部分放置在不同的节点上。在这种情况下,您需要将批量数据发送到每个节点,以便在模型的所有部分上处理数据。

网络模型这两个术语经常互换使用:大型模型实际上是一个包含许多层和参数的大型网络。使用大型网络进行训练会生成大型模型,然后将模型加载回网络,其中包含所有预先训练的参数及其权重,将大型模型加载到内存中。当你分解一个模型以将其拆分到节点上时,你也是在分解底层网络。网络由层组成,要分割网络,需要在不同的计算设备上放置图层。

天真地在设备之间拆分图层的一个常见陷阱是严重的 GPU 利用率不足。向前和向后训练本质上都是按顺序进行的,在给定时间,只有一个 GPU 可以主动计算,而其他 GPU 则等待激活信息发送。现代模型parallel 库通过使用流水线执行计划来提高设备利用率来解决这个问题。但是,只有亚马逊SageMaker的分布式模型parallel 库包含自动模型拆分。该库的两个核心功能,即自动模型拆分和流水线执行调度,通过做出可提高设备利用率的自动决策,简化了实现模型并行性的过程。

使用数据并行和模型并行进行训练

如果您使用大型数据集进行训练,请从数据parallel 方法开始。如果您在训练期间内存不足,则可能需要切换到模型parallel 方法,或者尝试混合模型和数据并行。您也可以尝试以下方法来提高数据并parallel 性能:

  • 更改模型的超参数。

  • 减小批次大小。

  • 继续减小批量大小,直到适合为止。如果您将批量大小减少到 1,但内存仍然不足,则应尝试模型parallel 训练。

尝试梯度压缩(FP16、INT8):

尝试减小输入大小:

  • 如果您增加序列链接、需要向下调整批次大小或向上调整 GPU 以分散批次,请减少 NLP 序列长度。

  • 降低图像解析。

检查是否使用批量标准化,因为这可能会影响收敛。当你使用分布式训练时,你的批次会被拆分到 GPU 上,如果批量大小小得多,错误率就会更高,从而干扰模型的收敛。例如,如果您在单个 GPU 上对网络进行原型设计,批量大小为 64,然后扩展到使用四个 p3dn.24xlarge,则现在您有 32 个 GPU,并且每 GPU 的批量大小从 64 降至 2。这可能会打破你在单个节点上看到的收敛性。

在以下情况下,从模型parallel 训练开始:

  • 您的型号不适用于单个设备。

  • 由于模型大小,您在选择较大的批量大小时会面临限制,例如,如果您的模型权重占用了大部分 GPU 内存,而您被迫选择较小、次优的批量大小。 

要了解有关SageMaker分布式库的更多信息,请参阅以下内容:

优化分布式训练

为您的用例和数据自定义超参数,以获得最佳的扩展效率。在以下讨论中,我们将重点介绍一些最具影响力的训练变量并提供state-of-the-art实现参考,以便您可以更多地了解自己的选项。此外,我们建议您参考首选框架的分布式训练文档。

Batch 大小

SageMaker分布式工具包通常允许你进行更大批量的训练。例如,如果模型适合于单个设备但只能以较小的批量大小进行训练,则使用模型并行训练或数据并parallel 训练使您能够在更大的批量规模上进行实验。

请注意,批量大小通过控制每次迭代时模型更新中的噪声量直接影响模型精度。增加批量大小可以减少梯度估计中的噪声量,这在从非常小的批量大小增加时可能会有所帮助,但是随着批量大小增加到较大值,可能会导致模型精度降低。 

提示

调整超参数,确保模型在增加批量大小时训练到令人满意的收敛性。

已经开发了许多技术,以便在增加批量时保持良好的模型收敛性。

小Batch 大小

在 SGD 中,小批量大小量化了梯度估计中存在的噪声量。小批量会产生非常嘈杂的小批量梯度,这不能代表数据集上的真实梯度。大型小批量会导致小批量梯度接近数据集的真实梯度,并且可能不够嘈杂,很可能会被锁定在不相关的最小值中。

要了解这些技术的更多信息,请参阅以下论文:

场景

以下各节介绍您可能需要扩大训练规模的场景,以及如何使用Amazon资源来扩大训练规模。

从单个 GPU 扩展到多个 GPU

机器学习中使用的数据量或模型的大小可能会造成训练模型的时间比你愿意等待的时间更长的情况。有时,由于模型或训练数据太大,训练根本不起作用。一种解决方案是增加用于训练的 GPU 数量。 在具有多个 GPU 的实例上,例如具有p3.16xlarge八个 GPU 的实例,数据和处理分散在八个 GPU 上。当您使用分布式训练库时,这可能会导致训练模型所需的时间达到近线性加速。它所花费的时间略高于一个 GPU 所花费的时间p3.2xlarge的 1/8。

实例类型 GPU
p3.2xlarge 1
p3.8xlarge 4
p3.16xlarge 8
p3dn.24xlarge 8
注意

SageMaker训练使用的 ml 实例类型具有与相应的 p3 实例类型相同的 GPU 数量。例如,ml.p3.8xlarge具有与 p3.8xlarge-4 相同数量的 GPU。

从单个实例扩展到多个实例

如果您想进一步扩大训练规模,则可以使用更多实例。但是,在添加更多实例之前,您应该选择更大的实例类型。查看上表,查看每个 p3 实例类型中有多少 GPU。

如果您已经从 a 上的单个 GPU 跃升到了 a p3.2xlarge p3.8xlarge 上的四个 GPU,但又决定需要更多的处理能力,那么如果您p3.16xlarge在尝试增加实例数之前选择一个,则可能会看到更好的性能并产生更低的成本。根据您使用的库,当您在单个实例上进行训练时,与使用多个实例的场景相比,性能更好,成本也更低。

当你准备好扩展实例数量时,你可以通过设置你的,使用 SageMaker Python SDK estimator 函数来做到这一点instance_count。例如,您可以设置instance_type = p3.16xlargeinstance_count = 2。你在两个相同的实例上有 16 个 GPUp3.16xlarge,而不是单个 GPU 上的八个 GPU。下图显示了扩展和吞吐量,从单个实例上的八个 GPU 开始,然后增加到 64 个实例,总共有 256 个 GPU。

可用区和网络底板

对于多个实例,了解连接实例的网络、它们如何读取训练数据以及它们之间如何共享信息(例如,执行AllReduce操作时集群中节点之间的通信)非常重要。

首先,您的实例必须位于同一区域与同一可用区。例如,中的实例us-west-2必须全部进入us-west-2a。当您使用 SageMaker Python SDK 时,这将为您进行处理。如果您使用 Amazon EC2 并协调自己的训练集群,则需要意识到这一点,否则您的训练速度会受到影响。 

您的训练数据也应位于同一可用区。当您使用SageMaker估算器时,会传入区域和 S3 存储桶,如果数据不在您设置的区域中,则会出现错误。 

优化的 GPU、网络和存储

p3dn.24xlarge实例类型专为快速本地存储和高达 100 千兆位的快速网络底板而设计,我们强烈建议将其作为分布式训练的最高性能选项。SageMaker支持来自 S3 的流式传输数据模式,称为pipe模式。对于分布式训练等 HPC 负载,我们建议您使用 Amazon FSx 作为文件存储。

自定义训练脚本

虽然可以SageMaker轻松部署和扩展实例和 GPU 的数量,但根据您选择的框架,管理数据和结果可能非常具有挑战性,这就是经常使用外部支持库的原因。 这种最基本的分布式训练形式需要修改训练脚本来管理数据分发。

SageMaker还支持 Horovod 和每个主要深度学习框架原生的分布式训练的实现。如果您选择使用这些框架中的示例,则可以遵循Deep SageMaker Learning Containers 容器指南以及演示实现的各种示例笔记本