分布式训练
对于大型数据集,在单台机器上存储整个数据集并进行内存训练可能会非常昂贵。因此,Ludwig 支持将预处理、训练和预测步骤分布到多台机器和 GPU 上,以便并行处理数据的不同分区。
Ludwig 支持两种不同的分布式执行后端:Ray 和 Horovod / 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 的CPU 和 GPU 镜像。
配置好 Ray 集群后,您可以启动集群并将现有的 ludwig
命令或 Python 文件提交给 Ray 进行分布式执行
ray up cluster.yaml
ray submit cluster.yaml \
ludwig train --config config.yaml --dataset s3://mybucket/dataset.parquet
最佳实践¶
云存储¶
为了让 Ray 预处理输入的 dataset
,数据集文件路径必须能从每个工作节点读取。有几种方法可以实现这一点
在大多数情况下,我们建议使用对象存储系统,例如 S3 (AWS)、GCS (GCP) 或 ADLS (Azure)。
要从 Ludwig 连接到这些系统之一,您需要两件事
-
在您的 Python 环境中安装相应的 filesystem 驱动包
s3fs # S3 adlfs # Azure Storage gcsfs # GCS
-
在您的容器中挂载您的凭据文件或设置正确的环境变量(示例:S3)。
有关每个主要文件系统的更详细说明,请参阅云存储。
自动扩展集群¶
默认情况下,Ludwig on Ray 将尝试使用所有可用的 GPU 进行分布式训练。但是,如果在自动扩展集群中运行,当 Ludwig 执行检查时,集群中可能没有任何 GPU。在这种情况下,我们建议在配置中显式设置 GPU worker 的数量。
例如,要使用 4 个 GPU 进行训练
backend:
trainer:
use_gpu: true
num_workers: 4
在自动扩展集群中使用 Hyperopt 时,您应该设置 max_concurrent_trials
和 gpu_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 的工作原理是增加批次大小,并将每个批次的一部分分发到不同的节点,然后以智能且可扩展的方式从所有节点收集梯度。它还会调整学习率以平衡批次大小的增加。其优势在于训练速度几乎与节点数量呈线性关系。
experiment
、train
和 predict
命令接受一个 --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...
这同样适用于 experiment
、predict
和 test
。
有关 Horovod 安装和运行参数的更多详细信息,请参阅 Horovod 文档。