分布式并行概述
在深度学习中,当数据集和参数量的规模越来越大,训练所需的时间和硬件资源会随之增加,最后会变成制约训练的瓶颈。分布式并行训练,可以降低对内存、计算性能等硬件的需求,是进行训练的重要优化手段。此外,分布式并行对大模型训练和推理有着重要的意义,它为处理大规模数据和复杂模型提供了强大的计算能力和性能优势。
要实现分布式并行训练和推理,您可以参考以下指引:
启动方式
MindSpore目前支持四种启动方式:
msrun:是动态组网的封装,允许用户使用单命令行指令在各节点拉起分布式任务,安装MindSpore后即可使用,不依赖外部配置或者模块,支持Ascend/GPU/CPU。
动态组网:通过MindSpore内部动态组网模块启动,不依赖外部配置或者模块,支持Ascend/GPU/CPU。
mpirun:通过多进程通信库OpenMPI启动,支持Ascend/GPU。
rank table:配置rank_table表后,通过脚本启动和卡数对应的进程,支持Ascend。
详细可参考分布式并行启动方式章节。
并行模式
目前MindSpore可以采取下述的几种并行模式,您可以按需求选择:
数据并行模式:数据并行模式下,数据集可以在样本维度拆分并下发到不同的卡上。如果您的数据集较大,而模型参数规模能在单卡运算,您可以选择这种并行模型。参考数据并行教程了解更多信息。
自动并行模式:融合了数据并行、算子级模型并行的分布式并行模式,可以自动建立代价模型,找到训练时间较短的并行策略,为用户选择合适的并行模式。如果您的数据集和模型参数规模都较大,且希望自动配置并行策略,您可以选择这种并行模型。参考自动并行教程了解更多信息。
半自动并行模式:相较于自动并行,该模式需要用户对算子手动配置切分策略实现并行。如果您数据集和模型参数规模都较大,且您对模型的结构比较熟悉,知道哪些“关键算子”容易成为计算瓶颈,为“关键算子”配置合适的切分策略可以获得更好的性能,您可以选择这种并行模式。此外该模式还可以手动配置优化器并行和流水线并行。参考半自动并行教程了解更多信息。
手动并行模式:在手动并行模式下,您可以基于通信原语例如
AllReduce
、AllGather
、Broadcast
等通信算子进行数据传输,手动实现分布式系统下模型的并行通信。您可以参考手动并行教程了解更多信息。参数服务器模式:相比于同步的训练方法,参数服务器具有更好的灵活性、可拓展性。您可以参考参数服务器模式教程了解更多信息。
保存和加载模型
模型的保存可以分为合并保存和非合并保存,可以通过mindspore.save_checkpoint
或者mindspore.train.CheckpointConfig
中的integrated_save
参数选择是否合并保存。合并保存模式下模型参数会自动聚合保存到模型文件中,而非合并保存模式下每张卡保存各自卡上的参数切片。关于各并行模式下的模型保存可以参考模型保存教程。
模型的加载可以分为完整加载和切片加载。若保存的是完整参数的模型文件,则可以直接通过load_checkpoint
接口加载模型文件。若保存的是多卡下的参数切片文件,则需要考虑加载后的分布式切分策略或集群规模是否有变化。如果分布式切分策略或集群规模不变,则可以通过load_distributed_checkpoint
接口加载各卡对应的参数切片文件,可以参考模型加载教程。
若保存和加载的分布式切分策略或集群卡数改变的情况下,则需要对分布式下的Checkpoint文件进行转换以适配新的分布式切分策略或集群卡数。您可以参考模型转换了解更多信息。
故障恢复
在分布式并行训练过程中,可能会遇到计算节点的故障或通信中断等问题。MindSpore提供了三种恢复方式以保证训练的稳定性和连续性:
根据完整Checkpoint恢复:在保存Checkpoint文件前,通过AllGather算子汇聚模型的完整参数,每张卡均保存了完整的模型参数文件,可以直接加载恢复。多个checkpoints副本提高了模型的容错性,但是对于大模型来说,汇聚的过程会导致各种资源开销过大。详细可参考模型加载教程。
动态组网场景下故障恢复:在动态组网中,若某个进程出现故障,其他进程会进入等待状态,可以通过重新拉起故障进程使得训练任务继续进行(目前仅支持GPU硬件平台)。和其他方式相比,该故障恢复方式无需重启集群。详细可参考动态组网场景下故障恢复教程。
根据参数切分的冗余信息恢复:在大模型训练中,根据数据并行的维度所划分的设备,他们的模型参数是相同的。根据这个原理,可以利用这些冗余的参数信息作为备份,在一个节点故障时,利用相同参数的另一节点就可以恢复故障的节点。详细可参考基于冗余信息的故障恢复教程。
优化方法
如果对性能、吞吐量或规模有要求,或者不知道如何选择并行策略,可以考虑以下优化技术:
并行策略优化:
内存优化:
梯度累加:梯度累加通过在多个MicroBatch上计算梯度并将它们累加起来,然后一次性应用这个累加梯度来更新神经网络的参数。通过这种方法少量设备也能训练大Batch Size,有效减低内存峰值,详细可参考梯度累加教程。
重计算:重计算通过不保存某些正向算子的计算结果,以节省内存空间,在计算反向算子时,需要用到正向结果再重新计算正向算子。详细可参考重计算教程。
数据集切分:数据集单个数据过大的时候,可以对数据进行切分,进行分布式训练。数据集切分配合模型并行是有效降低显存占用的方式。详细可参考数据集切分教程。
Host&Device异构:在遇到参数量超过Device内存上限的时候,可以把一些内存占用量大且计算量少的算子放在Host端,这样能同时利用Host端内存大,Device端计算快的特性,提升了设备的利用率。详细可参考Host&Device异构教程。
异构存储:大模型目前受限显存大小,难以在单卡上训练。大规模分布式集群训练中,在通信代价越来越大的情况下,提升单机的显存,减少通信,也能提升训练性能。异构存储可以将暂时不需要用到的参数或中间结果拷贝到Host端内存或者硬盘,在需要时再恢复至Device端。详细可参考异构存储教程。
通信优化:
不同平台差异
在分布式训练中,不同硬件平台(Ascend、CPU或者GPU)支持的特性也有所不同,用户可以根据自己的平台选择对应的分布式启动方式、并行模式和优化方法。
启动方式的差异
Ascend支持msrun、动态组网、mpirun以及rank table启动四种启动方式。
GPU支持msrun、动态组网和mpirun三种启动方式。
CPU支持msrun和动态组网启动。
详细过程请参考启动方式。
并行方式的差异
Ascend和GPU支持所有并行方式,包括数据并行、半自动并行、自动并行等。
CPU仅支持数据并行。
优化特性支持的差异
Ascend支持所有的优化特性。
GPU支持除了通信子图提取与复用以外的优化特性。
CPU不支持优化特性。
详细过程请参考优化方法。