步骤 1:使用 SageMaker 的分布式模型并行库修改自己的训练脚本 - Amazon SageMaker
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

步骤 1:使用 SageMaker 的分布式模型并行库修改自己的训练脚本

使用此部分来学习如何自定义训练脚本以使用 Amazon SageMaker 模型并行性库的核心功能。要使用特定于库的 API 函数和参数,我们建议您将本文档与《SageMaker Python SDK 文档》中的 SageMaker 模型并行库 API 一起使用。

这些部分中提供的训练脚本示例经过简化,旨在重点介绍使用库时必须进行的更改。有关演示如何将 TensorFlow 或 PyTorch 训练脚本与 SageMaker 模型并行性库结合使用的端到端、可运行的笔记本示例,请参阅 Amazon SageMaker 分布式训练笔记本示例

使用 SageMaker 模型并行性库拆分训练脚本的模型

有两种方法可以修改训练脚本以设置模型拆分:自动拆分或手动拆分。

自动模型拆分

使用 SageMaker 的模型并行性库时,可以利用自动模型拆分,也称为自动模型分区。该库使用分区算法来平衡内存,最大限度地减少设备之间的通信并优化性能。您可以配置自动分区算法以优化速度或内存。

或者,您可以使用手动模型拆分。除非您非常熟悉模型架构,并且很好地掌握了如何有效地对模型进行分区的知识,否则我们建议自动拆分模型。

工作方式

自动分区发生在第一个训练步骤中,也就是首次调用 smp.step 修饰的函数时。在此调用期间,库首先在 CPU RAM 上构造模型的版本(以避免 GPU 内存限制),然后分析模型图形并做出分区决策。根据这个决策,每个模型分区加载到一个 GPU 上,然后才会执行第一步。由于这些分析和分区步骤,第一个训练步骤可能需要较长的时间。

在这两个框架中,库均通过自己的后端管理设备之间的通信,而后端针对 Amazon 基础设施进行了优化。

自动分区设计适应了框架的特性,库按照在每个框架中更自然的粒度级别进行分区。例如,在 TensorFlow 中,每个特定的操作都可以分配给一个不同的设备,而在 PyTorch 中,分配在模块级别完成,每个模块都包含多个操作。以下部分介绍了每个框架中的具体设计。

在第一个训练步骤中,模型并行性库在内部运行一个跟踪步骤,用于构造模型图形并确定张量和参数配置。在此跟踪步骤之后,库将构造一个树,该树包含模型中的嵌套 nn.Module 对象,以及通过跟踪收集的其他数据,例如所存储的 nn.Parameters 数量,以及每个 nn.Module 的执行时间。

接下来,库从根目录遍历此树,并运行分区算法,将每个 nn.Module 分配给一个设备,这可以平衡计算负载(按模块执行时间来衡量)和内存使用量(按总共存储的 nn.Parameter 大小和激活来衡量)。如果多个 nn.Modules 共享相同的 nn.Parameter,则将这些模块放置在相同设备上,以避免维护同一个参数的多个版本。在做出分区决策后,分配的模块和权重就会加载到它们的设备上。

有关如何将 smp.step 修饰器注册到 PyTorch 训练脚本的说明,请参阅 PyTorch 的自动拆分

模型并行性库分析可训练变量的大小和图形结构,并在内部使用图形分区算法。该算法为每个操作提供了设备分配,目的是最大限度地减少所需的设备间通信量,但要遵守两个限制:

  • 平衡每个设备中存储的变量数量

  • 平衡每个设备中执行的操作数量

如果您为 optimize 指定 speed(在 Python SDK 的模型并行性参数中),则库会尝试平衡每个设备中的操作数和 tf.Variable 对象数量。否则,它会尝试平衡 tf.Variables 的总大小。

做出分区决策后,库会创建每个设备需要执行的子图形的串行化表示形式,并将其导入到每个设备上。在分区时,库会将使用相同 tf.Variable 的操作,以及属于同一 Keras 层的操作放在同一个设备上。它还遵循 TensorFlow 施加的主机托管限制。举例而言,这意味着如果有两个 Keras 层共享一个 tf.Variable,则属于这些层的所有操作都将放在单个设备上。

有关如何将 smp.step 修饰器注册到 PyTorch 训练脚本的说明,请参阅 TensorFlow 的自动拆分

各个框架的自动模型拆分的比较

在 TensorFlow 中,基本计算单元是 tf.Operation,而 TensorFlow 将模型表示为 tf.Operation 的有向无环图 (DAG),因此模型并行性库对此 DAG 进行分区,以便每个节点都连接到一台设备。至关重要的是,tf.Operation 对象具有足够丰富的可自定义属性,而且它们是通用的,因为每个模型都确保由此类对象的图形组成。

另一方面,PyTorch 没有一个足够丰富和通用的等价操作概念。PyTorch 中最接近具有这些特征的计算单元是 nn.Module,它的粒度级别要高得多,这就是 PyTorch 中的库在此级别进行分区的原因。

手动模型拆分

如果要手动指定如何跨设备对模型进行分区,请使用 smp.partition 上下文管理器。有关如何设置上下文管理器以进行手动分区的说明,请参阅以下页面。

要在进行修改后使用此选项,在步骤 2 中,您需要将 auto_partition 设置为 False,并在 SageMaker Python SDK 的框架估算器类中定义一个 default_partition。任何未通过 smp.partition 上下文管理器明确放置在分区上的操作都将在 default_partition 上执行。在这种情况下,将绕过自动拆分逻辑,并根据您的规范放置每个操作。根据生成的图形结构,模型并行性库会自动创建管道执行计划。