Accelerate

一、基础概念

  1. Accelerate 是一个库,只需添加四行代码,就可以在任何分布式 configuration 中运行相同的 PyTorch 代码:

    上述代码可以通过 AccelerateCLI 接口在任何系统上启动:

  2. 安装:

  3. 配置:

    然后 accelerate 会向你询问一些问题从而生成配置。

    检查配置:

  4. 为了使用 Accelerate,你只需要修改四件事:

    • 首先,导入 Accelerator 并创建一个 accelerator 对象:

    • 然后,移除针对你的模型和输入数据的所有 .to(device).cuda() 的调用。accelerator 将会为你正确处理这个问题,并为你把所有这些对象放在正确的设备上。

      如果你知道你在做什么,你可以保留那些 .to(device) 的调用,但你应该使用 accelerator 对象提供的设备: accelerator.device

      要完全停用自动的 device placement ,在初始化 Accelerator 时传递 device_placement=False

    • 接着,将所有与训练有关的对象(optimizer, model, training dataloader, learning rate scheduler )传递给accelerator.prepare() 方法。这将确保一切都为训练做好准备。

      具体而言,training dataloader 将被分片到所有可用的 GPU/TPU 核心上,这样每个设备都能看到训练数据集的不同部分。此外,所有进程的随机数状态将在每次迭代开始时通过 dataloader 进行同步,以确保数据以相同的方式被混洗(如果你决定使用shuffle=True 或任何类型的 random sampler )。

      训练的实际 batch size 将是使用的设备数量乘以你在脚本中设置的 batch size 。另外,你可以在创建 accelerator 对象时使用 split_batches=True 参半,此时无论你在多少个 GPU 上运行你的脚本,实际 batch size 都会保持不变。

      你需要再开始实际的 training loop 之前执行 accelerator.prepare()

      只有当 scheduler 需要再每个 optimizer step 中被 stepped 时,才需要把 learning rate scheduler 传递给 prepare()

      任何获取 training dataloader length 的方法(例如,你需要记录 total training step)都应该在 accelerator.prepare() 之后进行。

      你可能想、也可能不想把你的validation dataloader 发送到 prepare() ,这取决于你是否想运行分布式评估。

    • 最后,用 accelerator.backward(loss) 替换 loss.backward()

    现在,你的脚本将在你的本地机器上运行,也可以在多个 GPUTPU 上运行。你可以使用你喜欢的工具来启动分布式训练,或者你可以使用 Accelerate launcher 启动。

  5. 分布式评估:

    • 可以进行常规评估,此时你需要将 validation dataloader 保持在 accelerator.prepare() 之外。并且,你需要手动将 input 数据放在 accelerator.device 上。

    • 也可以进行分布式评估,此时你需要将 validation dataloader 放置在 accelerator.prepare() 之内:

      就像 training dataloader,这意味着在分布式评估时,每个设备将仅看到部分 evaluation 数据。这意味着你需要把 predictions 进行 group 。可以通过 accelerator.gather_for_metrics() 方法来实现:

      类似 training dataloader ,把 validation dataloader 传入 prepare() 可能会改变该 dataloader :如果你在 nGPU 上运行,则它的长度将被除以 n (因为你的实际 batch size 将被乘以 n ),除非你设置 split_batches=True

      任何获取 validation dataloader length 的方法都应该在 accelerator.prepare() 之后进行。

      数据集末尾的一些数据可能是重复的,所以这个 batch 的数据可以平均分配给所有的工作者。因此,应该通过gather_for_metrics() 方法计算指标,以便在收集时自动删除重复的数据。如果出于某种原因,你不希望自动完成这项工作,可以用 accelerator.gather() 来收集所有进程的数据,然后手动完成。

      gather()gather_for_metrics() 要求每个进程上的张量是相同尺寸的。如果你在每个进程上有不同尺寸的张量(例如,当动态填充到一个 batch 的最大长度时),你应该使用 accelerator.gather.pad_across_processes() 方法将张量填充到跨进程的最大尺寸。

  6. 启动分布式脚本:你可以使用常规命令来启动你的分布式训练(如 PyTorchtorch.distributed.launch ),它们与 Accelerate 完全兼容。这里唯一需要注意的是: Accelerate 使用 environment 来确定所有有用的信息,所以 torch.distributed.launch 应与标志 --use_env 一起使用。

    Accelerate 还提供了一个 CLI 工具,它统一了所有的 launcher ,所以你只需要记住一个命令:

    你需要回答问题,然后 Accelerate 将在你的 cache folder 创建一个 default_config.yaml 文件。这个缓存目录是(根据优先级递减):

    • 环境变量 HF_HOME 的内容,以 accelerate 为后缀。
    • 如果不存在,则环境变量 XDG_CACHE_HOME 的内容,以 huggingface/accelerate 为后缀。
    • 如果也不存在,则为 ~/.cache/huggingface/accelerate

    你也可以通过标志 --config_file 来指定你要保存的文件的位置。

    然后,你可以通过运行来测试你的设置是否一切顺利:

    这将启动一个简短的脚本,测试分布式环境。你也可以在测试期间指定配置文件的位置:

    如果测试通过,你可以通过如下的命令来执行你的脚本:

    也可以指定配置文件的位置:

  7. notebook 中启动:在 Accelerate 0.3.0 中引入了一个 notebook_launcher() 从而帮助你在 notebook 上启动训练。

    只要在 notebook 的一个 cell 中定义一个负责整个 train and/or evaluation 的函数,然后用以下代码执行一个 cell

    注意:你的 Accelerator 对象应该只在 training_function 中定义,这是因为初始化应该只在 launcher 内完成。

  8. TPU 上训练:如果你想在 TPU 上启动你的脚本,有一些注意事项是你应该注意的。在幕后,TPU 将为你的 training step (前向传播、反向传播、以及 optimizer step )中发生的所有操作创建一个 graph 。这就是为什么你的第一个训练步总是非常长,因为建立和编译这个 graph 需要一些时间。

    好消息是,这个编译将被缓存,所以第二步和所有后续的 step 将更快。坏消息是,这只适用于你的所有 step 做完全相同的操作,这意味着:

    • 所有 batch 必须有用相同的张量尺寸。
    • 必须使用静态的代码(即,如果单个 step 中存在循环,那么循环次数在每个 step 必须相同)。

    如果上述任何一项在两个 step 之间发生变化,都会触发新的编译,这将再次花费大量时间。在实践中,这意味着:你必须特别注意让你的输入中的所有张量具有相同的形状(所以没有动态填充),并且不应该使用具有 for 循环的层,其中 for 循环的根据 input 的不同而具有不同长度(如 LSTM)。否则,训练会慢得令人难受。

    可以针对 TPU 执行一些特殊的代码:

    最后要注意的是:如果你的模型有 tied weight (比如语言模型将 embedding matrix 的权重与 decoder 的权重绑定),将这个模型移动到 TPU (无论是你自己移动、还是由 prepare() 移动)会破坏绑定。你将需要在之后重新绑定权重。

  9. 在单个进程上执行的语句:有些语句只需要在特定的进程上执行而无需在所有进程上执行,如数据下载、记录日志、以及打印进度条。此时可以执行:

    local 意思是每台机器上运行:如果你在两台服务器上训练,其中每台服务器有几个 GPU ,则代码将在每台服务器上执行一次。

    如果你希望对所有进程仅执行一次(如,上传模型到 model hub),则可以执行:

    对于 print 语句,你希望在每台机器上执行一次,则可以用 accelerator.print 代替 print 函数。

  10. 延迟执行:当你运行你的常规脚本时,指令是按顺序执行的。使用 Accelerate 在几个 GPU 上同时部署你的脚本会带来一个复杂的问题:虽然每个进程都是按顺序执行所有指令,但有些可能比其他的快。

    你可能需要等待所有进程达到一定程度后再执行某条指令。例如,在确定每个进程都完成了训练之前,你不应该保存一个模型。要做到这一点,可以执行:

    这条指令将阻塞所有先到的进程,直到所有其他进程都到达该点(如果你只在一个 GPUCPU 上运行你的脚本,这不会有任何作用)。

  11. 保存/加载模型:保存训练好的模型可能需要一些调整:

    • 首先,你应该等待所有的进程到达脚本中的 “延迟执行” 所描述的那个点。

    • 然后,你应该在保存模型之前 unwrap 你的模型。这是因为在通过 prepare() 方法时,你的模型可能被 wrap 从而用于分布式训练。如:

      如果你的脚本包含加载 checkpoint 的逻辑,我们也建议你在 unwrapped model 中加载你的权重(这只在 prepare() 后使用加载函数时有用)。如:

  12. 保存/加载整个状态:当训练你的模型时,你可能想保存模型、优化器、随机数生成器、以及潜在的 LR scheduler 的当前状态,以便在同一个脚本中恢复训练。你可以分别使用 save_state()load_state() 来做到这一点,只需简单地传入一个保存位置。

    如果你通过 register_for_checkpointing() 注册了任何其他需要存储的 stateful item ,它们也会被保存和/或加载。

    示例:

  13. 梯度裁剪:如果你在脚本中使用梯度剪裁,你应该把对 torch.nn.utils.clip_grad_norm_torch.nn.utils.clip_grad_value_ 的调用分别替换为 accelerator.clipgrad_norm()accelerator.clipgrad_value()

  14. 混合精度训练:如果你用 Accelerate 在混合精度下训练,那么模型内的计算将以混合精度进行,而模型外的每一次计算都将以 full precision 执行。例如,loss 的计算通常在模型外,且涉及 softmax 。然而,你可能想把你的 loss 计算放在 accelerator.autocast上下文管理器中:

    混合精度训练的另一个注意事项是:梯度会在开始时跳过一些更新,有时在训练过程中也会跳过。这是因为动态损失缩放 dynamic loss scaling 策略,在训练过程中会有一些时刻,梯度已经溢出,loss scaling factor 会减少,从而避免在下一步再次发生这种情况。

    这意味着你可能会在没有梯度更新的时候就更新你的 learning rate scheduler 。这在一般情况下是没有问题的,但是当你的训练数据非常少,或者你的 scheduler 的第一个学习率值非常重要时,可能会有影响。在这种情况下,你可以跳过 learning rate scheduler 的更新:

  15. 梯度累积:要执行梯度累积,请使用 accumulate() 并指定 gradient_accumulation_steps 。在多设备训练时,这也会自动确保梯度同步或不同步,检查是否真的应该执行该 step ,并自动计算损失:

    相比之下,传统的梯度累加方法会用更冗长的代码:

  16. DeepSpeedDeepSpeed 支持是实验性的,所以底层 API 将在不久的将来发展,可能会有一些轻微的破坏性变化。具体而言, Accelerate 还不支持你自己编写的 DeepSpeed 配置,这将在下一个版本中添加。

  17. 使用 accelerate launch

    指定单个 GPU

    在两个 GPU 上混合精度训练:

    建议总是在 accelerate launch 之前执行 accelerate config ,这样就无需再 accelerate launch 中指定各种配置。

  18. notebooklaunch

    • 确保任何使用 CUDA 的代码在一个函数中,该函数被传递给 notebook_launcher()
    • 设置 num_processes 为训练的设备数量(如,GPU, CPU, TPU 数量)。
    • 如果使用 TPU ,在 training loop 函数之外声明你的模型。

    如:

    对于 TPU

  19. 启用 FSDP

    • 首先进行配置:accelerate configFSDP 配置的一个例子:

      然后开始训练:

    • 这些配置参数的含义为:

      • Sharding Strategy

        • FULL_SHARD:对 optimizer states, gradients, parameters 都进行分片。
        • SHARD_GRAD_OP:仅对 optimizer states, gradients 进行分片。
        • NO_SHARD:不进行分片。
      • Offload Params:一个布尔值,指定是否将 parametersgradients 卸载到 CPU

      • Auto Wrap Policy:可以为 TRANSFORMER_BASED_WRAP, SIZE_BASED_WRAP, NO_WRAP

      • Transformer Layer Class to Wrap:当使用 TRANSFORMER_BASED_WRAP 时,指定特定的 transformer layer class name (大小写敏感)从而执行 wrap 。如 BertLayer, GPTJBlock, T5Block,...

      • Min Num Params:使用 SIZE_BASED_WRAP 的最小参数数量。

      • Backward Prefetch:可以为 BACKWARD_PRE, BACKWARD_POST, NO_PREFETCH

      • State Dict Type:可以为 FULL_STATE_DICT, LOCAL_STATE_DICT, SHARDED_STATE_DICT

    • 有几个需要注意的地方:

      • PyTorch FSDP 会自动 wrap 子模块,对参数进行扁平化处理,并将参数分片。由于这个原因,任何在 model wrapping 之前创建的 optimizer 都会被破坏,并占用更多的内存。因此,强烈建议在创建 optimizer 之前准备好模型,这也是很有效的。Accelerate 将自动 wrap 模型,并在单个模型的情况下为你创建一个优化器,并发出警告信息:

        下面是使用 FSDP 时准备模型和优化器的推荐方法:

      • 在单个模型的情况下,如果你用多个 parameter groups创建了优化器,并且用它们一起调用 prepare ,那么 parameter groups 将被丢失,并显示以下警告:

        这是因为,由于嵌套的 FSDP 模块的参数扁平化为一维数组,在 wrapping 前创建的 parameter groupswrapping 后将没有意义。

      • 在有多个模型的情况下,有必要在创建优化器之前准备好模型,否则会抛出一个错误。然后将优化器以与相应模型相同的顺序传递给 prepare() 方法,否则 accelerator.save_state()accelerator.load_state() 将导致错误/意外的行为。

      • 这个功能与 Transformers libraryrun_translation.py 脚本中的 --predict_with_generate 不兼容。

    • 对于更多的控制,用户可以利用 FullyShardedDataParallelPlugin 。在创建这个类的实例后,用户可以把它传递给 Accelerator 类的实例。

  20. 启用 DeepSpeedDeepSpeed 实现了 ZeRO 论文中描述的一切。目前,它提供了如下的支持:Optimizer state partitioningZeRO stage 1)、Gradient partitioningZeRO stage 2)、Parameter partitioningZeRO stage 3)、Custom mixed precision training handling、一系列基于 CUDA 扩展的快速优化器、ZeRO-OffloadCPUDisk/NVMe

    DeepSpeed ZeRO-2 主要只用于训练,因为它的功能对推理没有用处。DeepSpeed ZeRO-3 也可以用于推理,因为它允许在多个 GPU 上加载巨大的模型。

    • Accelerate 通过两种方式集成 DeepSpeed

      • 通过 deepspeed 配置文件来集成。它支持 DeepSpeed 的所有核心功能,并为用户提供了很大的灵活性。用户可能需要根据配置来改变几行代码。
      • 通过 deepspeed_plugin 来集成。这支持 DeepSpeed 功能的子集,并对其余的配置使用默认选项。用户不需要改变任何代码。
    • 什么被集成了?

      • 训练:DeepSpeed ZeRO 训练支持完整的 ZeRO stages 1, 2 and 3、以及 optimizer states, gradients and parametersCPU/Disk offload

        • Stage 1:将 optimizer states 分片到数据并行 workers/GPUs 上。
        • Stage 2:将 optimizer states + gradients 分片到数据并行 workers/GPUs 上。
        • Stage 3:将 optimizer states + gradients + model parameters 分片到数据并行 workers/GPUs 上。
        • Optimizer Offload:将 optimizer states + gradients 卸载到 CPU/Disk ,建立在 ZERO Stage 2 之上。
        • Param Offload:将 model parameters 卸载到 CPU/Disk ,建立在 ZERO Stage 3 之上。

        注意:关于 Disk Offload ,磁盘应该是 NVME 的,以便有好的速度,但技术上可以在任何磁盘上工作。

      • 推断:DeepSpeed ZeRO Inference 支持 ZeRO Stage 3ZeRO-Infinity 。它使用与训练相同的 ZeRO 协议,但它不使用优化器和 lr scheduler

    • 如何工作:

      • 首先安装 DeepSpeed version >=0.6.5

      • 然后配置:accelerate config 。一个配置的例子:

      • 最后执行训练:accelerate launch examples/nlp_example.py

    • 配置参数的含义:

      • zero_stage0 表示禁用,1 表示 optimizer state partitioning2 表示 optimizer+gradient state partitioning3 表示 optimizer+gradient+parameter partitioning
      • gradient_accumulation_steps:一个整数,表示在 averagingapplying 这些梯度之前,积累梯度的 training steps 数量。
      • gradient_clipping:一个浮点数,指定启用梯度剪裁的值。
      • offload_optimizer_devicenone 表示禁用 optimizer offloadingcpu 表示 offload optimizerCPUnvme 表示offload optimizerNVMe SSD 。仅适用于 ZeRO >= Stage-2
      • offload_param_devicenone 表示禁用 parameter offloadingcpu 表示 offload parameterCPUnvme 表示offload parameterNVMe SSD 。仅适用于 ZeRO Stage-3
      • zero3_init_flag:决定是否启用 deepspeed.zero.Init 来构建大规模模型。只适用于 ZeRO Stage-3
      • zero3_save_16bit_model:决定是否在使用 ZeRO Stage-3 时保存 16 位模型权重。
      • mixed_precisionno 用于 FP32 训练,fp16 用于 FP16 混合精度训练,bf16用于 BF16 混合精度训练。
    • 当使用配置文件时,需要修改一些代码:

      • DeepSpeed Optimizers and Schedulers

        • 如果是 DeepSpeed Optim + DeepSpeed Scheduler :用户必须使用 enhance.utils.DummyOptimenhance.utils.DummyScheduler 来取代他们代码中的 PyTorch/Custom 优化器和调度器:

        • Custom Optim + Custom Scheduler:当 DeepSpeed 配置文件中没有 optimizer keyscheduler key 的情况。在这种情况下,不需要用户修改代码,通过 DeepSpeed Plugin 使用集成时就是这种情况。

        • Custom Optim + DeepSpeed Scheduler :这种情况下,用户必须使用accelerate.utils.DummyScheduler 来替换代码中的 PyTorch/Custom scheduler

        • DeepSpeed Optim + Custom Scheduler:这将导致一个错误,因为当使用 DeepSpeed Optim 时必须使用 DeepSpeed Scheduler

      • DeepSpeed 配置文件中存在一些 "auto" 值,这些值是由 prepare 方法根据所提供的模型、dataloadersdummy optimizerdummy schedulers 自动处理的。那些不是 "auto" 的字段必须由用户明确指定。如 zero_stage2_config.json 文件:

    • 保存和加载:

      • 对于 ZeRO Stage-1ZeRO Stage-2,模型的保存和加载不需要改动。

      • 对于 ZeRO Stage-3state_dict 仅只包含占位符,因为模型的权重被分片到多个 GPUZeRO Stage-3 有两个选项:

        • 保存整个 16 位的模型权重,然后使用 model.load_state_dict(torch.load(pytorch_model.bin)) 来直接加载。为此,要么在 DeepSpeed 配置文件中把 zero_optimization.stage3_gather_16bit_weights_on_model_save 设为True ,要么在 DeepSpeed Plugin 中把 zero3_save_16bit_model 设为 True

          请注意,这个选项需要在一个 GPU 上整合权重,这可能会很慢,而且对内存要求很高,所以只有在需要时才使用这个功能。

          示例:

        • 为了获得 32 位的权重,首先使用 model.save_checkpoint() 保存模型:

          这将在 checkpoint 目录下创建 ZeRO modeloptimizerpartitions 以及 zero_to_fp32.py 脚本。你可以使用这个脚本来做离线整合,这不需要配置文件或 GPU 。如:

          要想加载 32 位的模型,做法如下:

          如果你仅仅想得到 state_dict,做法如下:

          注意,加载时需要大约 2 倍于 final checkpoint 大小的内存。

    • ZeRO InferenceDeepSpeed ZeRO Inference 支持 ZeRO stage 3 。通过 accelerate 的集成,你只需要 prepare 模型和 dataloader ,如下:

    • 注意事项:

      • 目前的集成不支持 DeepSpeedPipeline Parallelism
      • 当前的集成不支持 mpu ,限制了 Megatron-LM 中支持的张量并行。
      • 目前的集成不支持多个模型。
  21. 目前 Accelerate 支持如下的 trackerTensorBoard, WandB, CometML, MLFlow ,如:

    然后需要初始化 tracker

    然后记录日志:

    最后在训练结束时调用:accelerator.end_training()

    你也可以通过 accelerator.get_tracker 来获取内置的 tracker 对象:

  22. 处理大模型:常规的加载预训练模型的方式:

    这对于常规大小的模型而言很有效,但是无法处理大型模型:在 step 1 我们在 RAM 中加载一个完整版本的模型,并花一些时间随机初始化权重(这将在 step 3 被丢弃);在 step 2 ,我们在 RAM 中加载另一个完整版本的模型,并使用预训练的权重。

    Accelerate 提供一些工具来帮助处理大模型(这些 API 是实验性质的,未来可能会发生改变):

    • init_empty_weights 上下文管理器:初始化一个模型而无需使用任何内存。这依赖于 PyTorch 1.9 中引入的 meta device

      在该上下文管理器中,每当有一个 parameter 被创建时,它就被立即移动到 meta device

    • sharded checkpoints:有可能你的模型太大从而无法装入内存,这并不意味着它不能被加载:如果你有一个或几个 GPU ,这就有更多的内存可用于存储你的模型。此时需要你的 checkpoint 被拆分为几个小文件,即 checkpoint shards

      Accelerate 将处理 checkpoint shards ,但是要满足如下格式:你的 checkpoint shards 应该放在一个文件夹中,并且有几个包含部分 state dict 的文件、以及一个 index.json 文件(将 parameter name 映射到包含该 parameter weights 的文件)。如:

      其中 index.json 内容为:

    • load_checkpoint_and_dispatch:在 empty model 中加载一个 checkpoint 。它支持 full checkpoints (包含整个 state dict 的单一文件)以及 sharded checkpoints 。它还会在你可用的设备( GPUCPU )上自动分配这些权重,所以如果你正在加载一个 sharded checkpoints ,最大的RAM 用量将是最大分片的大小。

      例如:

      初始化模型:

      加载权重:

      通过 device_map="auto"Accelerate 根据可用资源自动决定将模型的每一层放在哪里:

      • 首先,我们使用 GPU 上的最大可用空间。
      • 如果我们仍然需要空间,我们将剩余的权重存储在 CPU 上。
      • 如果没有足够的 RAM ,我们将剩余的权重作为内存映射的张量存储在硬盘上。

      no_split_module_classes=["GPTJBlock"] 表示属于 GPTJBlock 的模块不应该在不同的设备上分割。你应该在这里设置所有包括某种残差连接的 block

      可以通过 model.hf_device_map 查看模型的权重的设备。

  23. 分布式训练的复现:

    • 设置随机数种子:

      它在内部设置了五种随机数种子:

    • 设置 batch size:当使用 Accelerate 训练时,传递给 dataloaderbatch sizebatch size/GPU ,因此 final batch sizebatch size * device num

    • 设置学习率:学习率应该和 device num 成正比,如:

  24. 梯度同步:在 DDP 中,PyTorch 在一些特定的点上进行进程间通信。然而在梯度累积时,你会累积 nloss 并跳过 .backward() 。这可能会导致明显的减速,因为所有的进程都需要与它们进行更多次的通信。

    可以通过 no_sync 上下文管理器来避免:

    或者直接使用 accelerator.accumulate

  25. 进程间同步:

    这将阻塞所有进程直到所有进程都达到该点。

    用途:

    • 加载数据集:

      这等价于:

    • 存取 state_dict

    • global main 进程上 tokenizing,然后传播到每个 worker

 

