Skip to content

启动 Accelerate 脚本

在上一个教程中,你了解了如何修改当前的训练脚本来使用 Accelerate。 该代码的最终版本如下所示:

python
from accelerate import Accelerator

accelerator = Accelerator()

model, optimizer, training_dataloader, scheduler = accelerator.prepare(
    model, optimizer, training_dataloader, scheduler
)

for batch in training_dataloader:
    optimizer.zero_grad()
    inputs, targets = batch
    outputs = model(inputs)
    loss = loss_function(outputs, targets)
    accelerator.backward(loss)
    optimizer.step()
    scheduler.step()

但是,你如何运行这段代码并利用可用的特殊硬件呢?

首先,你应该将上述代码重写为一个函数,并使其可以作为脚本调用。例如:

diff
  from accelerate import Accelerator
  
+ def main():
      accelerator = Accelerator()

      model, optimizer, training_dataloader, scheduler = accelerator.prepare(
          model, optimizer, training_dataloader, scheduler
      )

      for batch in training_dataloader:
          optimizer.zero_grad()
          inputs, targets = batch
          outputs = model(inputs)
          loss = loss_function(outputs, targets)
          accelerator.backward(loss)
          optimizer.step()
          scheduler.step()

+ if __name__ == "__main__":
+     main()

接下来,你需要使用 accelerate launch 启动它。

使用 accelerate launch

Accelerate 提供了一个特殊的 CLI 命令,帮助你在系统中通过 accelerate launch 启动代码。 此命令封装了所有在不同平台上启动脚本所需的不同命令,你无需记住每个命令的具体内容。

你可以通过以下方式快速启动你的脚本:

bash
accelerate launch {script_name.py} --arg1 --arg2 ...

只需在命令的开头加上 accelerate launch,然后像往常一样传递额外的参数和选项到你的脚本中!

由于这会运行各种 torch spawn 方法,因此所有预期的环境变量也可以在这里进行修改。 例如,这是如何使用 accelerate launch 与单个 GPU:

bash
accelerate launch your_script.py --arg1 value1 --arg2 value2
bash
# for cuda device:
CUDA_VISIBLE_DEVICES="0" accelerate launch {script_name.py} --arg1 --arg2 ...
# for xpu device:
ZE_AFFINITY_MASK="0" accelerate launch {script_name.py} --arg1 --arg2 ...

你也可以在不先执行 accelerate config 的情况下使用 accelerate launch,但你可能需要手动传递正确的配置参数。 在这种情况下,Accelerate 会为你做出一些超参数决策,例如,如果 GPU 可用,它将默认使用所有 GPU 而不使用混合精度。 以下是如何使用所有 GPU 并禁用混合精度进行训练:

bash
accelerate launch --num_gpus=all --mixed_precision=no your_script.py
bash
accelerate launch --multi_gpu {script_name.py} {--arg1} {--arg2} ...

或者通过指定要使用的 GPU 数量:

bash
accelerate launch --num_processes=2 {script_name.py} {--arg1} {--arg2} ...

为了更具体,你应该自己传递所需的参数。例如,这里是如何在两个 GPU 上使用混合精度运行相同的脚本,同时避免所有警告:

bash
accelerate launch --multi_gpu --mixed_precision=fp16 --num_processes=2 {script_name.py} {--arg1} {--arg2} ...

要查看可以传递的所有参数的完整列表,请运行:

bash
accelerate launch -h

为了直观地展示这种差异,之前在多 GPU 上的 accelerate launch 操作使用 torchrun 时会如下所示:

bash
MIXED_PRECISION="fp16" torchrun --nproc_per_node=2 --nnodes=1 {script_name.py} {--arg1} {--arg2} ...

你也可以通过将脚本作为 Python 模块本身使用 launch CLI 来启动,从而能够传递其他 Python 特定的启动行为。为此,请使用 accelerate.commands.launch 而不是 accelerate launch

bash
python -m accelerate.commands.launch --num_processes=2 {script_name.py} {--arg1} {--arg2}

如果你想要使用其他 Python 标志来执行脚本,也可以像使用 -m 一样传递这些标志,例如下面的示例启用了未缓冲的标准输出和标准错误:

bash
python -u -m accelerate.commands.launch --num_processes=2 {script_name.py} {--arg1} {--arg2}

为什么你应该始终使用 accelerate config

为什么它如此有用,以至于你应该始终运行 accelerate config

还记得之前调用的 accelerate launch 以及 torchrun 吗? 配置完成后,要运行该脚本并包含所需的部分,你只需直接使用 accelerate launch,而无需传递任何其他参数:

bash
accelerate launch {script_name.py} {--arg1} {--arg2} ...

自定义配置

正如前面简要提到的,accelerate launch 主要通过结合使用 accelerate config 命令创建的配置来使用。这些配置会保存到 Accelerate 缓存文件夹中的 default_config.yaml 文件。此缓存文件夹的位置(按优先级从高到低)为:

  • 环境变量 HF_HOME 的内容,后缀为 accelerate
  • 如果不存在,则为环境变量 XDG_CACHE_HOME 的内容,后缀为 huggingface/accelerate
  • 如果上述两者都不存在,则为 ~/.cache/huggingface/accelerate

为了拥有多个配置,可以使用 --config_file 标志将自定义的 yaml 文件路径传递给 accelerate launch 命令。

一个示例 yaml 文件可能如下所示,适用于单机上的两个 GPU,并使用 fp16 进行混合精度计算:

yaml
compute_environment: LOCAL_MACHINE
deepspeed_config: {}
distributed_type: MULTI_GPU
fsdp_config: {}
machine_rank: 0
main_process_ip: null
main_process_port: null
main_training_function: main
mixed_precision: fp16
num_machines: 1
num_processes: 2
use_cpu: false

从自定义 yaml 文件的位置启动脚本的示例如下:

bash
accelerate launch --config_file {path/to/config/my_config_file.yaml} {script_name.py} {--arg1} {--arg2} ...

多节点训练

使用 Accelerate 进行多节点训练与 使用 torchrun 进行多节点训练 类似。启动多节点训练的最简单方法如下:

  • 将你的代码库和数据复制到所有节点上。(或将其放在共享文件系统上)
  • 在所有节点上设置你的 Python 包。
  • 首先在主节点上运行 accelerate config。在指定节点数量后,你将被要求指定每个节点的排名(主/主节点的排名为 0),以及主进程的 IP 地址和端口。这是为了让工作节点能够与主进程通信。之后,你可以将此配置文件复制或发送到所有节点上,并将 machine_rank 更改为 1、2、3 等,以避免在每个节点上运行该命令(或者直接按照其说明使用 torchrun 启动)

完成这些步骤后,你可以在所有节点上运行 accelerate launch(或 torchrun)来启动多节点训练。

要更好地了解多节点训练,请查看我们关于 使用 FSDP 进行多节点训练的示例