Transformers 文档

DeepSpeed

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

DeepSpeed

DeepSpeed 旨在优化大型模型的分布式训练,通过数据并行、模型并行、流水线并行,甚至三者的组合并行策略,来提供更好的内存效率和更快的训练速度。这是通过零冗余优化器 (ZeRO) 实现的,ZeRO 由三个阶段组成。

ZeRO 阶段 描述
1 分区优化器状态
2 分区优化器和梯度状态
3 分区优化器、梯度和参数

每个阶段逐步节省更多内存,使得真正的大型模型能够在一个 GPU 上适配和训练。所有 ZeRO 阶段,将优化器内存和计算从 GPU 卸载到 CPU,都与 Trainer 集成。向 Trainer 提供配置文件或示例模板之一,以启用 DeepSpeed 功能。

本指南将引导您完成设置 DeepSpeed 配置文件、如何在 Trainer 中启用其功能以及部署以进行训练。

从 PyPI 或 Transformers 安装 DeepSpeed。有关更详细的安装说明,请参阅 DeepSpeed 安装指南或 GitHUB README

PyPI
Transformers
pip install deepspeed

如果您的安装遇到问题,请参阅 DeepSpeed CUDA 安装指南。虽然 DeepSpeed 有一个可通过 pip 安装的软件包,但强烈建议从源代码安装它,以确保它与您的硬件匹配,并支持 PyPI 发行版中不可用的某些功能。

DeepSpeed 提供了一个工具,用于估计参数、优化器和梯度状态所需的 CPU 和 GPU 内存。您还需要为 CUDA 内核和激活预留一些内存。

运行以下命令以检查单个 GPU 上 bigscience/T0_3B 的内存需求。

$ python -c 'from transformers import AutoModel; \
from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live; \
model = AutoModel.from_pretrained("bigscience/T0_3B"); \
estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=1, num_nodes=1)'
[...]
Estimated memory needed for params, optim states and gradients for a:
HW: Setup with 1 node, 1 GPU per node.
SW: Model with 2783M total params, 65M largest layer params.
  per CPU  |  per GPU |   Options
   70.00GB |   0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=1
   70.00GB |   0.25GB | offload_param=cpu , offload_optimizer=cpu , zero_init=0
   62.23GB |   5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=1
   62.23GB |   5.43GB | offload_param=none, offload_optimizer=cpu , zero_init=0
    0.37GB |  46.91GB | offload_param=none, offload_optimizer=none, zero_init=1
   15.56GB |  46.91GB | offload_param=none, offload_optimizer=none, zero_init=0

如果您有足够的 GPU 内存,请禁用 CPU 和 NVMe 卸载以加速一切。

选择 ZeRO 阶段

请参考下表来帮助您选择合适的 ZeRO 训练阶段,因为训练速度和内存使用之间存在权衡。该表按从最快到最慢以及从最少内存使用到最多内存使用对 ZeRO 阶段进行了排序。

最快 最少内存使用
ZeRO-1 ZeRO-3 + 卸载
ZeRO-2 ZeRO-3
ZeRO-2 + 卸载 ZeRO-2 + 卸载
ZeRO-3 ZeRO-2
ZeRO-3 + 卸载 ZeRO-1

确定您要优化的性能类型(速度或内存),然后反向推导以找到最适合您用例的 ZeRO 阶段。例如,如果您要优化速度,请从最快的 ZeRO 阶段开始,如果内存不足,请尝试下一个阶段,该阶段速度较慢但内存效率更高。

配置文件

确定 ZeRO 阶段后,设置一个配置文件以使用 Trainer 启用 DeepSpeed。配置文件包含如何配置和设置训练的所有参数。当训练脚本执行时,DeepSpeed 会将 Trainer 的配置记录到控制台,以便您可以准确地看到正在使用的内容。

DeepSpeed Configuration JSON 参考中查找 DeepSpeed 配置选项的完整列表。在 DeepSpeedExamplesDeepSpeed 仓库中也有各种 DeepSpeed 配置示例的实用示例。运行以下命令以快速查找特定示例。

git clone https://github.com/microsoft/DeepSpeedExamples
cd DeepSpeedExamples
find . -name '*json'
# find examples with the Lamb optimizer
grep -i Lamb $(find . -name '*json')