二、API

2.1 Accelerator

  1. Accelerator 最佳实践:

    • print 语句应该由accelerator.print() 代替,每个进程打印一次。

    • 每个 server 执行一次的语句,应该使用 accelerator.is_local_main_process

      或者使用 accelerator.on_local_main_process() 装饰器:

    • 所有 server 中仅执行一次的语句,应该使用 accelerator.is_main_process

      或者使用 accelerator.on_main_process() 装饰器:

    • 在指定的进程(局部编号或全局编号)上执行的语句,也可以使用如下的装饰器:

    • 同步控制:使用 accelerator.wait_for_everyone() 来确保所有进程在继续之前,先到达该点。例如,在模型保存之前很有用。

    • 保存和加载:使用 accelerator.unwrap_model() 来删除所有在分布式过程中添加的特殊的 model wrapper

      使用 accelerator.save() 而不是 torch.save()

    • 使用 accelerator.clipgrad_norm() 而不是 torch.nn.utils.clip_grad_norm_() ;使用 accelerator.clipgrad_value() 而不是torch.nn.utils.clip_grad_value()

    • 梯度累积:要执行梯度累积,请使用 accelerator.accumulate() 并指定 gradient_accumulation_steps 。即使在多设备训练时,它也会自动处理。

  2. class accelerate.AcceleratorAccelerator 类,用于分布式训练或混合精度训练。

    参数:

    • device_placement:一个布尔值,默认为 True,指定 accelerator 是否应该将对象放在 device 上(由 dataloader, model 等等产生的张量)。

    • split_batches:一个布尔值,默认为 False,指定 accelerator 是否应该将 dataloaders 产生的 batches 在设备上进行分割。

      • 如果是 True ,实际使用的 batch size 在任何类型的分布式进程中都是一样的,但它必须是你使用的 num_processes (即,进程数量)的整数倍。
      • 如果是 False ,实际使用的 batch size 将是你脚本中设置的 batch size 乘以进程数。
    • mixed_precision:一个字符串,指定是否使用混合精度训练(fp16bfloat16)。可以为 'no', 'fp16', 'bf16' 。默认为环境变量 ACCELERATE_MIXED_PRECISION 中的值,或者通过 accelerate.launch 传入的选项。

      'fp16' 要求 pytorch 1.6 及其以上版本,'bf16' 要求 pytorch 1.10 及其以上版本。

    • gradient_accumulation_steps:一个整数,指定在累积梯度之前应该经过多少个 step。默认为 1 ,表示没有梯度累积。一个大于 1 的数字应该与 Accelerator.accumulate 相结合。

    • cpu:一个布尔值,指定是否强制脚本在 CPU 上执行。如果设置为 True ,将忽略 GPU 的可用性,并且仅强制在一个进程上执行。默认为 False

    • deepspeed_plugin:一个 DeepSpeedPlugin ,用于调整 DeepSpeed 的相关的参数。也可以通过 accelerate config 来直接调整 DeepSpeed

    • fsdp_plugin:一个 FullyShardedDataParallelPlugin ,用于调整 FSDP 的相关的参数。也可以通过 accelerate config 来直接调整 FSDP

    • megatron_lm_plugin:一个 MegatronLMPlugin ,用于调整 FSDPMegatronLM 的相关的参数。也可以通过 accelerate config 来直接调整 MegatronLM

    • rng_types:一个关于字符串或 RNGType 的列表,它指定了一个关于随机数生成器的列表,用于在 dataloaders 的每个 iteration 开始时进行同步。应该是如下的一个或几个:

      • "torch":基本的 torch 的随机数生成器。
      • "cuda"CUDA 随机数生成器(仅限于 GPU)。
      • "xla"XLA随机数生成器(仅咸鱼 TPU )。
      • "generator"sampler (或 batch sampler)的 torch.Generator 、或 iterable datasettorch.Generator

      如果 PyTorch 版本 <=1.5.1 ,将默认为 ["torch"] ;如果 PyTorch 版本 >=1.6 ,则默认为 ["generator"]

    • log_with:一个关于字符串、LoggerTypeGeneralTracker 的列表,指定 loggers 。可以为如下的一个或几个:"all", "tensorboard", "wandb", "comet_ml"

      如果选择了 "all" ,就会接收环境中所有可用的 trackers 并初始化它们。也可以接受用于自定义 trackerGeneralTracker 的实现,并且可以与 "all" 结合使用。

    • logging_dir:一个字符串或 os.PathLike,指定用于日志的目录的路径。

    • dispatch_batches:一个布尔值,如果为 "True"Accelerator 准备的 dataloader 只在 global main 进程上进行迭代,然后将 batch 分割并广播给每个 worker 进程。对于底层数据集是 IterableDatasetDataLoader ,默认为 True ,否则为False

    • even_batches:一个布尔值,如果设置为 True ,在所有进程的 total batch size 不能完全分割数据集的情况下,数据集开头的样本将被重复,这样 batch 就可以在所有 worker 之间平均分配。默认为 True

    • step_scheduler_with_optimizer:一个布尔值,如果学习率 scheduler 与优化器同时 step ,则设置为 True ;否则设置为 False。默认为 True

    • kwargs_handlers:一个关于 KwargHandler 的列表,用于自定义如何创建与分布式训练或混合精度相关的对象。

    • dynamo_backend:一个字符串或 DynamoBackend,设置一个 dynamo 后端从而利用 Torch dynamo 优化你的训练。默认为 'no'

    属性:

    • device:一个 Torch.device 对象,表示要使用的设备。
    • distributed_type:一个 DistributedType 对象,表示分布式训练配置。
    • local_process_index:一个整数,表示当前机器上的进程编号。
    • mixed_precision:一个字符串,表示配置好的混合精度模式。
    • num_processes :一个整数,表示用于训练的进程总数。
    • optimizer_step_was_skipped:一个布尔值,表示当学习率不应该被改变的情况下,优化器的更新是否被跳过(因为混合精度中的梯度溢出)。
    • process_index:一个整数,表示当前进程在所有进程中的总编号。
    • state:一个 AcceleratorState,表示分布式的 setup state
    • sync_gradients:一个布尔值,表示目前梯度是否在所有进程中被同步。
    • use_distributed:一个布尔值,表示当前配置是否用于分布式训练。

    方法:

    • accumulate(model):一个上下文管理器,它 wrap 模型并自动进行梯度累积。

      参数:model:一个 torch.nn.Module 对象,它是被 Accelerator.prepare 准备好之后的模型。

    • autocast():如果启用的话,将在这个上下文管理器中的代码块内应用自动混合精度。否则不会发生任何变化。

    • backward(loss, **kwargs):根据 Accelerator.gradient_accumulation_steps 对梯度进行调整,并根据配置来调用正确的backward() 。应该用来代替 loss.backward()

    • clear():是 Accelerate.free_memory 的别名,释放所有内部对象的引用并调用垃圾收集器。你应该在两个不同 models/optimizers 训练之间调用这个方法。

    • clip_grad_norm_(parameters, max_norm, norm_type = 2 ) -> torch.Tensor:参数梯度的总范数(将所有参数视为单个向量来看待)的范数截断。应该用来代替 torch.nn.utils.clip_grad_norm_

      参数:

      • parameters:待截断梯度的参数列表。
      • max_norm:梯度阈值。
      • norm_type:范数类型。
    • clip_grad_value_(parameters, clip_value ) -> torch.Tensor:参数梯度的数值截断(绝对值)。应该用来代替 torch.nn.utils.clip_grad_value_

      参数:

      • parameters :待截断取值的参数列表。
      • clip_value:参数阈值(绝对值)。
    • end_training():运行任何特殊的 end training behavior ,比如只在 global main 进程上停止 tracker 。如果使用实验跟踪,应始终在脚本的最后调用 end_training()

    • free_memory():参考 clear()

    • gather(tensor) -> torch.Tensor, or a nested tuple/list/dictionary of torch.Tensor :跨所有进程收集 tensor 的取值,并在第一个维度上将其拼接起来。在进行评估时,对所有进程的预测进行 regroup 是很有用的。

      注意:这种收集发生在所有进程中。

      参数:tensor:一个张量或张量的集合,表示需要跨所有进程来收集取值的张量。

      返回:返回收集后的结果,类型与 tensor 相同。

    • gather_for_metrics(tensor):与 gather() 作用相同,但是 gather_for_metrics 可能会丢弃 last batch 中重复的数组。它经常被用于收集 inputstargets 来计算指标。

      参数和返回值:参考 gather()

    • get_state_dict( model, unwrap = True ):以 full precision 来返回一个模型的 state_dict ,这个模型是被 accelerator.prepare() 处理过的。

      参数:

      • model:一个 PyTorch 模型,它被 accelerator.prepare() 处理过。
      • unwrap:一个布尔值,指定是否返回原始的 state_dict 。如果为 False,则返回 wrapped state_dict 。默认为 True
    • get_tracker(name: str):基于 nameself.trackers 中返回一个 tracker,仅在 global main 进程上有效。

      参数:name:一个字符串,指定 tracker 的名字。

    • init_trackers(project_name: str, config: Optional[dict] = None, init_kwargs: Optional[dict] = {}) :为存储在 self.log_with 中的所有 trackers 执行初始化。

      参数:

      • project_name:一个字符串,指定 project 的名字。
      • config:一个字典,指定 starting configuration
      • init_kwargs:一个字典,它将被传递给 tracker 的初始化方法。
    • join_uneven_inputs(joinables, even_batches = None ):一个上下文管理器,用于在 uneven 的输入上进行分布式训练或分布式评估。它作为 torch.distributed.algorithms.joinwrapper ,当 total batch size 无法整除 dataset length 时很有用。

      仅支持多 GPU 上的 Distributed Data Parallel training。对于其它配置,则没有效果。

      参数:

      • joinables:关于 torch.distributed.algorithms.Joinable 的列表,它为 torch.distributed.algorithms.Joinable 所子类化的模型或优化器,如 Accelerator.prepare 所准备的 PyTorch Module

      • even_batches:一个布尔值,它覆盖 Accelerator 中设置的 even_batches 的值。如果未提供,则默认使用 Accelerator 中的 even_batches 的值。

        对于 iterable-styledataloader,该参数不生效。

      示例:

    • load_state(input_dir: str):加载 model, optimizer, scaler, RNG generators, registered objects 的当前状态。必须与 accelerator.save_state() 配合工作。

      参数:input_dir :一个字符串或 os.PathLike 对象,指定存放 state 的目录。

    • local_main_process_first():让 local main 进程先进入一个 with block ,其它进程将在 local main 进程退出后进入 with block

    • log(values: dict, step: Optional[int] = None, log_kwargs: Optional[dict] = {}):记录 valuesself.trackers 中的所有 trackers,仅在 global main 进程上生效。

      参数:

      • values:一个字典,仅包含 int/float/str 数据类型,表示待记录的值。
      • step:一个整数,指定 run step
      • log_kwargs:一个字典,它将被传递给 trackerlog 函数。
    • main_process_first():让 global main 进程先进入一个 with block ,其它进程将在global main 进程退出后进入 with block

    • no_sync(model):一个上下文管理器,它通过调用 torch.nn.parallel.DistributedDataParallel.no_sync 来禁用跨DDP 进程的梯度同步。如果模型不在 DDP 中,这个上下文管理器不做任何事情。

      参数:model:一个 torch.nn.Module 对象,它被 accelerator.prepare() 处理过。

      示例:

    • on_last_process(func):一个装饰器,将仅仅在最后一个进程上运行被装饰的函数。

    • on_local_main_process(func):一个装饰器,将仅仅在 local main 进程上运行被装饰的函数。

    • on_local_process(local_process_idx):一个装饰器,将仅仅在 local process index 进程上运行被装饰的函数。

    • on_main_process(func):一个装饰器,将仅仅在 global main 进程上运行被装饰的函数。

    • on_process(process_idx):一个装饰器,将仅仅在 global process index 进程上运行被装饰的函数。

    • pad_across_processes(tensor, dim = 0, pad_index = 0, pad_first = False ):递归地将所有设备的张量(位于嵌套的 list/tuple/dict 中)填充到相同的 size,以便它们可以安全地被收集起来。

      参数:

      • tensortorch.Tensorlist/tuple/dict ,指定被收集的数据。
      • dim:一个整数,指定填充哪一维。默认为 0
      • pad_index:一个整数,指定用什么值来填充。
      • pad_first:一个布尔值,指定是否从开始填充。默认为 False,表示从尾部填充。
    • prepare(*args, device_placement = None ):为分布式训练和混合精度准备 args 中传递的所有对象,然后以相同的顺序返回。

      如果你使用一个 model 来用于推断,并且没有任何形式的混合精度,那么你不需要 preparemodel

      参数:

      • args:一个列表,可以包含如下类型的对象:torch.utils.data.DataLoadertorch.nn.Moduletorch.optim.Optimizertorch.optim.lr_scheduler.LRScheduler
      • device_placement:一个关于布尔值的列表,要求长度与 args 相同,分别指定每个被 prepare 的对象是否 automatic device placement
    • prepare_data_loader(data_loader: DataLoaderde, dvice_placement = None ):准备一个 PyTorch DataLoader 用于分布式训练。推荐使用 prepare() 函数。

      参数:参考 prepare() 函数。

    • prepare_model(model: Module, dvice_placement = None ):准备一个 PyTorch model 用于分布式训练。推荐使用 prepare() 函数。

      参数:参考 prepare() 函数。

    • prepare_optimizer(optimizer: Optimizer, dvice_placement = None ):准备一个 PyTorch Optimizer 用于分布式训练。推荐使用 prepare() 函数。

      参数:参考 prepare() 函数。

    • prepare_scheduler(scheduler: _LRScheduler, dvice_placement = None ):准备一个 PyTorch Scheduler 用于分布式训练。推荐使用 prepare() 函数。

      参数:参考 prepare() 函数。

    • print(*args, **kwargs ):用于替代 python 内置的 print() 函数从而仅在每个 server 上打印一次。

    • reduce(tensor, reduction = 'sum' ) -> torch.Tensor, or a nested tuple/list/dictionary of torch.Tensor:跨所有进程来 reduce 指定的张量。注意,所有的进程都将得到被 reduce 之后的值。

      参数:

      • tensor:一个 TensorTensor 的集合,指定要被 reduce 的张量。
      • reduction:一个字符串,指定 reduce 方式,可以为 'sum', 'mean', 'none' 。如果为 'none',则不做任何操作。默认为 'sum'

      返回:与 tensor 类型相同,表示被 reduce 之后的值。

    • register_for_checkpointing(*objects):注册对象,从而在 save_state/load_state 将该对象保存或加载。

      注意,该方法应该在同一脚本中加载或保存 state 时利用。它不是被设计用来在不同的脚本中使用的。

      参数:objects:被注册的对象,每个对象必须有一个 load_state_dict 方法和一个 state_dict 方法。

    • save(obj, f):在每台机器上保存 obj 一次,用于替代 torch.save

      参数:

      • obj:被保存的对象。
      • f:一个字符串或 os.PathLike 对象,指定存储路径。
    • save_state(output_dir: str):保存 model, optimizer, scaler, RNG generator, registered object 等对象的当前状态。

      参数:output_dir:一个字符串或 os.PathLike 对象,指定存储路径。

    • unscale_gradients(optimizer = None ):在使用 AMP 的混合精度训练中 unscale 梯度。在所有其他 setting 中,该方法不做任何事情。

      参数:optimizer:一个 Optimizer 或一组 Optimizer,指定哪些 optimizer 需要 unscale 梯度。如果未设置,则默认为传递给 prepare() 方法的所有 optimizers

    • unwrap_model(model, keep_fp32_wrapper: bool = False )unwrap model,其中 model 是经过 prepare() 处理过的。该方法常用于保存 model

      参数:

      • model:一个 torch.nn.Module,指定需要被 unwrap 的模型。
      • keep_fp32_wrapper:一个布尔值,指定是否需要移除 mixed precision hook(如果有的话)。默认为 False
    • wait_for_everyone():将停止当前进程的执行,直到其他所有进程都达到该点(因此,当脚本只在一个进程中运行时,这没有任何作用)。在保存模型前执行该方法很有用。

  3. class accelerate.state.AcceleratorState:单例类,它存储当前训练环境的信息。该类是不可变的,在第一次初始化之后就保存不变。

    参数参考 Accelerator

    属性:

    • device:一个 torch.device,表示要使用的设备。
    • distributed_type:一个 DistributedType,表示当前使用的分布式环境的类型。
    • initialized:一个布尔值,表示 AcceleratorState 是否已经从 Accelerator 得到初始化。
    • local_process_index:一个整数,表示当前进程在当前 server 上的索引。
    • mixed_precision:一个字符串,表示当前脚本是否会使用混合精度,如果是的话,正在执行的混合精度的类型。
    • num_processes:一个整数,表示当前并行启动的进程的数量。
    • process_index :一个整数,表示当前进程的 global index
  4. class accelerate.state.GradientState():单例类,它存储梯度同步相关的信息从而用于梯度累积。该类是不可变的,在第一次初始化之后就保存不变。

    属性:

    • end_of_dataloader:一个布尔值,表示我们是否已经到达了当前 dataloader 的结束。
    • remainder:一个整数,表示填充 dataloader 所需要增加的额外样本的数量。
    • sync_gradients:一个布尔值,表示梯度是否应该在所有设备上同步。

