注意
点击 这里 下载完整示例代码
5. DistributedDataParallel (DDP) 框架¶
在视频上训练深度神经网络非常耗时。例如,使用配备 8 块 V100 GPU 的服务器在 Kinetics400 数据集(包含 24 万段 10 秒短视频)上训练最先进的 SlowFast 网络需要 10 多天。训练缓慢会导致研究周期变长,对新手和学生进行视频相关问题研究不友好。使用分布式训练是一个自然的选择。将巨大的计算分散到多台机器上可以大大加快训练速度。然而,目前只有少数开源的视频理解 Github 仓库支持分布式训练,并且它们通常缺乏关于此功能的文档。此外,在线上关于如何对深度视频模型进行分布式训练的信息/教程也不多。
因此,我们在这里提供一个简单的教程,演示如何使用我们的 DistributedDataParallel (DDP) 框架进行高效的分布式训练。请注意,即使在具有多个 GPU 的单个实例中,也应该使用 DDP,它比普通的 DataParallel 效率更高。
分布式训练¶
我们可以通过两种方式将神经网络训练的负载分配到多个设备上:数据并行和模型并行。数据并行是指每个设备存储模型的完整副本的情况。每个设备处理数据集的不同部分,设备共同更新共享模型。当模型非常大无法放入设备内存时,模型并行就很有用。在这种情况下,不同的设备负责学习模型的不同部分。在本教程中,我们将介绍如何以数据并行的方式训练模型,设备分布在多台机器上。具体来说,我们采用 DistributedDataParallel (DDP),它实现了模块级别的数据并行,可应用于多台机器。DDP 会生成多个进程,每个进程创建一个 GPU 实例。它可以更均匀地分散计算,特别适用于深度视频模型的训练。
为了保持本教程的简洁,我不会详细介绍 DDP 是什么。读者可以参考 PyTorch 官方教程 获取更多信息。
如何使用我们的 DDP 框架?¶
为了进行分布式训练,您需要 (1) 准备集群;(2) 准备环境;以及 (3) 准备您的代码和数据。
我们需要一个集群,其中每个节点都能相互通信。第一步是为每台机器生成 ssh 密钥。为了更好地说明,假设我们有两台机器,node1 和 node2。
首先,ssh 进入 node1 并输入
ssh-keygen -t rsa
按照默认设置操作,您将在 ~/.ssh/
文件夹下得到一个名为 id_rsa
的文件和一个名为 id_rsa.pub
的文件。id_rsa
是 RSA 私钥,id_rsa.pub
是其公钥。
其次,将 node1 的两个文件(id_rsa
和 id_rsa.pub
)复制到所有其他机器上。对于每台机器,您也会在 ~/.ssh/
文件夹下找到一个 authorized_keys
文件。将 authorized_keys
文件追加 id_rsa.pub
的内容。这一步将确保集群中的所有机器都能够相互通信。
在进行下一步之前,最好进行一些健全性检查,确保通信良好。例如,如果您可以成功 ssh 到其他机器,则意味着它们现在可以相互通信了。您可以继续了。如果在 ssh 过程中出现任何错误,您可以使用选项 -vvv
获取详细信息进行调试。
集群准备好后,就可以准备环境了。请查看 GluonCV 安装指南 获取更多信息。每台机器都应该有相同的环境,例如 CUDA、PyTorch 和 GluonCV,以便代码可以运行。
现在是时候在每个节点上准备您的代码和数据了。在代码更改方面,您只需要修改 yaml 配置文件中的 DDP_CONFIG 部分。例如,在我们的例子中,我们有 2 个节点,然后将 WORLD_SIZE 更改为 2。WOLRD_URLS 包含用于训练的所有机器的 IP(目前仅支持局域网 IP),您可以将它们的 IP 地址放在列表中。如果 AUTO_RANK_MATCH 为 True,启动器将自动为 WOLRD_URLS 中的每台机器分配一个世界排名号,并将第一台机器视为根节点。请确保使用根节点的 IP 作为 DIST_URL。如果 AUTO_RANK_MATCH 为 False,则需要手动为每个实例设置一个排名号。被分配 rank=0 的实例将被视为根机器。我们建议始终启用 AUTO_RANK_MATCH。示例配置如下所示,
DDP_CONFIG:
AUTO_RANK_MATCH: True
WORLD_SIZE: 2 # Total Number of machines
WORLD_RANK: 0 # Rank of this machine
DIST_URL: 'tcp://172.31.72.195:23456'
WOLRD_URLS: ['172.31.72.195', '172.31.72.196']
GPU_WORLD_SIZE: 8 # Total Number of GPUs, will be assigned automatically
GPU_WORLD_RANK: 0 # Rank of GPUs, will be assigned automatically
DIST_BACKEND: 'nccl'
GPU: 0 # Rank of GPUs in the machine, will be assigned automatically
DISTRIBUTED: True
完成后,您就可以在每台机器上启动训练了。只需在每个实例上使用所需的配置文件运行 train_ddp_pytorch.py/test_ddp_pytorch.py,例如,
python train_ddp_pytorch.py --config-file XXX.yaml
如果您使用多个实例进行训练,我们建议您首先在根实例上开始运行,然后在其他实例上启动代码。默认情况下,日志只会显示在根实例上。
最后,我们要指出的是,我们已将 dataloader 和训练/测试循环集成到我们的 DDP 框架中。如果您只是想在您自己的数据集/用例上尝试我们的模型库,请参阅之前的微调教程。如果您有新的视频模型,可以将其添加到模型库(例如,一个 .py 文件),并享受我们的 DDP 框架带来的加速。您无需处理多进程数据加载和底层的分布式训练设置。
脚本总运行时间: ( 0 分 0.000 秒)