自动调优

在学习本教程之前,请确保您已阅读 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 个注意力头
  • 7.74 亿参数。

环境

训练使用 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)
  • datasets (1.11.0)

启用自动调优

要启用自动调优,需在训练脚本中添加 --autotuning run,并在 DeepSpeed 配置文件中添加 "autotuning": {"enabled": true}。如果用户训练脚本将 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 自动调优 是使用 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 倍
调优空间 实验次数 最佳指标值 最佳实验名称
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 自动调优器可以在合理的实验次数内选择出比手动调优更好的配置。自动调优 Hugging Face 示例中的例子将展示自动调优在不同模型上的有效性。

使用 AzureML 进行 DeepSpeed 自动调优

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

更新: