分布式训练的配置主要包括以下几个方面:
- 进程配置
- 设置进程总数RANK_SIZE
- 为每个进程分配唯一的RANK_ID
- 为每个进程指定DEVICE_ID
- 通信配置
- 使用 Horovod 或 PyTorch 的分布式后端(gloo/nccl)
- 设置通信端口等参数
- 数据并行
- 对数据集做shard分片,使每个进程负责部分数据
- 配置Sampler采样方式为分布式采样
- 模型并行
- 将模型切分到不同进程,实现模型并行训练
- 在forward和backward时同步梯度和参数
- 优化器配置
- 使用分布式优化器,如DistributedOptimizer
- 不同进程聚合梯度,更新模型参数
- 初始化
- 初始化进程组,分布式后端,建立通信
- 广播参数,确保不同进程模型初始化一致
- 保存和加载
- 保存检查点时集合各进程的参数
- 加载时再广播到各进程
- 日志记录
- 添加进程id信息,便于追踪和debug
按照上述流程进行分布式环境的配置,可以实现分布式数据并行或模型并行,使模型训练加速。
实操:
实际操作时用的国产框架MindSpore,华为的分布式通信工具hccl(见附1):
首先,确保物理环境已配置device的网卡IP:
hccn_tool -i 0 -ip -s address 192.168.100.101 netmask 255.255.255.0
hccn_tool -i 1 -ip -s address 192.168.101.101 netmask 255.255.255.0
hccn_tool -i 2 -ip -s address 192.168.102.101 netmask 255.255.255.0
hccn_tool -i 3 -ip -s address 192.168.103.101 netmask 255.255.255.0
hccn_tool -i 4 -ip -s address 192.168.100.100 netmask 255.255.255.0
hccn_tool -i 5 -ip -s address 192.168.101.100 netmask 255.255.255.0
hccn_tool -i 6 -ip -s address 192.168.102.100 netmask 255.255.255.0
hccn_tool -i 7 -ip -s address 192.168.103.100 netmask 255.255.255.0
其次,在裸机上下载下载hccl_tool脚本并解压
git clone https://gitee.com/mindspore/models/tree/master/utils/hccl_tools
用法:
python3 hccl_tools.py --device_num "[0,8)"
将生成的hccl_8p.json移动到执行脚本下(以ResNet为例)
mv ./hccl_8p.json models-master/official/cv/resnet/scripts/
常见错误:
-
进程rank_id和device_id配置错误
不同进程配置了相同的rank_id和device_id,例如多个进程都配置了rank_id=2, device_id=6。
分布式训练每个进程的rank_id和device_id必须唯一。 -
重复启动了多个相同配置的进程
有些进程配置完全相同,只是启动了多个实例,这会导致分布式训练异常。
每个配置只要启动一个进程即可。 -
只有部分进程正常运行
从进程运行时间看,有些进程运行时间很短,应该是启动失败退出了。
需要检查这些进程的日志,分析失败原因。 -
进程数不足
只启动了部分进程,不够分布式训练所需的进程数。
需要确认启动脚本是否正确,保证启动了足够数目的进程。
可以采取以下措施:
- 仔细检查每个进程的rank_id和device_id配置,确保唯一性。
- 删除多余重复的进程,每个配置一个即可。
- 检查启动失败进程的日志,解决启动问题。
- 调整启动脚本,正确启动所需数目的进程。
- 启动时添加日志,打印出每个进程的rank_id和device_id,确认配置正确。
多卡并行训练时rank表配置错误问题:
Invalid ranktable, with rank_id [4] and local device_id [4].
rank_id和device_id不匹配。 rank表信息中,配置的是4张卡,rank_id分别为0、1、2、3。
但是当前进程的rank_id是4,不在rank表的范围内。 同时device_id也是4,不匹配rank表。
解决方法是:
- 检查rank表配置是否正确,确认当前训练脚本中设置的设备数量和rank表一致。
- 检查环境变量RANK_ID和DEVICE_ID是否设置正确,不能超出rank表配置的范围。
- 如果配置了备卡,需要额外配置备卡的rank_id。
- 确认每张卡上的进程配置的是不同的rank_id,与rank表中对应的device_id和rank_id匹配。
- 保证每张卡仅启动一个训练脚本进程,避免rank_id重复。
- 重新启动训练,确保环境变量、进程和rank表配置一致。
多卡训练需要确保各个进程的rank_id与设备完全对应,才能正常运行分布式任务。
这样可以避免进程配置错误,从而让分布式训练正常进行。
八卡同时训练问题:
- 配置文件检查
需检查hccl.json文件配置是否正确,hccl.json文件中的ip地址是否与设备实际ip对应,server_count与实际设备数一致,device_ip与rank_id是否一一对应,环境变量设置是否正确,训练脚本中RANK_SIZE是否设置为8,每个卡上的RANK_ID是否唯一并与hccl.json中的rank_id一致
- 设备状态检查
使用npu-smi info查看8张卡是否都在线 ;使用ps -ef | grep python确认8个进程是否都启动
检查每个进程的日志,是否只打印四张卡在运行 ;排查进程是否只启动在部分设备上 ;加打印日志,确认脚本执行时DEVICE_ID是否为0-7
检查脚本中是否有只使用部分device的逻辑 ;排查设备资源限制问题 ;使用ulimit -a检查设备资源限制是否充足
需要按步骤排查hccl.json文件,环境变量,设备状态,进程是否只在部分卡启动,以及资源限制等。
找到不一致的配置后修正,重新启动训练,直到8卡进程成功运行。
附1:
华为的HCCL (Heterogeneous Computing Communication Library) 是一种分布式通信工具。它是华为自主研发的用于异构计算的高性能通信库,旨在提供高效、可扩展的通信和协同计算能力。
HCCL能够实现不同设备之间的数据传输和通信,包括GPU、FPGA等。它提供了一套接口和协议,使得不同设备之间可以进行数据交换、共享和协同计算,从而加速复杂的计算任务。
HCCL被广泛应用于人工智能领域,特别是深度学习和大规模计算中。通过使用HCCL,用户可以将计算任务划分到多个设备上,并通过高效的通信机制将这些设备连接起来,实现分布式计算和协同处理,进一步提高计算性能和效率。