2.2 命令行

  1. accelerate config 命令:启动一系列提示,为你的训练系统创建并保存 default_config.yml 配置文件。该命令应该总是最先执行。

    命令参数:

    • --config_file CONFIG_FILE (str):配置文件的存储路径。默认为 default_config.yaml 文件名,存放在 cache location
    • -h, --help (bool):展示帮助信息。
  2. accelerate config default 命令:启动一系列提示,为你的训练系统创建并保存 default_config.yml 配置文件,但是会在命令行中配置一些参数,如 --mixed_precision 等等。

    用法参考 accelerate config

  3. accelerate config update:命令:用一组新的参数更新已有的配置文件中的对应项。

    用法参考 accelerate config

  4. accelerate env:列出配置文件的内容。

    用法参考 accelerate config

  5. accelerate launchlaunch 一个脚本。

    位置参数:

    • {training_script}:脚本的完整路径。
    • --{training_script-argument-1}:脚本的参数。

    可选参数:

    • -h, --help (bool):展示帮助信息。
    • --config_file CONFIG_FILE (str):替换默认的配置文件。
    • -m, --module (bool):将 launch script 解释为一个 Python 模块,即通过 python -m 执行。
    • --no_python (bool):跳过在脚本前加上 "python" ,直接执行它。当脚本不是 Python 脚本时很有用。
    • --debug (bool):当发生故障时,是否打印出 torch.distributed stack trace
    • -q, --quiet (bool):将子进程的错误信息从 launch stack trace 切换到仅展示相关的信息。仅用于 DeepSpeed 和单进程。

    下面的参数可以通过 accelerate config 来配置。也可以在 launch 时配置(或更新):

    • 硬件选择参数:

      • --cpu (bool):是否强制在 CPU 上进行训练。
      • --multi_gpu (bool):是否应该启动分布式 GPU 训练。
      • --mps (bool):否应该在 MacOS 机器上使用支持 MPSGPU 设备。
      • --tpu (bool) :是否应该启动 TPU 训练。
    • 资源选择参数:

      • --mixed_precision {no,fp16,bf16} (str):是否使用混合精度训练。 BF16 训练仅在 Nvidia Ampere GPUPyTorch 1.10 或更高版本上支持。
      • --num_processes NUM_PROCESSES (int):要并行启动的进程总数。
      • --num_machines NUM_MACHINES (int):本次训练中使用的机器总数。
      • --num_cpu_threads_per_process NUM_CPU_THREADS_PER_PROCESS (int):每个进程的 CPU 线程数。可以进行调优以获得最佳性能。
    • 训练方式选择参数:

      • --use_deepspeed (bool):是否使用 DeepSpeed 进行训练。
      • --use_fsdp (bool):是否使用 FullyShardedDataParallel 进行训练。
      • --use_megatron_lm (bool):是否使用 Megatron-LM 进行训练。
    • 分布式 GPU 参数:以下参数只有在传递了 multi_gpu 或者通过 accelerate config 配置了 multi-gpu training 时才有用。

      • --gpu_ids (str):在这台机器上应该使用哪些 GPU (通过 id 指定)进行训练,以逗号分隔的方式列出。
      • --same_network (bool):用于多节点训练的所有机器是否存在于同一个 local network
      • --machine_rank MACHINE_RANK (int):启动这个脚本的机器的 rank (即,编号)。
      • --main_process_ip MAIN_PROCESS_IP (str)rank 0 的机器的 IP 地址。
      • --main_process_port MAIN_PROCESS_PORT (int):与 rank 0 的机器通信的端口。
      • --rdzv_conf (str):额外的 rendezvous 配置(<key1>=<value1>,<key2>=<value2>,…) 。
      • --max_restarts (int)worker group 最多重启多少次(之后不再重启而是失败)。
      • --monitor_interval (float):监控 worker 状态的时间间隔,单位是秒。
    • TPU 参数:以下参数只有在传递了 tpu 或者通过 accelerate config 配置了 tpu training 时才有用。

      • --main_training_function MAIN_TRAINING_FUNCTION (str):脚本中要执行的主函数的名称。
      • --downcast_bf16 (bool):当在 TPU 上使用 bf16 精度时,是否 floatdouble 张量都被类型转换到 bfloat16 ,还是 double 张量仍为 float32
    • DeepSpeed 参数:以下参数只有在传递了 use_deepspeed 或者通过 accelerate config 配置了 deepspeed 时才有用。

      • --deepspeed_config_file (str)DeepSpeed 配置文件。
      • --zero_stage (int)DeepSpeedZeRO 优化阶段。
      • --offload_optimizer_device (str):决定在哪里(none|cpu|nvme)卸载优化器状态。
      • --offload_param_device (str):决定在哪里(none|cpu|nvme)卸载 parameters
      • --gradient_accumulation_steps (int):训练脚本中使用的gradient_accumulation_steps 的数量。
      • --gradient_clipping (float):训练脚本中使用的梯度剪裁值。
      • --zero3_init_flag (str):决定是否( true|false )启用 deepspeed.zero.Init来构建大规模模型。只适用于DeepSpeed ZeRO Stage-3
      • --zero3_save_16bit_model (str):决定在使用 ZeRO Stage-3 时是否(true|false)保存 16 位模型权重。只适用于DeepSpeed ZeRO Stage-3
      • --deepspeed_hostfile (str):用于配置多节点计算资源的DeepSpeed hostfile
      • --deepspeed_exclusion_filter (str):当使用多节点配置时,DeepSpeed exclusion filter 字符串。
      • --deepspeed_inclusion_filter (str):当使用多节点配置时,DeepSpeed inclusionfilter 字符串。
      • --deepspeed_multinode_launcher (str):要使用的 DeepSpeed 多节点 launcher
    • Fully Sharded Data Parallelism 参数:以下参数只有在传递了 use_fdsp 或者通过 accelerate config 配置了 Fully Sharded Data Parallelism 时才有用。

      • --fsdp_offload_params (str): 决定是否( true|false )将 parameters 和梯度卸载到 CPU
      • --fsdp_min_num_params (int)FSDP 默认的 Default Auto Wrappingparameters 的最少数量。
      • --fsdp_sharding_strategy (int)FSDP 的分片策略。
      • --fsdp_auto_wrap_policy (str)FSDPauto wrap policy
      • --fsdp_transformer_layer_cls_to_wrap (str):要 wrapTransformer layer class name (区分大小写),例如:BertLayer, GPTJBlock, T5Block ...
      • --fsdp_backward_prefetch_policy (str)FSDPbackward prefetch policy
      • --fsdp_state_dict_type (str)FSDPstate dict 类型。
    • Megatron-LM 参数:以下参数只有在传递了 use_megatron_lm 或者通过 accelerate config 配置了 Megatron-LM 时才有用。

      • --megatron_lm_tp_degree ('')Megatron-LM 的张量并行(Tensor Parallelism: TP )度。
      • --megatron_lm_pp_degree ('')Megatron-LM 的管道平行(Pipeline Parallelism: PP )度。
      • --megatron_lm_num_micro_batches (''):当管道并行度大于 1 时,Megatron-LMmicro batch 数量。
      • --megatron_lm_sequence_parallelism (''):当张量并行度大于 1 时,决定是否(true|false )启用序列并行 Sequence Parallelism
      • --megatron_lm_recompute_activations (''):决定是否(true|false )启用 Selective Activation Recomputation
      • --megatron_lm_use_distributed_optimizer ('') :决定是否(true|false )使用分布式优化器,将优化器状态和梯度分片到 Data Pralellel: DPranks
      • --megatron_lm_gradient_clipping ('')Megatron-LM 基于全局 L2 范数的梯度裁剪值( 0 表示禁用)。
    • AWS SageMaker 参数:以下参数仅当在 SageMake 中训练时才有用。

      • --aws_access_key_id AWS_ACCESS_KEY_ID (str):用于启动 Amazon SageMaker 训练工作的 AWS_ACCESS_KEY_ID
      • --aws_secret_access_key AWS_SECRET_ACCESS_KEY (str):用于启动 Amazon SageMaker 训练工作的AWS_SECRET_ACCESS_KEY
  6. accelerate tpu-config:配置 tpu 训练。

    可选参数:

    • -h, --help (bool):展示帮助信息。

    配置参数:下面参数也可以通过 accelerate config 来配置:

    • --config_file (str)accelerate 配置文件的路径。
    • --tpu_name (str):要使用的 TPU 的名称。如果没有指定,将使用配置文件中指定的 TPU
    • --tpu_zone (str):要使用的 TPUzone。如果没有指定,将使用配置文件中指定的 zone

    TPU 参数:下面的参数用于配置 TPU

    • --command_file (str):一个文件的路径,该文件包含启动时在 pod 上运行的命令。
    • --command (str):要在 pod 上运行的命令。可以传递多次。
    • --install_accelerate (bool):是否在 pod 上安装 accelerate 。默认为 False
    • --accelerate_version (str):在 pod 上安装 accelerate 的版本。如果不指定,将使用最新的 pypi 版本。指定 'dev' 可以从 GitHub 安装。
    • --debug (bool):如果设置,将打印将运行的命令,而不是运行它。
  7. accelerate test:执行 accelerate/test_utils/test_script.py 从而确保 Accelerate 被正确地配置。

    可选参数:

    • --config_file CONFIG_FILE (str):配置文件的存储路径。默认为 default_config.yaml 文件名,存放在 cache location
    • -h, --help (bool):展示帮助信息。

2.3 Tracker

  1. class accelerate.tracking.GeneralTracker():所有 Tracker 的基类。

    方法(每个方法都应该接受 **kwargs 参数):

    • finish():应该运行位于 tracking API 中的任何 finalizing function 。如果API 中没有这类 finalizing function ,则不要重写 finish() 方法。

    • log(values: dict, step: typing.Optional[int], **kwargs ):记录当前 run 的日志。

      参数:

      • values:一个字典,指定 key-value 的要被记录的内容。注意,key 为字符串,而value 必须是字符串、浮点数、或整数类型。
      • step:一个整数,指定当前的 run step
    • store_init_configuration(values: dict ):将 values 记录为超参数。

      参数:参考 log()

  2. class accelerate.tracking.TensorBoardTrackerTensorboard Tracker 。应该在你的脚本开始的地方就被初始化。

    参数:

    • run_name:一个字符串,指定当前 experiment run 的名字。
    • logging_dir:一个字符串或 os.PathLike,指定 TensorBoard logs 存储的位置。
    • kwargs:关键字参数,传递给 tensorboard.SummaryWriter.__init__ 方法。
  3. class accelerate.tracking.WandBTracker(run_name: str, **kwargs )WandB Tracker。应该在你的脚本开始的地方就被初始化。

    参数:

    • run_name:一个字符串,指定当前 experiment run 的名字。
    • kwargs:关键字参数,传递给 wandb.init 方法。
  4. class accelerate.tracking.CometMLTracker(run_name: str, **kwargs )comet_ml Tracker 。应该在你的脚本开始的地方就被初始化。API key 必须存储在 Comet 配置文件中。

    参数:

    • run_name:一个字符串,指定当前 experiment run 的名字。
    • kwargs:关键字参数,传递给 Experiment.__init__ 方法。

2.4 分布式 Lancher

  1. accelerate.notebook_launcher( function, args = (), num_processes = None, mixed_precision = 'no', use_port = '29500'):启动一个训练函数。如果当前环境中允许的话(如,具有多核的 TPU ),使用几个进程。

    要使用这个 notebook_launcher ,在调用之前,notebook session 中必须对 CUDA 设备没有任何调用。如果有任何调用,你将需要重启 notebook ,并确保没有 cell 使用任何 CUDA 设备。

    参数:

    • function:一个可调用对象,指定要执行的训练函数。如果它接受参数,第一个参数应该是运行进程的 index
    • args:一个元组,指定传递给函数的参数的元组(函数将接收到 *args)。
    • num_processes:一个整数,指定训练时使用的进程的数量。如果有 TPU,则在 Colab/Kaggle 中默认为 8,否则为可用的GPU 数量。
    • mixed_precision:一个字符串,指定混合精度训练。默认为 'no'
    • use_port:一个字符串,指定启动多 GPU 训练时用于进程间通信的端口。默认为 '29500'

    示例:

  2. accelerate.debug_launcher(function, args = (), num_processes = 2):在 CPU 上使用几个进程启动一个训练函数从而用于调试。

    debug_launcher 仅用于调试,不应该用于真实的训练。它将仅使用 CPU

    参数:参考 notebook_launcher

2.5 Logging

  1. accelerate 有自己的 logging 工具从而用于分布式系统。使用方法为:用 accelerate.logging 代替 Python logging 。如:

  2. accelerate.logging.get_logger(name: str, log_level: str = None ):返回一个 logging.Logger ,它可以用于多进程环境。

    参数:

    • name:一个字符串,指定 logger 名字。
    • log_level:一个字符串,指定 log level 。默认为 LOG_LEVEL 环境变量指定的。如果没有 LOG_LEVEL 环境变量,则默认为 INFO
  3. 如果一个 log 应该在所有进程上都记录,那么使用 main_process_only=False;否则仅在全局主进程上记录。

2.6 与大型模型一起工作

2.6.1 Dispatching and Offloading Models

  1. accelerate.init_empty_weights(include_buffers: bool = False):一个上下文管理器,在这个管理器下,模型被初始化为所有 parameters 都在 meta device 上,因此创建一个空模型。当仅仅初始化模型就会耗尽可用的内存时,这很有用。

    参数:include_buffers:一个布尔值,指定在模型初始化时是否将所有的 buffers 也放在 meta device 上。

    示例:

  2. accelerate.cpu_offload( model: Module, execution_device: typing.Optional[torch.device] = None, offload_buffers: bool = False, state_dict: typing.Union[typing.Dict[str, torch.Tensor], NoneType] = None, preload_module_classes: typing.Optional[typing.List[str]] = None):将模型的所有 parameters 卸载到 CPU上。此时,仅在 CPU 中保留一份 state dictGPU 中没有了)。在前向传播过程中,parameters 将从 state dict 中提取,并在需要时放在 execution_device 上,然后再次卸载。

    参数:

    • model:一个 torch.nn.Module,指定被卸载的模型。
    • execution_device:一个 torch.device,指定执行模型前向传播的设备(应该是 GPU )。将默认为模型的第一个 parameter device
    • offload_buffers:一个布尔值,指定是否也同时卸载模型的 buffer
    • state_dict:一个字典,指定模型的 state dict(它将被保持在 CPU )。
    • preload_module_classes:一个关于字符串的列表,它们的实例应该在前向传播开始时就加载权重(包括实例中包含的子模块)。
  3. accelerate.disk_offload():将模型的所有 parameters 卸载到磁盘上。此时,模型的所有 parameter 将作为内存映射 array 被卸载到一个给定的目录中。在前向传播过程中,parameters 将从该目录中访问,并在需要时放在 execution_device 上,然后再次卸载。

    参数:

    • offload_dir:一个字符串或 os.PathLike,指定卸载权重到哪个目录。
    • model/execution_device/offload_buffers/preload_module_classes:参考 cpu_offload()
  4. accelerate.dispatch_model():根据一个给定的设备映射来 dispatch 一个模型。模型的各层可能分布在 GPU 上,也可能卸载在CPU 甚至磁盘上。

    参数:

    • model:一个 torch.nn.Module,指定要 dispatch 的模型。

    • device_map:一个字典,将模型 state_dict 中的模块名称映射到它们应该放置的设备。注意,设备名称可以是 "disk",即使它不是 torch.device 的正确值。

      它不需要细化到每个 parameter/buffer 名称,一旦一个给定的模块名称在里面,它的每个子模块都将被发送到同一个设备。要让 Accelerate 自动计算出最优化的设备映射,请设置 device_map="auto"

    • main_device:一个字符串、整数、或 torch.device,指定主执行设备。默认为 device_map 中不同于 "cpu""disk" 的第一个设备。

    • state_dict:一个字典,指定模型哪些部分的 state dict 被保留在 CPU 上。

    • offload_dir:一个字符串或 os.PathLike,指定卸载模型权重的文件夹(或者模型权重已经被卸载的地方)。

    • offload_index:一个字典,从权重名称到权重信息( dtype/shapesafetensors 文件名)。默认为 save_folder 中保存的 index

    • offload_buffers/preload_module_classes:参考 cpu_offload()

  5. accelerate.load_checkpoint_and_dispatch():加载一个 checkpoint(可能是被分片后的)到模型。可能在加载时将权重发送到一个给定的设备上,并添加各种 hooks ,这些 hooks 这个模型正常运行(即使在设备间分割)。

    参数:

    • model:一个 torch.nn.Module,指定需要加载 checkpoint 的模型。
    • checkpoint:一个字符串或 os.PathLike 对象,指定 checkpoint 的路径名。可以为:包含整个模型 state dict 的文件的路径、一个 .json 文件的路径(该 .json 文件包含 sharded checkpoint 的索引)、一个路径包含唯一的 .index.json 文件和 shards checkpoint
    • max_memory:一个字典,指定每个设备的最大内存。如果不设置,将默认为每个 GPU 的最大内存,以及可用的 CPU RAM
    • no_split_module_classes:一个关于字符串的列表,指定哪些 layer 不能跨设备分割(如,包含残差连接的层)。
    • dtype:一个字符串或 torch.dtype,指定权重在加载时被转换为什么类型。
    • offload_folder:一个字符串或 os.PathLike 对象,如果 device_map 包含 "disk" ,那么 offload_folder 指定卸载权重的目录。
    • offload_state_dict:一个布尔值,如果为 True,则临时卸载 CPU state dict 到硬盘上从而防止 CPU out of memory 。如果 device map 包含 "disk",则默认为 True
    • device_map/offload_buffers/preload_module_classes:参考 cpu_offload()

    示例:

2.6.2 Model Hooks

  1. class accelerate.hooks.ModelHook()hook 包含一些回调函数,这些回调函数在模块的前向传播之前或之后被调用。

    PyTorch 现有的 hook 不同的是,这里的 hook 会沿着 kwargs 传递。

    属性:

    • no_grad(bool, optional, defaults to False):是否在 torch.no_grad() 上下文管理器中执行实际的前向传播过程。

    方法:

    • detach_hook(module):当 hook 从一个模块中 detach 时执行该方法。

      参数:module:一个 torch.nn.Module 对象,指定模块。

    • init_hook(module):当 hook attach 到一个模块时执行该方法。

      参数:module:一个 torch.nn.Module 对象,指定模块。

    • post_forward(module, output) -> any:在模块的前向传播之后立即执行。

      参数:

      • module:一个 torch.nn.Module 对象,指定模块。
      • output:任何对象,表示模块前向传播的结果。

      返回:后处理的 output

    • pre_forward(module, *args, **kwargs) -> Tuple[Tuple[Any], Dict[Str, Any]]:在模块的前向传播之前执行。

      参数:

      • module:一个 torch.nn.Module 对象,指定模块。
      • args, kwargs:位置参数和关键字参数,被传递给 module

      返回值:处理过的 argskwargs 的元组。

  2. class accelerate.hooks.AlignDevicesHook():一个通用的 ModelHook ,确保 inputs 和模型权重在相关模块的前向传播中处于同一设备上,可能在前向传播之后卸载权重。

    参数:

    • execution_device:一个 torch.device,指定在前向传播之前,inputs 和模型权重应该放在哪个设备上。
    • offload:一个布尔值,指定权重是否应该在前向传播后被卸载。
    • io_same_device:一个布尔值,指定 outputs 是否应放在与 inputs 相同的设备上。
    • weights_map:一个 Mapping (可能是惰性的),指定当模型权重被卸载时,从参数名到张量值的映射。
    • offload_buffers:一个布尔值,指定卸载时是否也包含模块的 buffers
    • place_submodules:一个布尔值,指定在 init_hook 事件中是否将子模块放在 execution_device 上。
  3. class accelerate.hooks.SequentialHook(*hooks):一个 hook ,可以包含几个 hook ,并在每个事件中对这些子 hook 进行迭代。

  4. accelerate.hooks.add_hook_to_module( module: Module, hook: ModelHook, append: bool = False) -> torch.nn.Module:在一个给定的模块中添加一个 hook

    这将重写模块的 forward() 方法,使其包含 hook 。如果要删除这一行为并恢复原来的 forward() 方法,请使用remove_hook_from_module()

    • module:一个 torch.nn.Module 对象,指定需要 attach hook 的模块。
    • hook:一个 ModelHook,指定 hook
    • append:一个布尔值,指定当前的 hook 是否与 module 上已有的 hook 串起来(即,hook list)、或者替代已有的 hook 。默认为替代行为(False )。

    返回相同的 module,但是已经 attachhook 。注意,module 已经被原地修改了。

  5. accelerate.hooks.attach_execution_device_hook( module: Module, execution_device: typing.Union[int, str, torch.device], preload_module_classes: typing.Optional[typing.List[str]] = None):递归地将 AlignDevicesHook 附加到一个给定模型的所有子模块,以确保它们有正确的执行设备。

    参数:

    • module:一个 torch.nn.Module 对象,指定需要 attach hook 的模块。
    • execution_device:一个整数、字符串、或 torch.device,指定前向传播之前,inputs 和模型权重应该放到哪个设备。
    • preload_module_classes:参考 cpu_offload()
  6. accelerate.hooks.attach_align_device_hook( module: Module, execution_device: typing.Optional[torch.device] = None, offload: bool = False, weights_map: typing.Optional[typing.Mapping] = None, offload_buffers: bool = False, module_name: str = '', preload_module_classes: typing.Optional[typing.List[str]] = None):递归地将 AlignDevicesHook 附加到一个给定模型的所有子模块。

    参数:

    • module/execution_device/preload_module_classes:参考 attach_execution_device_hook()
    • offload/weights_map/offload_buffers:参考 AlignDevicesHook() 初始化方法。
    • module_name:一个字符串,指定模块的名字。
  7. accelerate.hooks.attach_align_device_hook_on_blocks(module: Module, execution_device: typing.Union[torch.device, typing.Dict[str, torch.device], NoneType] = None, offload: typing.Union[bool, typing.Dict[str, bool]] = False, weights_map: typing.Mapping = None, offload_buffers: bool = False, module_name: str = '', preload_module_classes: typing.Optional[typing.List[str]] = None):根据需要将AlignDevicesHook 附加到一个给定模型的所有 blocks 上。

    参数:参考 attach_align_device_hook()

  8. accelerate.hooks.remove_hook_from_module(module: Module, recurse = False ) -> torch.nn.Module:移除模块上附加的任何 hook

    参数:

    • module:一个 torch.nn.Module 对象,指定需要 detach hook 的模块。
    • recurse:一个布尔值,指定是否递归地移除。

    返回相同的 module,但是已经 detachhook 。注意,module 已经被原地修改了。

  9. accelerate.hooks.remove_hook_from_submodules(module: Module):递归地删除一个给定模型的子模块上的所有 hook

    参数:module:一个 torch.nn.Module 对象,指定需要 detach hook 的模块。