如果您从命令行界面进行训练,则配置文件作为 JSON 文件的路径传递;如果您在 notebook 中使用 Trainer,则配置文件作为嵌套的 dict 对象传递。

文件路径
嵌套字典
TrainingArguments(
    deepspeed="path/to/deepspeed_config.json",
    ...,
)

DeepSpeed 与 Trainer 参数

有三种类型的配置参数。

  1. 一些配置参数由 DeepSpeed 和 Trainer 共享,当存在冲突的定义时,很难识别错误。在这种情况下,请从 Trainer 命令行参数配置这些参数。
  2. 一些配置参数是从模型配置自动派生的,不需要手动配置。Trainer 使用配置值 auto 来设置最正确或最有效的选项。您可以显式定义这些参数,但必须注意确保 Trainer 和 DeepSpeed 配置参数匹配。不匹配可能会导致训练以非常难以检测的方式失败。
  3. 一些配置参数是 DeepSpeed 特有的,应根据您的训练要求手动设置。

有两种修改配置参数的方法。

某些值(例如 scheduler.params.total_num_steps)由 Trainer 在训练期间计算。

  1. 创建或加载 DeepSpeed 配置以用作主配置。
  2. 基于 DeepSpeed 配置值创建一个 TrainingArguments 对象。

ZeRO 阶段

每个 ZeRO 阶段的配置都在 zero_optimization 中定义。

有关每个参数的更详细说明,请参阅 DeepSpeed Configuration JSON 参考。这些参数必须使用 DeepSpeed 设置,因为 Trainer 不提供等效的命令行参数。

DeepSpeed 不会验证参数名称,任何拼写错误都会回退到参数的默认设置。观察 DeepSpeed 引擎启动日志消息,以查看正在使用的值。

ZeRO-1
ZeRO-2
ZeRO-3

ZeRO-1 将优化器状态在 GPU 之间分片,您可以期望获得小的速度提升。

{
    "zero_optimization": {
        "stage": 1
    }
}

NVMe

ZeRO-Infinity 将模型状态卸载到 CPU 和/或 NVMe,以节省更多内存。智能分区和分块算法允许每个 GPU 在卸载期间发送和接收非常少量的数据,从而使现代 NVMe 能够容纳比您的训练过程可用的更大的总内存池。ZeRO-Infinity 需要 ZeRO-3。

根据可用的 CPU 和 NVMe 内存,您可以卸载优化器状态参数,仅卸载其中一个,或都不卸载。确保 nvme_path 指向 NVMe 设备,因为虽然它仍然适用于常规硬盘驱动器或固态硬盘驱动器,但速度会明显较慢。使用现代 NVMe,您可以期望读取操作的峰值传输速度约为 3.5GB/s,写入操作的峰值传输速度约为 3GB/s。

考虑在您的训练设置上运行基准测试,以确定最佳 aio 配置。

下面的 ZeRO-3 和 ZeRO-Infinity 配置示例将大多数参数值设置为 auto,但您也可以手动设置配置这些值。

