自动调整

在逐步学习本教程之前,请确保您已阅读 DeepSpeed 关于 入门零冗余优化器 的教程。

模型训练的一个痛点是找出良好的性能相关配置,例如微批次大小,以充分利用硬件并获得较高的吞吐量。此配置探索过程通常是手动完成的,但非常重要,因为模型训练会重复多次,并且受益于使用良好的配置。手动调整过程不仅耗时,而且结果还取决于硬件。这意味着在一个硬件上的良好配置可能不是另一个不同硬件上的最佳配置。因此,用户必须再次手动调整配置。使用 DeepSpeed,还有更多配置参数可能会影响训练速度,从而使手动调整配置变得更加繁琐。

DeepSpeed 自动调整器缓解了此痛点,并自动发现提供良好训练速度的最佳 DeepSpeed 配置。它不仅减少了用户花费在调整上的时间和资源,而且还可以发现比手动调整方法更好的配置。在本教程中,我们将展示 DeepSpeed 中自动调整功能的用法和优势。有关更多详细信息,请参阅 README.md

调整范围和策略

DeepSpeed 自动调整器使用模型信息、系统信息和启发式方法来有效地调整影响计算和内存效率的系统旋钮,例如 ZeRO 优化阶段、微批次大小以及许多其他 ZeRO 优化配置。目前,DeepSpeed 自动调整器在用户在 DeepSpeed 配置文件中定义的其他配置(如优化器、调度器、fp16)之上调整 ZeRO 阶段、每个 GPU 的微批次大小以及 ZeRO 配置(尚未支持卸载)。请注意,要调整的 ZeRO 阶段、微批次大小和其他 ZeRO 配置也是可配置的,并且可以通过 DeepSpeed 配置文件由用户覆盖。有关详细信息,请参阅 配置调整范围

易用性

DeepSpeed 自动调整易于使用,无需 DeepSpeed 用户更改任何代码。与原始训练脚本(deepspeed your_program.py <normal cl args> --deepspeed ds_config.json)相比,在 DeepSpeed 中调用自动调整功能只需要在 DeepSpeed 启动器之后设置一个 autotuning 标志(有关详细信息,请参阅 用法),并在 DeepSpeed 配置文件中添加 " autotuning": {"enabled": true}。用户可以通过更改 DeepSpeed 配置 JSON 文件中的自动调整配置来进一步定制自动调整过程(有关详细信息,请参阅 自动调整配置)。

示例

我们使用 16 个 Nvidia V100 GPU 训练来自 Hugging Face 的 0.77 亿参数 GPT2-large 模型 来演示自动调整的用法和优势。有关更多示例,请参阅 DeepSpeedExamples 存储库中的 autotuning。请注意,自动调整适用于任何 DeepSpeed 加速的模型训练,不限于 Hugging Face 模型。

该模型具有

  • 36 层
  • 1280 个隐藏维度
  • 20 个注意力头
  • 774M 参数。

环境

训练使用 fp16 并在一个节点上运行,该节点配备 16 个 Nvidia V100 GPU。自动调整使用与训练相同的硬件资源。未定义 max_train_batch_size。使用以下 HF 包。

HF 示例需要从源代码安装 transformers

    git clone https://github.com/huggingface/transformers.git
    cd transformers
    pip install .

可以通过 pip install datasets 安装 datasets

以下是本测试中使用的版本。

  • transformers (4.12.0.dev0)
  • datasets (1.11.0)

启用自动调整

要启用自动调整,请在训练脚本中添加 --autotuning run 并将 "autotuning": {"enabled": true} 添加到 DeepSpeed 配置文件。如果用户训练脚本使用 DeepSpeed 配置参数作为训练脚本参数,则必须在 DeepSpeed 配置文件 autotuning 部分的 arg_mappings 字典中提供 DeepSpeed 配置中的参数与训练脚本参数之间的名称映射。

训练脚本

    deepspeed --autotuning run --num_nodes=$NNODES --num_gpus=$NGPUS $HF_PATH/transformers/examples/pytorch/language-modeling/run_clm.py --deepspeed $DS_CONFIG\
    --model_name_or_path $MODEL_NAME \
    --dataset_name wikitext \
    --dataset_config_name wikitext-2-raw-v1 \
    --do_train \
    --do_eval \
    --fp16 \
    --per_device_train_batch_size $PER_DEVICE_TRAIN_BATCH_SIZE \
    --gradient_accumulation_steps $GRADIENT_ACCUMULATION_STEPS \
    --learning_rate 2e-5 \
    --num_train_epochs $NEPOCHS \
    --output_dir ${OUTPUT_DIR} \
    --overwrite_output_dir

DeepSpeed 配置文件

{
  "train_micro_batch_size_per_gpu": "auto",
  "fp16": {
    "enabled": true
  },
  "autotuning": {
    "enabled": true,
    "arg_mappings": {
      "train_micro_batch_size_per_gpu": "--per_device_train_batch_size",
      "gradient_accumulation_steps ": "--gradient_accumulation_steps"
    }
  }
}

吞吐量比较

下表显示了吞吐量(每秒样本数)比较。还显示了用于实现吞吐量值的每个 GPU 的相应微批次大小 (mbs 或 tmbspg) 和使用的 ZeRO 阶段(括号内)。假设用户在手动调整过程中使用的策略是从 mbs = 1 开始,每次增加 mbs 2,直到耗尽 GPU 内存。

  • baseline 是没有 DeepSpeed (DS) 的普通 Hugging Face (HF),并且 mbs 是手动调整的。
  • HF + DS hand-tuned 是带有 DS 的 HF,并且 mbs 是手动调整的,而其他 DS 配置使用默认值。
  • HF + DS autotuning 是带有 DS 的 HF,并且 DS 配置是从自动调整中选择的。

符号:Hugging Face (HF)、DeepSpeed (DS)、ZeRO 阶段 (z)、梯度累积步数 (gas)、每个 GPU 的微批次大小 (mbs 或 tmbspg)。

模型名称 baseline (普通 HF) HF + DS 手动调整 HF + DS 自动调整 (快速模式)
GPT2-large 27.874 (mbs = 1) 56.797 (z = 1, mbs = 2), 69.061 (z = 1, mbs = 3)

下面显示了详细的 HF + DS autotuning 结果摘要。

请注意,自动调整中使用的性能指标是使用 DeepSpeed 正向、反向和步长函数中捕获的时间计算的。这些时间的总和小于实际的训练步长延迟,因此自动调整使用的吞吐量指标值将高于训练中的端到端吞吐量。

  • 快速模式自动调整时间:27 分钟
  • 实验次数:13
  • 相对于基线的吞吐量提升:2.48 倍
tuning_space num_experiments best_metric_val best_exp_name
z0 4 59.0229 z0_gas1_tmbspg2
z1 5 87.3017 z1_gas1_tmbspg3
z2 3 77.8338 z2_gas1_tmbspg3
z3 1 0 z3_gas1_tmbspg3
global 13 87.3017 z1_gas1_tmbspg3

调整在 0:27:33.988447 完成。实验总数:13。

正如我们所看到的,DeepSpeed 自动调整器可以选择比手动调整更好的配置,并且实验次数合理。自动调整 Hugging Face 示例 中的示例将演示自动调整在不同模型上的有效性。

使用 AzureML 进行 DeepSpeed 自动调整

要尝试使用 AzureML 进行 DeepSpeed 自动调整,请参阅此处的示例 此处

更新: