【问题标题】:sagemaker horizontally scaling tensorflow (keras) modelsagemaker 水平缩放张量流(keras)模型
【发布时间】:2019-12-22 18:04:17
【问题描述】:

我大致遵循这个脚本fashion-MNIST-sagemaker

我在笔记本上看到了

from sagemaker.tensorflow import TensorFlow

tf_estimator = TensorFlow(entry_point='mnist_keras_tf.py', 
                          role=role,
                          train_instance_count=1, 
                          train_instance_type='local',
                          framework_version='1.12', 
                          py_version='py3',
                          script_mode=True,
                          hyperparameters={'epochs': 1}
                         )

我想知道我可以并且应该在多大程度上使用train_instance_count 参数。它会自动沿着某个维度分配训练吗?如果是的话 - 维度是什么?

此外,在基于 keras(使用 tensorflow)的设置中水平分布训练通常有意义吗?

【问题讨论】:

    标签: python tensorflow keras amazon-sagemaker horizontal-scaling


    【解决方案1】:

    分布式训练是特定于模型和框架的。并非所有模型都易于分发,并且从 ML 框架到 ML 框架的事情并非同样容易。 它很少是自动的,更不用说 TensorFlow 和 Keras。

    在数据并行范式下,神经网络在概念上很容易分布,其中给定小批量的梯度计算在工作人员之间分配,这些工作人员可以是同一主机中的多个设备(多设备)或多个主机每个多设备(多设备多主机)。 D2L.ai 课程深入介绍了神经网络如何分布herehere

    Keras 过去很容易通过 multi_gpu_model, which will sadly get deprecated in 4 months 以多设备、单主机方式分发。在您的情况下,您似乎指的是多主机模型(多台机器),这需要编写临时同步代码,例如在this official tutorial 中看到的代码。

    现在让我们看看这与 SageMaker 有何关系。

    SageMaker 提供 3 个用于算法开发的选项。根据您选择的选项,使用分布式训练可能需要不同数量的自定义工作:

    1. 内置算法是一个包含 18 种预写算法的库。其中许多被编写为分布在单主机多 GPU 或多 GPU 多主机中。使用第一个选项,除了将 train_instance_count > 1 设置为分布在多个实例上之外,您无需做任何事情

    2. 框架容器(您正在使用的选项)是为流行框架(TensorFlow、PyTorch、Sklearn、MXNet)开发的容器,并提供预先编写的 docker 环境,您可以在其中编写任意代码。在此选项中,某些容器将支持一键创建临时训练集群来进行分布式训练,但是使用大于 1 的train_instance_count 不足以分发模型的训练。它只会在多台机器上运行您的脚本。为了分发您的训练,您必须在 mnist_keras_tf.py 脚本中编写适当的分发和同步代码。 对于某些框架,此类代码修改将非常简单,例如对于 TensorFlow 和 Keras,SageMaker 带有 Horovod pre-安装。 Horovod 是一种点对点的环形通信机制,只需要很少的代码修改并且具有高度可扩展性(initial annoucement from UberSageMaker docSageMaker exampleSageMaker blog post)。我的建议是尝试使用 Horovod 分发您的代码。同样,在 Apache MXNet 中,您可以轻松创建参数存储,以分布式方式托管模型参数,并从多个节点与它们同步。 MXNet 的可扩展性和易于分发是亚马逊喜欢它的原因之一。

    3. 自带容器要求您同时编写 docker 容器和算法代码。在这种情况下,您当然可以将训练分布在多台机器上,但您还必须编写机器对机器的通信代码

    对于您的具体情况,我的建议是首先在具有多个 GPU 的单个节点中在越来越大的机器类型上进行水平扩展,因为当您从单主机环境切换到多主机环境时,延迟和复杂性会急剧增加。如果确实有必要,请使用多节点上下文,如果使用 Horovod,事情可能会更容易。 在任何情况下,使用 SageMaker 做事情仍然容易得多,因为它可以管理创建具有内置、日志记录和元数据以及工件持久性的临时、每秒计费的集群,还可以处理从 s3 快速加载训练数据,在训练上分片节点。

    关于分布式训练的相关性的注意事项:请记住,当您在 N 台设备上分发在一台设备上运行良好的模型时,您通常会将批量大小增加 N,以便每个-设备批量大小保持不变,每个设备都保持忙碌。这会干扰您的模型收敛,因为更大的批次意味着更少的 SGD。一个常见的启发式方法是将学习率提高 N (更多信息在 this great paper from Priya Goyal et al 中),但另一方面这会在前几个时期引起不稳定,因此它有时与学习率预热有关。扩展 SGD 以使其适用于非常大的批次仍然是一个活跃的研究问题,新想法经常出现。使用非常大的批次达到良好的模型性能有时需要临时研究和大量的参数调整,有时需要花费额外的钱来寻找如何很好地分布,这会抵消您最终设法运行的更快训练的好处。分布式训练有意义的情况是,当单个记录表示太多计算以在设备上形成足够大的物理批次时,这种情况在大输入尺寸(例如高清图片上的视觉)或大参数计数(例如 BERT)上看到。话虽如此,对于那些需要非常大的逻辑批次的模型,您不一定必须物理分配事物:您可以通过单个 GPU 顺序运行 N 个批次,并在进行梯度平均和参数更新以模拟之前等待每个设备的 N 个批次拥有 N 倍大的 GPU。 (有时称为梯度累积的巧妙技巧)

    【讨论】:

    • @oliver_cruchant - 感谢您的精彩回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 2021-01-29
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多