{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },

    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "nvme",
            "nvme_path": "/local_nvme",
            "pin_memory": true,
            "buffer_count": 4,
            "fast_init": false
        },
        "offload_param": {
            "device": "nvme",
            "nvme_path": "/local_nvme",
            "pin_memory": true,
            "buffer_count": 5,
            "buffer_size": 1e8,
            "max_in_cpu": 1e9
        },
        "aio": {
            "block_size": 262144,
            "queue_depth": 32,
            "thread_count": 1,
            "single_submit": false,
            "overlap_events": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_16bit_weights_on_model_save": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}

训练功能

DeepSpeed 支持许多可以在配置文件中配置的训练功能。本节介绍一些最重要的功能。

梯度检查点

梯度检查点通过仅存储一些中间激活而不是存储所有激活来节省内存。它对于在 GPU 上拟合更大的模型而不耗尽内存或增加批大小以获得更好的性能很有用。但训练速度会较慢。

  • 对于 Transformers 模型,设置 model.gradient_checkpointing_enable() 或在 TrainingArguments 中添加 --gradient_checkpointing
  • 对于非 Transformers 模型,请使用 DeepSpeed Activation Checkpointing API。用 DeepSpeed API 替换 Transformers 建模代码和 torch.utils.checkpoint 可以为您提供更大的灵活性,因为您可以将前向激活卸载到 CPU 内存,而不是重新计算它们。

批大小

批大小可以自动配置或手动设置。当您选择 "auto" 选项时,Trainertrain_micro_batch_size_per_gputrain_batch_size 设置为 world_size * per_device_train_batch_size * gradient_accumulation_steps 的值。

{
    "train_micro_batch_size_per_gpu": "auto",
    "train_batch_size": "auto"
}

通信数据类型

单独的数据类型用于通信集合操作,例如归约、收集和分散操作。

所有收集和分散操作都在数据所在的数据类型中执行。例如,如果您在 bf16 中训练,数据也会在 bf16 中收集,因为收集是无损操作。

归约操作是有损的,例如,当梯度在多个 GPU 之间平均时。当通信在 fp16 或 bf16 中完成时,更有可能是有损的,因为以低精度添加多个数字并不精确。bf16 的情况尤其如此,它的精度比 fp16 低。因此,fp16 是归约操作的默认值,因为在平均梯度时损失最小。

通过在配置文件中设置 communication_data_type 参数来选择通信数据类型。例如,选择 fp32 会增加少量开销,但确保归约操作在 fp32 中累积,并且准备就绪后,它会被降级为您正在训练的任何半精度数据类型。

{
    "communication_data_type": "fp32"
}

梯度累积

梯度累积在更新参数之前,在几个小批量数据上累积梯度。它存储较少的梯度,并能够以更大的有效批大小进行训练。训练速度较慢,但对于克服内存限制很有用。

梯度累积可以自动配置或手动设置。当您选择 "auto" 选项时,Trainer 将其设置为 gradient_accumulation_steps 的值。

{
    "gradient_accumulation_steps": "auto"
}

梯度裁剪

梯度裁剪对于防止梯度爆炸很有用,梯度爆炸可能导致训练期间的不稳定性。它设置最大阈值,并在梯度的范数超过阈值时重新缩放梯度。

梯度裁剪可以自动配置或手动设置。当您选择 "auto" 选项时,Trainer 将其设置为 max_grad_norm 的值。

{
    "gradient_clipping": "auto"
}

混合精度训练

混合精度通过以半精度执行一些计算来加速训练速度,但它也保持一些全精度计算以保持精度。DeepSpeed 支持 fp32、fp16 和 bf16 数据类型。

fp32
fp16
bf16

如果模型未在混合精度中预训练,请在 fp32 中训练,因为它可能导致下溢或溢出错误。在这种情况下,禁用默认的 fp16。

{
    "fp16": {
        "enabled": false
    }
}

对于 Ampere GPU 和 PyTorch 1.7+,更高效的 tf32 模式会自动为某些操作启用,但结果仍然是 fp32。在 Trainer 中配置它,通过设置 --tf32 启用它,以及 --tf32 0--no_tf32 禁用它。

优化器和调度器

如果未启用 offload_optimizer,则 DeepSpeed 和 Transformers 优化器和调度器可以混合和匹配。启用 offload_optimizer 后,使用非 DeepSpeed 优化器(LAMB 除外),只要它具有 CPU 和 GPU 实现。

从命令行设置配置文件的优化器和调度器参数,以避免难以发现的错误。例如,如果学习率在另一个地方设置为不同的值,您可以从命令行覆盖它。

优化器
调度器

DeepSpeed 提供了几种优化器(Adam、AdamW、OneBitAdam 和 LAMB),但您也可以从 PyTorch 导入其他优化器。如果您不在配置中配置优化器,Trainer 会自动选择 AdamW,并使用提供的或以下命令行参数的默认值:lradam_beta1adam_beta2adam_epsilonweight_decay

您可以将参数设置为 "auto" 或手动输入您自己的值。

{
   "optimizer": {
       "type": "AdamW",
       "params": {
         "lr": "auto",
         "betas": "auto",
         "eps": "auto",
         "weight_decay": "auto"
       }
   }
}

通过将以下内容添加到顶层配置来使用不受支持的优化器。

{
   "zero_allow_untested_optimizer": true
}

从 DeepSpeed 0.8.3+ 开始,如果您想使用卸载,您还需要将以下内容添加到顶层配置,因为卸载与 DeepSpeed 的 CPU Adam 优化器配合使用效果最佳。

{
   "zero_force_ds_cpu_optimizer": false
}

通用检查点

通用检查点跨不同的模型架构、并行技术和训练配置保存和加载模型、优化器和训练调度器状态。通过以通用格式保存它们,可以更轻松地进行模型训练的继续和微调。

通过在配置文件中将 load_universal 设置为 true,使用通用检查点恢复训练。

{
    "checkpoint": {
        "load_universal": true
    }
}

部署

DeepSpeed 可以通过其原生启动器、torchrunAccelerate 进行部署。

在命令行中,将 --deepspeed ds_config.json 参数添加到 Trainer 中。 建议使用 DeepSpeed 的 add_config_arguments 实用程序,以便向代码添加任何其他命令行参数。

多 GPU
单 GPU

要在多个 GPU 上部署 DeepSpeed,请添加 --num_gpus。 如果您计划使用所有可用的 GPU,则无需添加 --num_gpus

deepspeed --num_gpus=2 examples/pytorch/translation/run_translation.py \
--deepspeed tests/deepspeed/ds_config_zero3.json \
--model_name_or_path google-t5/t5-small --per_device_train_batch_size 1 \
--output_dir output_dir --overwrite_output_dir --fp16 \
--do_train --max_train_samples 500 --num_train_epochs 1 \
--dataset_name wmt16 --dataset_config "ro-en" \
--source_lang en --target_lang ro

多节点

多节点设置由多个节点组成,其中每个节点都有一台或多台 GPU 运行工作负载。 DeepSpeed 需要共享存储系统,但如果情况并非如此,您需要调整配置文件以包含 checkpoint,以便在无法访问共享文件系统的情况下进行加载。

{
  "checkpoint": {
    "use_node_local_storage": true
  }
}

您还可以使用 TrainingArguments 中的 --save_on_each_node 参数,以自动将上述 checkpoint 添加到您的配置中。

以下 torchrun 和 DeepSpeed 启动器的示例演示了如何部署两个节点,每个节点有八个 GPU。 使用 ssh hostname1 访问第一个节点,使用 ssh hostname2 访问第二个节点。 两个节点都必须能够通过 ssh 在本地相互通信,而无需密码。

torchrun
DeepSpeed

使用 torchrun,通过 ssh 连接到每个节点,并在两个节点上运行以下命令。 启动器将等待两个节点同步,然后启动训练。

torchrun --nproc_per_node=8 --nnode=2 --node_rank=0 --master_addr=hostname1 \
--master_port=9901 your_program.py <normal cl args> --deepspeed ds_config.json

Slurm

Slurm 是一种集群管理和作业调度系统。 下面显示了一个 Slurm 脚本示例。

#SBATCH --job-name=test-nodes        # name
#SBATCH --nodes=2                    # nodes
#SBATCH --ntasks-per-node=1          # crucial - only 1 task per dist per node!
#SBATCH --cpus-per-task=10           # number of cores per tasks
#SBATCH --gres=gpu:8                 # number of gpus
#SBATCH --time 20:00:00              # maximum execution time (HH:MM:SS)
#SBATCH --output=%x-%j.out           # output file name

export GPUS_PER_NODE=8
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
export MASTER_PORT=9901

srun --jobid $SLURM_JOBID bash -c 'python -m torch.distributed.run \
 --nproc_per_node $GPUS_PER_NODE --nnodes $SLURM_NNODES --node_rank $SLURM_PROCID \
 --master_addr $MASTER_ADDR --master_port $MASTER_PORT \
your_program.py <normal cl args> --deepspeed ds_config.json'

使用以下命令在所有节点上同时启动训练。

sbatch launch.slurm

Jupyter Notebook

要在 Jupyter Notebook 中使用 DeepSpeed,您需要模拟分布式环境,因为启动器不支持从 notebook 部署。 这仅支持一个 GPU。 要使用多个 GPU,您必须使用多进程环境,这意味着您必须使用 DeepSpeed 启动器,该启动器无法像此处所示进行模拟。

# emulate a launcher in the notebook
import os

os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "9994"  # modify if RuntimeError: Address already in use
os.environ["RANK"] = "0"
os.environ["LOCAL_RANK"] = "0"
os.environ["WORLD_SIZE"] = "1"

training_args = TrainingArguments(..., deepspeed="ds_config_zero3.json")
trainer = Trainer(...)
trainer.train()

在 notebook 的当前目录中使用专用单元格动态创建配置文件。

%%bash
cat <<'EOT' > ds_config_zero3.json
{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },

    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },

    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },

    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "cpu",
            "pin_memory": true
        },
        "offload_param": {
            "device": "cpu",
            "pin_memory": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_16bit_weights_on_model_save": true
    },

    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "steps_per_print": 2000,
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "wall_clock_breakdown": false
}
EOT

