自动调优

在开始本教程之前,请确保您已经阅读了关于入门零冗余优化器的DeepSpeed教程。

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

DeepSpeed Autotuner 减轻了这一痛点,并自动发现提供良好训练速度的最佳 DeepSpeed 配置。它不仅减少了用户在调优上花费的时间和资源,还能发现比手动调优方法更好的配置。在本教程中,我们展示了 DeepSpeed 中自动调优功能的用法和优势。更多详情,请参阅 README.md

调优范围和策略

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

易用性

DeepSpeed 自动调优易于使用,DeepSpeed 用户无需更改代码。 与原始训练脚本(deepspeed your_program.py --deepspeed ds_config.json)相比,在 DeepSpeed 中调用自动调优功能只需在 DeepSpeed 启动器后设置一个 autotuning 标志(详见 Usage),并在 DeepSpeed 配置文件中添加 " autotuning": {"enabled": true}。用户可以通过更改 DeepSpeed 配置 JSON 文件中的自动调优配置来进一步定制自动调优过程(详见 Autotuning Configuration)。

示例

我们展示了使用16个Nvidia V100 GPU对Hugging Face的7.7亿参数GPT2-large模型进行训练的自动调优的使用和好处。更多示例,请参考DeepSpeedExamples仓库中的autotuning。请注意,自动调优适用于任何DeepSpeed加速的模型训练,不仅限于Hugging Face模型。

该模型具有:

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

环境

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

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

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

datasets 包可以通过 pip install datasets 安装

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

  • transformers (4.12.0.dev0)
  • 数据集 (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 手动调优 是带有 DS 的 HF,其中 mbs 是手动调优的,而其他 DS 配置使用默认值。
  • HF + DS autotuning 是带有 DS 的 HF,并且 DS 配置是从自动调优中选择的。

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

模型名称 基线(普通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 自动调优结果总结如下所示。

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

  • 快速模式自动调优时间:27分钟
  • 实验数量:13
  • 相对于基线的吞吐量提升:2.48倍
翻译结果: 注:根据翻译规则,此HTML内容中的数值和代码部分不需要翻译,因此翻译结果与原内容相同。
调优空间 实验次数 最佳指标值 最佳实验名称
z0 4 59.0229 z0_gas1_tmbspg2
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
全局 13 87.3017 z1_gas1_tmbspg3

调优在0:27:33.988447内完成。总实验次数:13。

正如我们所看到的,DeepSpeed 自动调优器可以通过合理数量的实验选择比手动调优更好的配置。Autotuning Hugging Face Examples 中的示例将展示自动调优在不同模型中的有效性。

使用AzureML进行DeepSpeed自动调优

要尝试使用AzureML进行DeepSpeed自动调优,请参见示例这里

更新: