跳到内容

分布式训练

对于大型数据集,在单台机器上存储整个数据集并进行内存训练可能会非常昂贵。因此,Ludwig 支持将预处理、训练和预测步骤分布到多台机器和 GPU 上,以便并行处理数据的不同分区。

img

Ludwig 支持两种不同的分布式执行后端RayHorovod / MPI。在大多数情况下,我们建议使用 Ray(它同时支持分布式数据处理和分布式训练),但也支持原生的 Horovod 执行,特别是对于习惯使用 MPI 运行的用户。

Ray

Ray 是一个分布式计算框架,可以轻松地将运行在本地机器上的代码扩展到整个集群中并行执行。

Ludwig 原生集成了 Ray,支持超参数搜索和分布式训练。

使用 Ray 运行相比本地执行有以下几个优势

  • Ray 通过其集群启动器,只需一个命令即可为您配置机器集群。
  • 在 Ray 上运行 Horovod 允许您进行分布式训练,而无需在您的环境中配置 MPI。
  • 在 Ray 上运行 Dask 允许您处理无法在单台机器内存中容纳的大型数据集。
  • Ray Tune 允许您轻松地在多台机器上并行运行分布式超参数搜索。
  • Ray 提供对云中高性能实例的便捷访问,例如高内存或 GPU 机器。

所有这些都无需更改 Ludwig 中的任何一行代码即可获得。当 Ludwig 检测到您在 Ray 集群中运行时,Ray 后端将自动启用。您也可以通过命令行显式启用 Ray 后端

ludwig train ... --backend ray

或在 Ludwig 配置文件中

backend:
  type: ray
  processor:
    type: dask
  trainer:
    strategy: ddp

使用 Ray 运行 Ludwig

要在 Ludwig 中使用 Ray,您需要有一个正在运行的 Ray 集群。启动 Ray 集群最简单的方法是使用 Ray 的集群启动器,它可以使用 pip 在本地安装

pip install ray

启动 Ray 集群需要您能够访问云实例提供商,例如 AWS EC2 或 Kubernetes。

这是一个您可以用来创建您的 Ludwig Ray 集群的 Ray 集群配置 YAML 文件示例(部分)

cluster_name: ludwig-ray-gpu-latest

min_workers: 4
max_workers: 4

docker:
    image: "ludwigai/ludwig-ray-gpu:latest"
    container_name: "ray_container"

head_node:
    InstanceType: m5.2xlarge
    ImageId: latest_dlami

worker_nodes:
    InstanceType: g4dn.2xlarge
    ImageId: latest_dlami

此配置运行在 AWS EC2 实例上,包含一个 CPU 头节点和 4 个 GPU (Nvidia T4) 工作节点。每个工作节点都在一个 Docker 镜像中运行,该镜像提供了 Ludwig 及其依赖项,包括 Ray、Dask、Horovod 等。您可以使用这些预构建的 Docker 镜像作为集群的父镜像。Ludwig 提供了可用于 Ray 的CPUGPU 镜像。

配置好 Ray 集群后,您可以启动集群并将现有的 ludwig 命令或 Python 文件提交给 Ray 进行分布式执行

ray up cluster.yaml
ray submit cluster.yaml \
    ludwig train --config config.yaml --dataset s3://mybucket/dataset.parquet

最佳实践

云存储

为了让 Ray 预处理输入的 dataset,数据集文件路径必须能从每个工作节点读取。有几种方法可以实现这一点

  • 将输入数据集复制到每个工作节点的本地文件系统(适用于小型数据集)。
  • 使用网络挂载的文件系统,例如 NFS
  • 使用对象存储系统,例如 Amazon S3

在大多数情况下,我们建议使用对象存储系统,例如 S3 (AWS)、GCS (GCP) 或 ADLS (Azure)。

要从 Ludwig 连接到这些系统之一,您需要两件事

  1. 在您的 Python 环境中安装相应的 filesystem 驱动包

    s3fs   # S3
    adlfs  # Azure Storage
    gcsfs  # GCS
    
  2. 在您的容器中挂载您的凭据文件或设置正确的环境变量(示例:S3)。

有关每个主要文件系统的更详细说明,请参阅云存储

自动扩展集群

默认情况下,Ludwig on Ray 将尝试使用所有可用的 GPU 进行分布式训练。但是,如果在自动扩展集群中运行,当 Ludwig 执行检查时,集群中可能没有任何 GPU。在这种情况下,我们建议在配置中显式设置 GPU worker 的数量。

例如,要使用 4 个 GPU 进行训练

backend:
  trainer:
    use_gpu: true
    num_workers: 4

在自动扩展集群中使用 Hyperopt 时,您应该设置 max_concurrent_trialsgpu_resources_per_trial,否则 Ludwig 同样会低估在完全扩展的集群中同时可以运行多少个 trial

hyperopt:
  executor:
    max_concurrent_trials: 4
    gpu_resources_per_trial: 1

DeepSpeed

您可以使用 DeepSpeed 启动器运行,它支持在多个 GPU 和多台机器上进行大型模型训练。

示例

deepspeed --no_python --no_local_rank --num_gpus 4 \
    ludwig train --config config.yaml --dataset dataset.csv

当使用 ray 后端时,DeepSpeed 也可以用作分布式策略。使用 ray 后端允许 Ludwig 使用超出内存大小的数据集进行训练,但这会带来一些协调开销。实际上,性能是可比的,尽管 Ludwig on Ray 相较于使用 deepspeed CLI 运行,有一些额外的优化来减少内存压力。

Horovod / MPI

您可以使用 Horovod 分布您的模型的训练和预测,它支持在单台机器上使用多个 GPU 进行训练,也支持在多台机器上使用多个 GPU 进行训练。

为了使用分布式训练,您必须按照 Horovod 的安装说明详细安装 Horovod。如果您希望使用 MPI,请务必在安装 Horovod 之前安装 OpenMPI 或其他实现。

pip install horovod mpi4py

实践中,Horovod 的工作原理是增加批次大小,并将每个批次的一部分分发到不同的节点,然后以智能且可扩展的方式从所有节点收集梯度。它还会调整学习率以平衡批次大小的增加。其优势在于训练速度几乎与节点数量呈线性关系。

experimenttrainpredict 命令接受一个 --backend=horovod 参数,该参数指示使用 Horovod 以分布式方式执行模型构建、训练和预测阶段。在调用 Ludwig 命令之前,必须提供一个 horovodrun 命令,指定要使用的机器和/或 GPU,以及其他一些参数。例如,要在本地机器上使用四个 GPU 训练 Ludwig 模型,您可以运行

horovodrun -np 4 \
    ludwig train ...other Ludwig parameters...

要在四台远程机器上使用四个 GPU 进行训练,您可以运行

horovodrun -np 16 \
    -H server1:4,server2:4,server3:4,server4:4 \
    ludwig train ...other Ludwig parameters...

这同样适用于 experimentpredicttest

有关 Horovod 安装和运行参数的更多详细信息,请参阅 Horovod 文档