如果训练脚本位于文件中而不是 notebook 单元格中,请从 notebook 单元格中的 shell 启动 DeepSpeed。

!git clone https://github.com/huggingface/transformers
!cd transformers; deepspeed examples/pytorch/translation/run_translation.py ...

另一种选择是使用 %%bash 运行 shell 程序,而无需模拟分布式环境。 但是,您将无法查看日志,直到训练完成。

%%bash

git clone https://github.com/huggingface/transformers
cd transformers
deepspeed examples/pytorch/translation/run_translation.py ...

保存模型权重

DeepSpeed 将主 fp32 权重存储在自定义检查点优化器文件中 (global_step*/*optim_states.pt),这些文件保存在正常检查点下。

fp16

ZeRO-2 以 fp16 格式保存模型权重。 要以 fp16 格式保存 ZeRO-3 的权重,请在配置文件中设置 "stage3_gather_16bit_weights_on_model_save": true,因为权重分布在多个 GPU 上。

如果您不这样做,Trainer 将不会以 fp16 格式保存权重,并且不会创建 pytorch_model.bin 文件。 这是因为 DeepSpeed 的 state_dict 包含占位符而不是真实权重,因此您将无法加载它。

{
    "zero_optimization": {
        "stage": 3,
        "stage3_gather_16bit_weights_on_model_save": true
    }
}

fp32

除非您有大量空闲 CPU 内存,否则不应在训练期间保存 fp32 权重,因为它可能需要大量内存。 通常最好在训练完成后离线保存 fp32 权重。

离线
在线

DeepSpeed 在顶级检查点文件夹中提供了一个 zero_to_fp32.py 脚本,用于在任何时候提取权重。 这是一个独立的脚本,您不需要配置文件或 Trainer

例如,如果您的检查点文件夹如下所示,那么您可以运行以下命令来创建和合并来自多个 GPU 的 fp32 权重到一个 pytorch_model.bin 文件中。 该脚本会自动发现包含检查点的子文件夹 global_step1

$ ls -l output_dir/checkpoint-1/
-rw-rw-r-- 1 stas stas 1.4K Mar 27 20:42 config.json
drwxrwxr-x 2 stas stas 4.0K Mar 25 19:52 global_step1/
-rw-rw-r-- 1 stas stas   12 Mar 27 13:16 latest
-rw-rw-r-- 1 stas stas 827K Mar 27 20:42 optimizer.pt
-rw-rw-r-- 1 stas stas 231M Mar 27 20:42 pytorch_model.bin
-rw-rw-r-- 1 stas stas  623 Mar 27 20:42 scheduler.pt
-rw-rw-r-- 1 stas stas 1.8K Mar 27 20:42 special_tokens_map.json
-rw-rw-r-- 1 stas stas 774K Mar 27 20:42 spiece.model
-rw-rw-r-- 1 stas stas 1.9K Mar 27 20:42 tokenizer_config.json
-rw-rw-r-- 1 stas stas  339 Mar 27 20:42 trainer_state.json
-rw-rw-r-- 1 stas stas 2.3K Mar 27 20:42 training_args.bin
-rwxrw-r-- 1 stas stas 5.5K Mar 27 13:16 zero_to_fp32.py*

运行 python zero_to_fp32.py -h 以获取更多用法详细信息。 该脚本需要最终 fp32 权重的一般 RAM 的 2 倍。

python zero_to_fp32.py . pytorch_model.bin

非 Trainer 集成

DeepSpeed 也适用于没有 Trainer 的 Transformers。 当调用 from_pretrained() 时,HfDeepSpeedConfig 负责收集 ZeRO-3 参数并在多个 GPU 之间划分模型。

您必须在加载模型之前实例化 HfDeepSpeedConfig,以有效部署 ZeRO-3。

预训练模型
非预训练模型
from transformers.integrations import HfDeepSpeedConfig
from transformers import AutoModel
import deepspeed

# DeepSpeed config object or path to the file
ds_config = {...}
# must run before instantiating the model to detect ZeRO-3
dschf = HfDeepSpeedConfig(ds_config)  # keep this object alive
model = AutoModel.from_pretrained("openai-community/gpt2")
engine = deepspeed.initialize(model=model, config_params=ds_config, ...)

故障排除

当您遇到错误时,首先要检查的事情之一是 DeepSpeed 是否是原因(因为它通常不是)。 在没有 DeepSpeed 的情况下重试您的设置,如果错误仍然存在,请报告该问题。 如果问题与 Transformers 集成无关,请在 DeepSpeed 存储库上打开问题。

对于与 Transformers 集成相关的问题,请提供以下信息。

  • 完整的 DeepSpeed 配置文件。

  • 如果您自己编写 Trainer 设置的脚本,则 Trainer 的命令行参数或 TrainingArguments(不要转储包含许多不相关条目的整个 TrainingArguments)。

  • 以下命令的输出。

    python -c 'import torch; print(f"torch: {torch.__version__}")'
    python -c 'import transformers; print(f"transformers: {transformers.__version__}")'
    python -c 'import deepspeed; print(f"deepspeed: {deepspeed.__version__}")'
  • 指向 Google Colab notebook 以重现该问题的链接。

  • 用于重现该问题的标准或非自定义数据集或现有示例。

以下部分提供了解决两个最常见问题的指南。

启动时进程被终止

当 DeepSpeed 进程在启动期间被终止且没有回溯时,这通常意味着程序尝试分配的 CPU 内存超过了系统上的可用内存。 或者,进程可能尝试分配超出允许的 CPU 内存,导致操作系统内核终止该进程。

在这种情况下,请检查您的配置文件是否配置了 offload_optimizerofflload_param 或两者都配置为卸载到 CPU。

如果您设置了 NVM3 和 ZeRO-3,请尝试卸载到 NVMe(首先 估算 模型的内存需求)。

NaN 损失

当模型在 bf16 中预训练,而您尝试将其与 fp16 一起使用时(尤其与 TPU 训练的模型相关),通常会发生 NaN 损失。 要解决此问题,如果您的硬件(TPU、Ampere GPU 或更新型号)支持,请使用 fp32 或 bf16。

fp16 也可能导致溢出。 例如,如果您的配置文件如下所示,您可能会在日志中看到以下溢出错误。

{
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    }
}

下面的 OVERFLOW! 错误是 DeepSpeed 损失缩放器无法找到缩放系数来克服损失溢出的结果。 在这种情况下,尝试更高的 initial_scale_power 值(通常 32 有效)。

0%|                                                                                                                             | 0/189 [00:00<?, ?it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 262144
  1%|▌                                                                                                                    | 1/189 [00:00<01:26,  2.17it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 262144, reducing to 131072.0
  1%|█▏
 [...]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 14%|████████████████▌                                                                                                   | 27/189 [00:14<01:13,  2.21it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 15%|█████████████████▏                                                                                                  | 28/189 [00:14<01:13,  2.18it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
 15%|█████████████████▊                                                                                                  | 29/189 [00:15<01:13,  2.18it/s]
 [deepscale] OVERFLOW! Rank 0 Skipping step. Attempted loss scale: 1, reducing to 1
[...]

资源

DeepSpeed 是一项用于扩展大型模型训练的强大技术。 要了解有关 DeepSpeed 的更多信息,请查看他们的博客文章文档GitHub

以下论文提供了有关 ZeRO 的更多详细信息。

< > 在 GitHub 上更新