1-Cycle 调度

本教程展示了如何在 PyTorch 中实现学习率和动量的 1-Cycle 调度。

1-Cycle 调度

最近的研究表明,大型批次训练的缓慢收敛问题可以通过在训练期间使用循环和衰减调度调整学习率和动量等关键超参数来解决。在 DeepSpeed 中,我们实现了一种最先进的调度,称为 1-Cycle,以帮助数据科学家有效地使用更大的批次大小来训练他们在 PyTorch 中的模型。

先决条件

要使用 1-Cycle 调度进行模型训练,您应该满足以下两个要求

  1. 使用 入门 指南将 DeepSpeed 集成到您的训练脚本中。
  2. 将参数添加到模型的参数中,以配置 1-Cycle 调度。我们将在下面定义 1-Cycle 参数。

概述

1-Cycle 调度分两个阶段运行:循环阶段和衰减阶段,它们跨越训练数据的迭代。为了具体起见,我们将回顾 1-Cycle 学习率调度的工作原理。在循环阶段,学习率在一定数量的训练步骤内在最小值和最大值之间振荡。在衰减阶段,学习率从循环阶段的最小值开始衰减。下图说明了模型训练期间 1-Cycle 学习率调度的示例。

1cycle_lr

1-Cycle 参数

1-Cycle 调度由许多参数定义,这些参数允许用户探索不同的配置。文献建议同时调整学习率和动量,因为它们是相关的超参数。我们利用了这一建议,通过将 1-Cycle 参数组织成两组来减少配置负担

  1. 用于配置循环和衰减阶段的全局参数。
  2. 用于配置学习率和动量的局部参数。

配置 1-Cycle 阶段的全局参数为

  1. cycle_first_step_size: 完成循环阶段第一步的训练步骤数量。
  2. cycle_first_stair_count: 循环阶段第一步中的更新(或阶梯)数量。
  3. cycle_second_step_size: 完成循环阶段第二步的训练步骤数量。
  4. cycle_second_stair_count: 循环阶段第二步中的更新(或阶梯)数量。
  5. post_cycle_decay_step_size: 衰减阶段衰减超参数的训练步骤间隔。

超参数的局部参数为

学习率:

  1. cycle_min_lr: 循环阶段的最小学习率。
  2. cycle_max_lr: 循环阶段的最大学习率。
  3. decay_lr_rate: 衰减阶段学习率的衰减率。

尽管可以根据经验或专业知识选择合适的 cycle_min_lrcycle_max_lr 值,但我们建议使用 DeepSpeed 的 学习率范围测试 功能来配置它们。

动量

  1. cycle_min_mom: 循环阶段的最小动量。
  2. cycle_max_mom: 循环阶段的最大动量。
  3. decay_mom_rate: 衰减阶段动量的衰减率。

所需的模型配置更改

为了说明在模型训练中使用 1-Cycle 调度所需的模型配置更改,我们将使用一个具有以下属性的调度

  1. 一个对称的循环阶段,其中循环的每一半跨越相同数量的训练步骤。对于此示例,学习率从 0.0001 增加到 0.0010(10 倍缩放)需要 1000 个训练步骤,然后降回到 0.0001。动量将相应地在类似数量的步骤内在 0.85 和 0.99 之间循环。
  2. 一个衰减阶段,其中学习率每 1000 步衰减 0.001,而动量不会衰减。

请注意,这些参数由 DeepSpeed 作为会话参数处理,因此应将其添加到模型配置的相应部分。

PyTorch 模型

PyTorch 版本 1.0.1 及更高版本提供了一个用于实现超参数调度程序的功能,称为 学习率调度程序。我们使用此功能实现了 1-Cycle 调度。您将添加一个类型为 “OneCycle” 的调度程序条目,如下所示。

"scheduler": {
    "type": "OneCycle",
    "params": {
        "cycle_first_step_size": 1000,
        "cycle_first_stair_count": 500,
        "cycle_second_step_size": 1000,
        "cycle_second_stair_count": 500,
        "decay_step_size": 1000,
        "cycle_min_lr": 0.0001,
        "cycle_max_lr": 0.0010,
        "decay_lr_rate": 0.001,
        "cycle_min_mom": 0.85,
        "cycle_max_mom": 0.99,
        "decay_mom_rate": 0.0
    }
},

批次缩放示例

为了举例说明 1-Cycle 调度如何实现有效的批次缩放,我们简要分享了我们在 Microsoft 内部模型上的经验。在这种情况下,该模型针对单 GPU 上的快速收敛(以数据样本为单位)进行了很好的调整,但在 8 个 GPU(8 倍批次大小)上训练时,收敛到目标性能 (AUC) 的速度很慢。下图显示了使用 8 个 GPU 的这些学习率调度的模型收敛情况

  1. 固定: 使用 1-GPU 训练的最佳固定学习率。
  2. LinearScale: 使用一个固定学习率,该学习率是 固定 的 8 倍。
  3. 1Cycle: 使用 1-Cycle 调度。

model_convergence

使用 1Cycle,模型比其他调度更快地收敛到目标 AUC。事实上,1Cycle 收敛速度与最佳 1-GPU 训练一样快(未显示)。对于 固定,收敛速度大约慢 5 倍(需要 5 倍多的数据样本)。使用 LinearScale,模型发散,因为学习率太高。下图通过报告 8-GPU 训练期间的学习率值来说明这些调度。

lr_schedule

我们看到,1Cycle 的学习率始终大于 固定,并且短暂地大于 LinearScale,以实现更快的收敛。此外,与 LinearScale 相比,1Cycle 在训练后期降低了学习率,以避免模型发散。总之,通过配置适当的 1-Cycle 调度,我们能够将该模型的训练批次大小有效地扩展 8 倍,而不会损失收敛速度。

更新: