背景与挑战
随着大模型并行训练可配置的参数越来越多,例如DP、TP(以及SP)、PP、ZeRO、VPP、CP、EP、MicroBatchSize以及重计算等,内存和性能受到各种配置的影响变得越来越复杂,人工调优变得越来越困难。于是,业内开始尝试一些自动调优的方法,主要思路是基于网络模型的结构进行白盒或者灰盒建模,在建模的指导下结合一些profiling,进行配置参数的搜索。但是,这些方法通常存在以下不足之处:
- 白盒或灰盒的建模对网络模型的结构进行了假设,而很多用户会对模型进行修改,这类建模难以捕捉到模型的变化。例如,仅仅是GQA或MQA的修改,就会让此类建模的内存出现偏差。
- profiling的规模和实际的负载规模相同,当要进行大规模(如千卡)的训练时,profiling的开销会变得很大。
解决方案
为应对上述挑战,我们设计并开发了一种Auto Tuning的特性,该特性与业内已有的自动调优方案相比,完全基于profiling的分析,无需对网络的结构做出假设,且支持“以小仿大”,即以小规模的profiling预估更大集群上的较优训练配置。
Auto Tuning特性完全依赖由profiling得出的黑盒建模,与网络结构的变化解耦,并且支持在小规模集群(如双机)上推测大规模集群的配置。
- 阶段1:用少量机器拉起Auto Tuning,该特性会裁剪网络大小,并生成多个profiling的配置,自动多次拉起。这些profiling主要是用于黑盒分析,例如分析配置变化时,哪些tensor会被切分,哪些算子的shape会如何变化,会增加或减少哪些算子等。profiling结束后会对结果文件进行解析,提取出后续黑盒建模需要的信息。
- 阶段2:依据profiling结果进行黑盒建模。内存方面会自动分析各个tensor在不同配置下的切分情况,性能方面会推断算子随不同配置的增减和shape变化,并用线性回归得出机内和机间通信的效率。除了基础的性能和内存建模之外,还会分析各个候选重计算模块的性能和内存,从而可以在后续搜索中预估应该选择哪些模块做重计算,以及其对性能和内存的影响。
- 阶段3:根据阶段2得出的建模,进行配置的搜索,给出每个配置下预期的性能和内存。这一步还会依赖一个算子性能知识库,从中查询不同shape的算子的性能。profiling产生的没见过的算子都会被添加到算子性能知识库中。如果某个配置下算子性能知识库覆盖的算子比例小于阈值,则会额外拉起一组profiling,该profiling仍然可以以小仿大,通过同时缩小网络规模和并行参数,从而得到相同shape的算子。如果算子性能知识库覆盖的算子比例不足以推测算子性能,则未覆盖到的少量算子会通过线性回归来估计性能。搜索结束后会推荐出内存充足的性能最好的三组配置。
使用场景
已支持的模型:llama2-7b、mixtral-8*7b、gpt3-15b
已支持的特性:DP、TP、Megatron-SP、PP、ZeRO1、VPP、CP(Ring Attention)、EP(DeepSpeed-MoE)、MicroBatchSize、Token重排、重计算
使用方法
在训练脚本的参数列表中加入以下配置开启Auto Tuning特性,仅1.0.0_core_r0.7.0分支支持该特性。
表1 方法说明重要参数
|
参数说明
|
--auto-tuning
|
开启Auto Tuning特性。
|
--auto-tuning-work-dir <auto_tuning_dir>
|
工作目录,在此会保存profiling等文件。
可配置为绝对路径或者相对路径。执行用户需要有此路径的可读写权限。
|
--auto-tuning-ranks [int]
|
需要搜索的卡数,最低16卡。
|
--auto-tuning-log-level debug
|
Auto Tuning日志级别,包括以下几种:
warning、info、debug。
|
--nnodes <NNODES>
|
Profiling拉起的节点数,与基线训练脚本保持一致。
|
--nproc-per-node <GPUS_PER_NODE>
|
每个节点上运行的进程数,一般与单节点卡数相同,与基线训练脚本保持一致。
|
--master-addr <MASTER_ADDR>
|
主节点IP,与基线训练脚本保持一致。
|
--master-port 6005
|
主节点端口,设置一个与基线脚本不同的端口。
|
--node-rank <Node_Rank>
|
与基线训练脚本保持一致。
|
使用效果
使能该特性能自动寻找出一组较优并行配置,有助于提升模型训练效率。