2.7 DeepSpeed 工具

  1. class accelerate.DeepSpeedPlugin:用于集成 DeepSpeed 的插件。

    方法:

    • deepspeed_config_process( prefix = '', mismatches = None, config = None, must_match = True, **kwargs ):用 kwargs 的内容来处理 DeepSpeed config
  2. class accelerate.utils.DummyOptim(params, lr = 0.001, weight_decay = 0, **kwargs)Dummy optimizer。 当在 deepspeed 配置文件中指定 optimizer config 时,如果遵循常规的训练循环则用该 Dummy optimizer

    参数:

    • lr:一个浮点数,指定学习率。
    • params:一个可迭代对象或字典,指定 parametersparameter group
    • weight_decay:一个浮点数,指定权重衰减。
    • kwargs:关键字参数。
  3. class accelerate.utils.DummyScheduler( optimizer, total_num_steps = None, warmup_num_steps = 0, **kwargs )Dummy scheduler 。当在 deepspeed 配置文件中指定 scheduler config 时,如果遵循常规的训练循环则用该 Dummy scheduler

    参数:

    • optimizer:一个 torch.optim.optimizer.Optimizer:指定优化器。
    • total_num_steps:一个整数,指定总的 step 数。
    • warmup_num_steps:一个整数,指定 warmupstep 数。
    • kwargs:关键字参数。
  4. class accelerate.utils.DeepSpeedEngineWrappe(engine):用于 deepspeed.runtime.engine.DeepSpeedEnginewrapper。它用于常规的训练循环。

    参数:engine:一个 deepspeed.runtime.engine.DeepSpeedEngine,指定被 wrapdeepspeed engine

  5. class accelerate.utils.DeepSpeedOptimizerWrapper(optimizer):用于 deepspeed optimizerwrapper

    参数:optimizer:一个 torch.optim.optimizer.Optimizer,指定被 wrap 的优化器。

  6. class accelerate.utils.DeepSpeedSchedulerWrapper(scheduler, optimizers):用于 deepspeed schedulerwrapper

    参数:

    • scheduler:一个 torch.optim.lr_scheduler.LambdaLR,指定被 wrapscheduler
    • optimizers:一个torch.optim.Optimizer 或它的列表,指定被 wrapoptimizer

2.8 Megatron-LM 工具

  1. class accelerate.utils.MegatronLMPluginMegatron-LM的插件,用于实现张量并行、管道并行、序列并行和数据并行。还可以启用 selective activation recomputationoptimized fused kernel

  2. class accelerate.utils.MegatronLMDummyScheduler(optimizer, total_num_steps = None, warmup_num_steps = 0, **kwargs )MegatronLM Dummy scheduler 。当在 megatron 配置文件中指定 scheduler config 时,如果遵循常规的训练循环则用该 Dummy scheduler

    参数:参考 DummyScheduler

  3. class accelerate.utils.MegatronLMDummyDataLoader(**dataset_kwargs)Dummy DataLoader,仅用于常规的训练循环。

  4. class accelerate.utils.AbstractTrainStep(name):用于 batching 的抽象类。

  5. class accelerate.utils.GPTTrainStep(args)GPT train step 类。

    参数:args:指定 Megatron-LM 的参数。

  6. class accelerate.utils.BertTrainStep(args)Bert train step 类。

    参数:args:指定 Megatron-LM 的参数。

  7. class accelerate.utils.T5TrainStep(args)T5 train step 类。

    参数:args:指定 Megatron-LM 的参数。

  8. accelerate.utils.avg_losses_across_data_parallel_group(losses):跨 data parallel group 来对损失函数值取平均。

    参数:losses:张量的列表,指定哪些 loss 需要跨 data parallel group 取平均。