方案和原理
故障检测
故障说明
断点续训基于故障检测能力获取集群和训练业务的故障状态,根据检测结果进行故障处理。当前,断点续训特性主要提供以下几个方面的故障检测能力:昇腾硬件故障、训练业务故障、其他故障发送方的故障。
MindCluster集群调度组件Ascend Device Plugin提供NPU芯片故障检测能力及NPU参数面网络故障检测能力,NodeD提供服务器节点故障、DPC共享存储故障和灵衢网络故障检测能力,ClusterD提供公共故障检测能力,Volcano提供业务面容器异常检测能力,故障检测整体架构如下图所示。

- 计算服务器上的Ascend Device Plugin通过驱动获取NPU芯片故障以及参数面网络故障后,将故障信息上报到管理服务器。
- 计算服务器上的NodeD通过驱动获取服务器节点故障、DPC共享存储故障和灵衢网络故障信息后,将故障信息上报到管理服务器。
- 计算服务器上的K8s监测训练容器状态,训练容器异常后上报到K8s中,管理服务器上的Volcano通过K8s获取训练容器的故障信息。
- 管理服务器上的ClusterD通过公共故障接口获取公共故障后,将接收到的信息进行汇总写入cluster-info-device-cm。
- (可选)管理服务器上的ClusterD汇总集群内所有Ascend Device Plugin和NodeD上报的故障信息。
当前已支持200+故障的检测。支持的故障类型请参见表1,详细的故障说明请参见典型故障.xlsx。
表 1 故障类型说明
| 故障类型 | 故障说明 |
|---|---|
| 节点故障 | 包括节点健康状态、节点硬件故障和DPC共享存储故障。 故障码说明请参见节点故障码参考文档。 若节点的硬件故障导致节点宕机或重启,则NodeD无法检测到具体的故障类型并上报。 |
| 芯片故障 | DCMI接口上报的芯片故障和设备网络探测工具hccn_tool检测到的芯片网络故障。 故障码说明请参见芯片故障码参考文档。 |
| 参数面网络故障 | 包括芯片网络相关故障和灵衢总线设备故障。
|
| 业务面故障 | 训练任务异常退出,导致Pod的Status变为Failed状态。 可执行kubectl describe pod {pod名称} -n {NAMESPACE} |grep Status:命令,查看当前Pod的Status是否为Failed状态。回显示例如下: Status: Failed |
| 公共故障 | 公共故障指的是其他故障发现者(非MindCluster组件)提供的故障,公共故障包括以下几种类型:NPU故障、节点故障、网络故障和存储故障。 |
| pingmesh灵衢网络故障 | 灵衢网络故障是针对超节点内部(包括节点内和节点间)的HCCS网络提供的NPU网络故障检测。 |
| 性能劣化故障 | MindCluster结合MindStudio提供的profiling能力对集群中的性能劣化故障(慢节点)提供诊断功能。该功能提供动态启动打点和打点数据持久化功能、可动态启停,无需重启任务进行诊断,对训练无损耗。 |
-
每个计算节点的Ascend Device Plugin均会创建记录本节点NPU和灵衢总线设备信息的ConfigMap文件。该ConfigMap文件名为mindx-dl-deviceinfo-<nodename>(以下简称device-info-cm),故障信息会通过该ConfigMap进行上报。该ConfigMap文件中各字段的说明,请参见DeviceInfoCfg表。
-
当节点上存在节点故障时,每个计算节点的NodeD会创建记录本节点设备信息的ConfigMap文件。该ConfigMap文件名为mindx-dl-nodeinfo-<nodename>(以下简称node-info-cm),节点故障信息会通过该ConfigMap进行上报。该ConfigMap文件中各字段的说明,请参见mindx-dl-nodeinfo-<nodename>表。
-
ClusterD会创建记录本集群设备信息的ConfigMap文件,该ConfigMap文件名为cluster-info-<device/switch>-<[0-5]>、cluster-info-node-cm(以下简称cluster-info-cm)。节点及芯片故障信息会通过cluster-info-cm进行上报。
-
创建每个任务时,需要在YAML中配置ConfigMap文件,该ConfigMap文件名称为reset-config-<job-name>(以下简称reset-info-cm)。该ConfigMap挂载到容器的“/user/restore/reset/config”路径下。Ascend Device Plugin会自动将ConfigMap挂载到本节点的“/user/restore/reset/<job-namespace>.<job-name>”路径下。
也可以将节点上/user/restore/reset/<job-namespace>.<job-name>替代ConfigMap,挂载到容器的“/user/restore/reset/config”路径下。该ConfigMap文件字段说明,请参见reset-config-<job-name>表。
节点故障
节点故障的发现主要通过NodeD组件实现。节点故障包括节点健康状态和节点硬件故障、节点DPC共享存储故障,详细说明如下:
-
节点健康状态
NodeD完成当前节点的节点状态诊断后,收集本节点内的故障信息。当节点发生故障时,通过节点状态上报机制不断向Volcano发送节点状态(当前仅收集本节点内的硬件故障信息)。
-
节点硬件故障
针对节点硬件故障,NodeD通过IPMI驱动向iBMC发送故障查询请求,iBMC将当前硬件告警信息响应给NodeD。NodeD收集硬件告警信息后,将节点硬件状态上报给Volcano。
-
节点DPC共享存储故障
针对使用Scale-Out Storage DPC产品的节点,可以使用NodeD安装包下的noded-dpc-{version}.yaml启动NodeD服务。开启对DPC的进程异常及内存不足异常的检测和上报。
Note
当节点发生故障时,NodeD会上报节点健康状态和节点硬件故障。无故障时,默认节点健康。
- 当节点发生故障时,NodeD最短5秒(默认)更新本节点的node-info-cm内容,其中字段说明见mindx-dl-nodeinfo-<nodename>表。
- NodeD每隔60秒(默认)从iBMC查询故障信息。当查到的故障信息相比上次查到的有变化或与上次上报的时间间隔30分钟以上时,会在1秒内上报到node-info-cm中。
为保证节点故障检测功能的正常使用,需要安装以下组件:Volcano、Ascend Operator、NodeD、ClusterD
- NodeD的节点硬件故障上报能力仅支持以下产品型号:Atlas 800T A2 训练服务器、Atlas 900 A2 PoD 集群基础单元、Atlas 900 A3 SuperPoD 超节点。
- 仅V2 3.15.0.1及以上版本或者V2 3.10.02.55版本的iBMC,且安装了IPMC驱动的产品,支持NodeD的节点硬件故障上报能力。低版本的iBMC或IPMI获取节点故障信息失败时,将只上报节点健康状态。
- 如需使用超节点故障检测功能,需使用V3 5.8.3.35及以上版本的iBMC。
- 如需使用DPC故障检测功能,需使用Scale-Out Storage DPC 24.2.0及以上版本。
Job级别重调度、Pod级别重调度、进程级别重调度
断点续训针对节点故障中节点硬件故障的不同故障码,提供了默认的故障级别和对应级别的故障处理策略。若用户需要修改故障处理策略,可参见节点硬件故障。若无特殊需求,请勿随意修改。
芯片故障
芯片故障指的是NPU出现的基础软件类故障和芯片硬件类故障。断点续训特性中芯片故障的检测和上报由设备管理组件Ascend Device Plugin负责。
NPU发生故障时,故障管理框架获取到故障信息后,将该信息上传给NPU驱动的故障管理框架。故障管理框架收到故障信息后,通过DCMI接口上报给Ascend Device Plugin,如图1所示。
Ascend Device Plugin通过DCMI接口获取芯片健康状态。当前提供如下两种获取模式:
- 故障订阅模式。Ascend Device Plugin启动时会先调用DCMI故障订阅接口注册监测,故障发生时驱动通过该接口将故障事件上报给Ascend Device Plugin。故障恢复时通过该接口将恢复事件上报给Ascend Device Plugin。
- 故障轮询模式。每隔固定时间,通过故障查询接口查询芯片故障状态,当设备驱动不支持订阅能力时将切换该模式。
Ascend Device Plugin获取到芯片故障信息后,通过ConfigMap的形式上报给K8s。Ascend Device Plugin的故障上报机制如下:
对于不同故障处理模式,上报的路径会有一定差别。
-
重调度模式:Ascend Device Plugin获取到芯片故障后,将芯片故障信息写入该节点所属的device-info-cm中,其中字段说明见DeviceInfoCfg表。ClusterD读取每个节点的device-info-cm感知芯片故障并上报给调度器。
-
优雅容错模式:Ascend Device Plugin获取到可恢复的芯片故障后,将芯片故障信息写入该任务所属的reset-info-cm中,业务容器通过将reset-info-cm挂载为文件的形式,读取文件感知芯片故障。
Note
若优雅容错模式处理故障失败,回退至重调度模式后,故障上报的路径则按照重调度模式进行上报。
为保证芯片故障检测功能的正常使用,需要安装以下组件:Volcano、Ascend Operator、Ascend Device Plugin、ClusterD
断点续训针对芯片故障提供了默认的故障频率、时长、故障级别以及对应级别的故障处理策略。若用户需要修改故障处理策略,可参见芯片故障。若无特殊需求,请勿随意修改。
Job级别重调度、Pod级别重调度、进程级别重调度、进程级在线恢复、优雅容错
Note
仅片上内存出现的不可纠正错误支持进程级在线恢复,其他类型的芯片故障不支持进程级在线恢复。
参数面网络故障
NPU的参数面网络故障包括芯片网络相关故障和灵衢总线设备故障。
参数面网络出现故障时,将导致训练任务中断或者训练任务性能较差。灵衢总线设备发生故障后,MindCluster集群调度组件将根据故障级别进行相应的重调度处理。
Note
- 参数面网络故障不会直接触发任务重调度,当参数面故障导致训练任务异常中断时才触发任务重调度。
- 如果需要对参数面网络故障进行故障处理,需要同时开启业务面故障无条件重试能力。
参数面网络故障检测由设备管理组件Ascend Device Plugin负责,详细原理如图1所示。
芯片网络故障:
- NPU定时检测和网关地址的通信是否正常,探测周期为2.5秒,通过故障管理框架上报结果。
- RoCE驱动实时监测NPU网口Link状态,通过故障管理框架上报Linkdown或Linkup事件。
- Ascend Device Plugin通过DCMI接口从故障管理框架获取信息,通过轮询的方式查询网关探测结果,并实时订阅网口Linkdown或Linkup事件并进行上报。Ascend Device Plugin统计网关检测异常持续时间、Linkdown持续时间。如果小于或等于RoCE网络超时时间(默认为20秒)则标记为NPU网络故障(默认不处理,可能会引起参数面网络故障);如果大于20秒,则升级成配置的故障等级。
灵衢总线设备故障:
- 灵衢总线设备将设备发生的故障写入本地队列中。
- 灵衢查询接口通过查询上述队列,将故障缓存至查询接口,并进行汇总处理。
- Ascend Device Plugin通过订阅或轮询的方式调用接口获取灵衢总线设备相关故障,并写入device-info-cm进行上报。
-
芯片发生网络故障时,NPU故障管理框架获取故障信息后,将该信息上报给NPU驱动。NPU驱动收到故障信息后,通过DCMI接口上报给Ascend Device Plugin。Ascend Device Plugin通过DCMI接口获取芯片健康状态。当前提供如下两种获取模式:
- 故障订阅模式。Ascend Device Plugin启动时会先调用DCMI故障订阅接口注册监测,故障发生或恢复时,驱动通过该接口将故障发生或恢复事件上报给Ascend Device Plugin。
- 故障轮询模式。每隔固定时间,通过故障查询接口查询芯片故障状态。当设备驱动不支持订阅能力时将切换该模式。
-
灵衢总线设备发生故障时,Ascend Device Plugin通过灵衢查询接口获取故障信息,当前故障查询提供两种模式:
- 故障订阅模式:在Ascend Device Plugin启动过程中向灵衢查询接口注册故障处理回调。故障发生后,该回调被调用后将故障上报给Ascend Device Plugin,故障恢复时通过该接口上报恢复事件。
- 故障轮询模式:Ascend Device Plugin每隔5分钟调用一次全量故障查询接口。
Ascend Device Plugin获取到参数面网络故障后,将故障信息写入到device-info-cm中,并通过ConfigMap的形式上报给K8s。device-info-cm中各字段的说明,请参见DeviceInfoCfg表。
Ascend Device Plugin的故障上报机制如图2所示。
参数面网络链路异常(参数面网络故障)可能导致任务中正常NPU无法与故障NPU通信,使所有NPU集合通信陷入超时等待状态;并使任务集合通信出现等待超时异常后才退出(默认为30分钟)。
开启watchdog功能(且开启了业务面故障无条件重试能力)可以在参数面网络链路异常发生后,隔离故障NPU,将任务重调度到健康的NPU上,从而实现6分钟内使任务快速退出。
Note
仅支持在PyTorch及MindSpore框架下使用watchdog功能。
为保证参数面网络故障检测功能的正常使用,需要安装以下组件:Volcano、Ascend Operator、Ascend Device Plugin、ClusterD
Job级别重调度、Pod级别重调度、进程级别重调度
断点续训针对参数面故障提供了默认的故障级别以及对应级别的故障处理策略,若用户需要修改故障处理策略可参见参数面网络故障。若无特殊需求,请勿随意修改。
业务面故障
断点续训特性支持通过Volcano调度器感知并处理因业务面故障导致的任务失败。业务面故障是因容器内的训练进程均异常退出后引起容器异常退出,导致Pod的Status变为Failed状态。在使用Ascend Operator的场景下,业务面故障仅支持任务的部分Pod发生故障的场景,若任务所有Pod在几秒内Status都转变为Failed,任务不会发生重调度,认定任务为失败状态。
业务面故障发现原理如图1所示。
调度器不断轮询地查询每个任务的Pod状态,从而感知到业务面故障并上报该故障。用户可根据具体业务需求对业务面故障做处理。断点续训获取到业务面故障后,Volcano会检测是否开启无条件重试功能,开启后会将任务重新调度到未导致本次训练任务重调度的新节点,并重新执行训练任务,重试次数减1;当重试次数为0或者没有开启无条件重试功能时,不会对业务容器故障进行处理。
Note
- 如需使用无条件重试功能,需在任务YAML中配置以下3个参数:fault-retry-times,restartPolicy及policies,详细参数说明请参见YAML参数说明(policies 是 vcjob 原生字段)。
- 在使用Ascend Operator的场景下,若希望任务所有Pod的Status在转变为Failed后仍发生重调度,可参考使用Volcano和Ascend Operator组件场景下,业务面故障的任务所有Pod的Status全部变为Failed,任务无法触发无条件重试重调度。
NPU上Task执行异常(业务面故障)可能导致任务中正常NPU无法与故障NPU通信,使正常NPU集合通信陷入超时等待状态,任务集合通信出现等待超时异常后才退出(默认为30分钟)。开启watchdog功能(需同时开启业务面故障无条件重试能力),可以在该异常发生后,隔离故障NPU,将任务重调度到健康的NPU上,从而实现6分钟内使任务快速退出。
Note
NPU上Task执行异常仅支持Atlas A2 训练系列产品的PyTorch框架使用watchdog功能。
为保证业务面故障检测功能的正常使用,需要安装以下组件:Volcano、Ascend Operator
Job级别重调度、Pod级别重调度、进程级别重调度、优雅容错
公共故障
公共故障指的是其他故障发送方(非MindCluster组件)上报的故障,公共故障包括以下几种类型:NPU故障、节点故障、网络故障和存储故障。
Note
ClusterD支持接收公共故障的前提是需要在节点上安装Ascend Device Plugin,并且生成了相应的device-info-cm。
公共故障发送方发现故障后,将通过ConfigMap或gRPC方式,将获取到的故障信息发送给ClusterD。ClusterD会将接收到的信息进行汇总写入cluster-info-device-cm,再上报给Ascend-volcano-plugin。
- 通过ConfigMap获取。故障发现者将故障信息写入ConfigMap中,然后由ClusterD获取故障信息。用户可通过调用ConfigMap接口的方式来注入公共故障,详细说明请参见ConfigMap。
- 通过gRPC获取。故障发现者将故障信息通过gRPC通道发送给ClusterD,然后由ClusterD获取故障信息。用户可通过调用gRPC接口的方式来注入公共故障,说明请参见gRPC接口。
为保证公共故障检测功能的正常使用,需要安装以下组件。
- 必选组件:Volcano、Ascend Operator、Ascend Device Plugin、ClusterD
- 可选组件:NodeD
Job级别重调度、Pod级别重调度、进程级别重调度
断点续训针对公共故障提供了默认的故障级别以及支持的故障发送方。若用户需要修改公共故障的级别及故障发送方,可参见公共故障。若无特殊需求,请勿随意修改。
pingmesh灵衢网络故障
灵衢网络故障是针对超节点内部(包括节点内和节点间)的HCCS网络提供的NPU网络故障检测。
NodeD调用DCMI接口启动pingmesh任务,并周期性查询pingmesh结果,将该结果写入文件<nodename>.log。该文件所在目录在容器中为固定路径:/user/mind-cluster/pingmesh,物理机默认目录/user/mind-cluster/pingmesh。物理机路径可以修改,修改方式如以下说明所示。
Note
- <nodename>非固定值,为K8s中查询到的节点名称。
- <nodename>.log文件物理机路径可由用户根据实际情况自行配置:在NodeD的启动YAML中修改挂载卷名称为pingmesh-result的物理机挂载路径。
获取pingmesh结果后,ClusterD会对结果进行初步分析,将故障信息写入到名为pingmesh-fault-<nodename>的ConfigMap文件中。ClusterD会侦听该ConfigMap信息,并将故障汇总后上报给Volcano,由Volcano进行调度。
- (必选)已创建命名空间
- 在相应节点上完成以下组件的安装:NodeD(必选)、Ascend Device Plugin(可选)、ClusterD(可选)
- (必选)已配置NodeD启动参数resultMaxAge
本功能仅支持在以下产品型号中使用:Atlas 900 A3 SuperPoD 超节点。
配置灵衢网络检测,需执行以下步骤。
-
配置共享存储。
ClusterD和NodeD通过共享存储进行交互,两者的共享存储根路径需要保持一致。共享目录的根路径属主为9000用户,与ClusterD运行用户一致。
-
配置server。

-
修改NodeD配置。

-
如果存在ClusterD,则需修改ClusterD配置。

-
执行kubectl get pods -o wide -A命令出现如下示例,则表示已完成共享存储配置。

-
-
启用或关闭灵衢网络检测。
-
(推荐)已安装Ascend Device Plugin和ClusterD
-
登录环境,进入NodeD解压目录。
-
执行以下命令创建名为pingmesh-config的ConfigMap文件。
pingmesh-config.yaml为pingmesh配置文件,可从NodeD安装包中获取。
kubectl apply -f pingmesh-config.yaml回显示例如下。
configmap/pingmesh-config created -
执行以下命令编辑pingmesh-config文件。该文件中各参数的填写说明如表1所示。
kubectl edit cm -n cluster-system pingmesh-config表 1 pingmesh-config cm
参数 说明 取值 app ConfigMap其中一个label的key。 pingmesh global 集群配置信息。 - "1" 超节点ID为1的配置示例,用户可根据实际情况进行修改或新增。当配置了某个超节点后,NodeD会采用超节点的配置信息而忽略global配置信息。 超节点ID activate 是否启用pingmesh功能。 on或off task_interval pingmesh任务间隔。单位为秒。 [1~60]
-
-
未安装Ascend Device Plugin和ClusterD
自行生成名为cluster-system的命名空间,name为super-pod-<superPodID>、label为app=pingmesh的ConfigMap。且该ConfigMap中各字段需按照super-pod-<super-pod-id>表填写。示例如下。
apiVersion: v1 data: superPodDevice: '{"SuperPodID":"0","NodeDeviceMap":{"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"62914560","1":"62980097","10":"64225290","11":"64290827","12":"64487436","13":"64552973","14":"64749582","15":"64815119","2":"63176706","3":"63242243","4":"63438852","5":"63504389","6":"63700998","7":"63766535","8":"63963144","9":"64028681"}},"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"67108864","1":"67174401","10":"68419594","11":"68485131","12":"68681740","13":"68747277","14":"68943886","15":"69009423","2":"67371010","3":"67436547","4":"67633156","5":"67698693","6":"67895302","7":"67960839","8":"68157448","9":"68222985"}},"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"104857600","1":"104923137","10":"106168330","11":"106233867","12":"106430476","13":"106496013","14":"106692622","15":"106758159","2":"105119746","3":"105185283","4":"105381892","5":"105447429","6":"105644038","7":"105709575","8":"105906184","9":"105971721"}},"node-**-*":{"NodeName":"node-**-*","DeviceMap":{"0":"4194304","1":"4259841","10":"5505034","11":"5570571","12":"5767180","13":"5832717","14":"6029326","15":"6094863","2":"4456450","3":"4521987","4":"4718596","5":"4784133","6":"4980742","7":"5046279","8":"5242888","9":"5308425"}},"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"142606336","1":"142671873","10":"143917066","11":"143982603","12":"144179212","13":"144244749","14":"144441358","15":"144506895","2":"142868482","3":"142934019","4":"143130628","5":"143196165","6":"143392774","7":"143458311","8":"143654920","9":"143720457"}},"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"146800640","1":"146866177","10":"148111370","11":"148176907","12":"148373516","13":"148439053","14":"148635662","15":"148701199","2":"147062786","3":"147128323","4":"147324932","5":"147390469","6":"147587078","7":"147652615","8":"147849224","9":"147914761"}},"node-**-**":{"NodeName":"node-**-**","DeviceMap":{"0":"83886080","1":"83951617","10":"85196810","11":"85262347","12":"85458956","13":"85524493","14":"85721102","15":"85786639","2":"84148226","3":"84213763","4":"84410372","5":"84475909","6":"84672518","7":"84738055","8":"84934664","9":"85000201"}}}}' kind: ConfigMap metadata: labels: app: pingmesh name: super-pod-0 # 0为超节点ID namespace: cluster-system
-
Note
检测结果查询周期为配置参数“task_interval”的10倍。
灵衢网络检测的pingmesh结果写入文件<nodename>.log中。该文件中各字段的详细说明如下表所示。
表 2 <nodename>.log
| 参数 | 说明 | 取值 |
|---|---|---|
| uid | 该次pingmesh任务的ID。 | 长度为64的字符串 |
| config | 该次pingmesh任务的用户配置。 | 字符串 |
| physicID | NPU卡物理ID。 | [0~15] |
| taskID | 任务ID,0代表节点内部、1代表节点间。 | 0或1 |
| DestNum | 本次pingmesh目标地址数量。 | [0~47] |
| source_addr | 源地址 | IPv4网络地址 |
| target_addr | 目标地址 | IPv4网络地址 |
| suc_pkt_num | 发送成功的包数量。 | - |
| fail_pkt_num | 发送失败的包数量。 | - |
| max_time | 最长响应时间。 |
|
| min_time | 最短响应时间。 |
|
| avg_time | 平均响应时间。 |
|
| tp95_time | 处于95%位置的响应时间。 |
|
| reply_stat_num | 本次查询到的响应数量。 | - |
| ping_total_num | 本次任务累计的响应数量。 | - |
在管理节点上执行以下命令,查看灵衢网络检测的故障信息。
kubectl describe cm -n cluster-system pingmesh-fault-<nodename>
故障信息中各字段的详细说明如下所示。
表 3 pingmesh-fault-<nodename>
| 参数 | 说明 | 取值 |
|---|---|---|
| mc-consumer-publicfault | ClusterD侦听所需的label key | true |
| PublicFault | 公共故障信息key | 详细说明请参见fault字段说明表。 |
| 故障码 | 故障说明 | 故障级别 |
|---|---|---|
| 220001001 | NPU卡HCCS网络故障 | SeparateNPU 该故障级别不支持自行配置。 |
性能劣化故障
使用7.1.RC1及以上版本TaskD
MindCluster集群调度组件结合MindStudio提供的profiling能力,对集群中的性能劣化故障(慢节点)提供诊断功能。该功能提供动态打点和打点数据持久化功能、可动态启停训练任务打点功能,无需重启任务进行诊断,对训练无损耗。
当前支持的打点数据如表1所示。
表 1 打点数据说明
| 打点数据的类型 | 支持的AI框架 | 提供支持的组件 |
|---|---|---|
FP (标识前向传播数据) |
PyTorch 仅支持单算子场景。 |
mstx_torch_plugin |
Step (标识Step时延) |
PyTorch、MindSpore |
|
Communication (标识通信算子) |
PyTorch、MindSpore |
|
SaveCheckpoint (标识SaveCheckpoint耗时) |
PyTorch、MindSpore |
|
DataLoader (标识DataLoader耗时) |
PyTorch、MindSpore |
|
- 当前Step、SaveCheckpoint、FP、DataLoader仅支持同步开启。如需关闭以上四类打点数据,需同时关闭Communication。
- Communication通信算子数据支持单独开启、关闭。
- 动态轻量打点功能与MindStudio的全量打点功能不可同时开启,开启全量打点功能会导致性能劣化故障不能正常采集数据。
- (可选)已安装ClusterD、Ascend Device Plugin和Volcano(以上MindCluster组件版本均需与TaskD配套)
- 在容器内安装torch_npu(可选,PyTorch场景需安装、版本号≥7.1.RC1)、MindSpore(可选,MindSpore场景需安装、版本号≥2.7.0)、CANN(必选,版本号≥8.2.RC1)、TaskD(必选)
表 2 准备软件包
| 软件包 | 是否必选 | 说明 | 获取方法 | 使用场景 |
|---|---|---|---|---|
| mstx_torch_plugin | 否 | Ascend PyTorch Profiler中的采集并解析msproftx数据功能已经内置了通信算子的打点。为了方便用户在不修改业务代码的基础上获取更多关键阶段的耗时数据,mstx_torch_plugin在Ascend PyTorch Profiler内置了dataloader、forward、step、save_checkpoint这四个关键阶段函数的打点。
|
获取链接 | PyTorch |
本方案仅针对7.1.RC1及以上版本的TaskD组件。如使用7.1.RC1以下版本的组件请参见使用其他版本TaskD章节进行操作。
-
PyTorch场景
-
以下两种方式请根据实际需要进行二选一。
-
在容器内安装mstx_torch_plugin。
-
下载mstx_torch_plugin的whl包。whl包链接:mstx_torch_plugin。
-
安装软件包。
pip install mstx_torch_plugin-1.0-py3-none-any.whl -
在AI任务执行脚本中import导入该whl包。
需保证import的顺序在import torch和import torch_npu后面,示例如下。
import torch import torch_npu import mstx_torch_plugin
-
-
非原生优化器或不使用mstx_torch_plugin的情况下,为获取训练的Step耗时数据需修改训练脚本中的训练迭代循环,需增加Step打点代码。
以下示例为PyTorch-MindSpeed场景,需修改./mindspeed_llm/training/training.py文件,增加如下加粗字段。
def train(forward_step_func, model, optimizer, opt_param_scheduler, train_data_iterator, valid_data_iterator, process_non_loss_data_func, config): # Cache into one-logger for callback …… …… if is_profile_enabled(): prof = get_profiler() prof.start() step_id = iteration while iteration < args.train_iters: stream = torch.npu.current_stream() # 获取当前环境的执行流,用于获取NPU侧时间 range_id = torch.npu.mstx.range_start(f"step {step_id}", stream) # 标识当前训练step的开始 …… …… if args.manual_gc: if args.manual_gc_interval != 0 and iteration % args.manual_gc_interval == 0: gc.collect() if is_profile_enabled(): prof.step() step_id +=1 # 训练step加一,用于标识下一step torch.npu.mstx.range_end(range_id) # 标识当前训练step的结束
-
-
在容器内,以CANN软件包的运行用户登录环境,执行source ${install_path}/set_env.sh命令设置环境变量。其中${install_path}为CANN软件的安装目录。示例如下。
source /usr/local/Ascend/cann/set_env.sh -
训练启动前,在训练脚本中导入LD_PRELOAD环境变量。该环境变量允许系统提前加载指定的so文件。示例如下。
export LD_PRELOAD=/usr/local/Ascend/cann/lib64/libmspti.so:/usr/local/python3.10.5/lib/python3.10/site-packages/taskd/python/cython_api/libs/libtaskd.so-
libmspti.so:该so由MindStudio提供,集成在CANN包内。当使用默认安装路径时,路径为:/usr/local/Ascend/cann/lib64/libmspti.so。
-
libtaskd.so:该so由TaskD组件提供,安装该whl包后,路径为:TaskD所在路径/taskd/python/cython_api/libs/libtaskd.so。
TaskD所在路径可通过以下命令进行查询。回显中的Location字段即为TaskD所在路径。
pip show taskd
-
-
在分布式环境初始化完成,能够获取到全局rank之后,修改训练脚本,在训练脚本中拉起TaskD Manager,在管理进程中拉起TaskD Proxy,在训练进程内部拉起TaskD Worker。
-
(可选)拉起TaskD Manager和TaskD Proxy。若通过gRPC接口方式开启轻量profiling获取落盘数据,则需执行如下步骤;若通过ConfigMap方式开启轻量profiling获取落盘数据,则跳过该步骤。
-
创建manager.py文件,放在调用训练脚本时的当前目录下。manager.py文件内容如下所示。
from taskd.api import init_taskd_manager, start_taskd_manager import os job_id=os.getenv("MINDX_TASK_ID") node_nums=XX # 用户填入任务节点总数 proc_per_node=XX # 用户填入任务每个节点的训练进程数量 init_taskd_manager({"job_id":job_id, "node_nums": node_nums, "proc_per_node": proc_per_node}) start_taskd_manager()Note
manager.py文件中的参数详细说明请参见def init_taskd_manager(config:dict) -> bool:。
-
在训练脚本中增加以下代码,拉起TaskD Manager和TaskD Proxy。
sed -i '/import os/i import taskd.python.adaptor.patch' $(pip3 show torch | grep Location | awk -F ' ' '{print $2}')/torch/distributed/run.py if [[ "${RANK}" -eq 0 ]]; then export MASTER_ADDR=${POD_IP} python /job/code/manager.py 2>> /job/code/alllogs/$MINDX_TASK_ID/taskd/error.log & # manager.py具体执行路径由当前路径决定,error.log日志路径需提前创建 fi torchrun ...
-
-
以下示例为PyTorch-MindSpeed场景,需修改QWEN3_for_PyTorch_2.7_code/mindspeed_llm/training/training.py文件,在代码中增加如下加粗字段。
def pretrain(train_valid_test_dataset_provider, model_provider, model_type, forward_step_func, process_non_loss_data_func=None, extra_args_provider=None, args_defaults={}): print_rank_0('time to initialize megatron (seconds): {:.3f}'.format( time.time() - _TRAIN_START_TIME)) print_datetime('after megatron is initialized') import torch.distributed as dist if dist.is_initialized(): rank = dist.get_rank() from taskd.api.taskd_worker_api import init_taskd_worker from taskd.api.taskd_worker_api import start_taskd_worker init_taskd_worker(rank,5000) start_taskd_worker() app_metrics['app_model_init_finish_time'] = one_logger_utils.get_timestamp_in_ms() one_logger_utils.on_pretrain_start()Note
以上代码init_taskd_worker(rank,5000)中的入参5000为/user/cluster-info/profiling的上限大小,详细说明请参见def init_taskd_worker(rank_id: int, upper_limit_of_disk_in_mb: int = 5000, framework: str = "pt") -> bool中“upper_limit_of_disk_in_mb”参数。
-
-
-
修改容器端口,在所有的Pod下增加TaskD通信使用的端口9601。
... spec: ... containers: ... ports: - containerPort: 9601 name: taskd-port ... -
挂载文件。
- 挂载轻量profiling配置文件:需将宿主机上任务对应的data-trace ConfigMap落盘到/user/cluster-info/datatrace-config/命名空间.data-trace-任务名称/文件夹下。将名为profilingSwitch的文件挂载到容器指定路径:/user/cluster-info/datatrace-config/。
- 挂载轻量profiling落盘文件:轻量profiling数据写在容器内的/user/cluster-info/profiling路径下。如需在宿主机获取,请修改任务YAML,将该路径挂出。
-
容器内YAML挂载示例如下。
volumeMounts: - name: profilingdata mountPath: /user/cluster-info/ - name: profileswitch mountPath: /user/cluster-info/datatrace-config -
宿主机内YAML挂载示例如下。
volumes: - name: profileswitch hostPath: path: /user/cluster-info/datatrace-config/default.data-trace-default-test-pytorch-fault-mixtral - name: profilingdata hostPath: path: /home/profilingdatapath
-
-
-
-
修改ClusterD提供的gRPC接口:若配置了4.a,需要使用该方式开启。详细接口信息请参见ModifyTrainingDataTraceSwitch。
Note
通过ClusterD提供的gRPC接口开启或修改轻量profiling获取落盘数据,创建的data-trace-<任务名称> ConfigMap的生命周期会随着任务的删除而删除。当任务不存在时,该接口会调用失败。
-
修改任务对应的data-trace ConfigMap:若未配置4.a,需要使用该方式开启。具体操作步骤如下:
以default命名空间下的名为default-test-pytorch-fault-mixtral的任务为例,以编辑ConfigMap的方式开启轻量profiling获取落盘数据,示例如下。
-
在master节点执行以下命令查询该任务对应的配置ConfigMap。
kubectl get cm -
执行以下命令,创建配置轻量profiling获取落盘数据所需ConfigMap文件。
-
将以下内容写入datacm.yaml。
apiVersion: v1 kind: ConfigMap metadata: name: data-trace-default-test-pytorch-fault-mixtral # cm的名字需以data-trace为前缀+任务名 labels: reset: "true" data: profilingSwitch: '{"CommunicationOperator":"off","Step":"on","SaveCheckpoint":"on","FP":"on","DataLoader":"on"}' -
在master节点执行以下命令,创建ConfigMap。
kubectl apply -f datacm.yaml回显如下所示,表示ConfigMap创建成功。
configmap/data-trace-default-test-pytorch-fault-mixtral created
-
-
kubectl edit cm data-trace-default-test-pytorch-fault-mixtral -
如需开启通信算子,请将CommunicationOperator字段的取值改为“on”。
apiVersion: v1 data: profilingSwitch: '{"CommunicationOperator":"on","Step":"on","SaveCheckpoint":"on","FP":"on","DataLoader":"on"}'Note
开启通信算子后可能造成训练性能下降,不建议常态开启通信算子。
-
按“Esc”键,输入:wq!保存并退出。
-
-
-
-
MindSpore场景
-
在容器内,以CANN软件包的运行用户登录环境,执行source ${install_path}/set_env.sh命令设置环境变量。其中${install_path}为CANN软件的安装目录。示例如下。
source /usr/local/Ascend/cann/set_env.sh -
训练启动前,在训练脚本中导入LD_PRELOAD环境变量。该环境变量允许系统提前加载指定的so文件。示例如下。
export LD_PRELOAD=/usr/local/Ascend/cann/lib64/libmspti.so:/usr/local/python3.10.5/lib/python3.10/site-packages/taskd/python/cython_api/libs/libtaskd.so-
libmspti.so:该so由MindStudio提供,集成在CANN包内。当使用默认安装路径时,路径为:/usr/local/Ascend/cann/lib64/libmspti.so。
-
libtaskd.so:该so由TaskD组件提供,安装该whl包后,路径为:TaskD所在路径/taskd/python/cython_api/libs/libtaskd.so。
TaskD所在路径可通过以下命令进行查询。回显中的Location字段即为TaskD所在路径。
pip show taskd
-
-
在分布式环境初始化完成,能够获取到全局rank之后,修改训练脚本,在训练脚本中拉起TaskD Manager,在管理进程中拉起TaskD Proxy,在训练进程内部拉起TaskD Worker。
-
(可选)拉起TaskD Manager和TaskD Proxy。若通过gRPC接口方式开启轻量profiling获取落盘数据,则需执行如下步骤;若通过ConfigMap方式开启轻量profiling获取落盘数据,则跳过该步骤。
-
创建manager.py文件,放在调用训练脚本时的当前目录下,manager.py文件内容如下所示。
from taskd.api import init_taskd_manager, start_taskd_manager import os job_id=os.getenv("MINDX_TASK_ID") node_nums=XX # 用户填入任务节点总数 proc_per_node=XX # 用户填入任务每个节点的训练进程数量 init_taskd_manager({"job_id":job_id, "node_nums": node_nums, "proc_per_node": proc_per_node}) start_taskd_manager()Note
manager.py文件中的参数详细说明请参见def init_taskd_manager(config:dict) -> bool:。
-
在训练脚本中增加以下代码拉起TaskD Manager。
if [[ "${MS_SCHED_HOST}" -eq "${POD_IP}" ]]; then python /job/code/manager.py 2>> /job/code/alllogs/$MINDX_TASK_ID/taskd/error.log & # manager.py具体执行路径由当前路径决定,error.log日志路径需提前创建 fi msrun ... -
修改mindspore/python/mindspore/parallel/cluster/process_entity/_api.py文件,拉起TaskD Proxy。示例如下。
... if ("TTP:1" in tft_env) or ("UCE:1" in tft_env) or ("ARF:1" in tft_env): try: from taskd.python.framework.agent.ms_mgr.msrun_plugin import MSRunPlugin from taskd.api.taskd_proxy_api import init_taskd_proxy from taskd.python.framework.common.type import CONFIG_UPSTREAMIP_KEY, LOCAL_HOST import threading proxy = threading.Thread(target=init_taskd_proxy, args=({CONFIG_UPSTREAMIP_KEY : os.getenv("MS_SCHED_HOST", LOCAL_HOST)},)) proxy.daemon = True proxy.start() self.msmgr = MSRunPlugin() self.msmgr.register_callbacks("KILL_WORKER", self.kill_workers) self.msmgr.register_callbacks("START_ALL_WORKER", self.start_all_workers) self.msmgr.register_callbacks("START_WORKER_LIST", self.start_worker_list) self.msmgr.register_callbacks("MONITOR", self.monitor_rank_status) self.enable_mindx = True os.environ["MS_ENABLE_RECOVERY"] = str(1) ...
-
-
以下示例为MindSpore-MindFormers场景,需修改./mindformers/trainer/base_trainer.py文件,在代码中增加如下加粗字段。
def training_process( self, config: Optional[Union[dict, MindFormerConfig, ConfigArguments, TrainingArguments]] = None, network: Optional[Union[Cell, PreTrainedModel]] = None, dataset: Optional[Union[BaseDataset, GeneratorDataset]] = None, optimizer: Optional[Optimizer] = None, callbacks: Optional[Union[Callback, List[Callback]]] = None, compute_metrics: Optional[Union[dict, set]] = None, **kwargs): …… …… logger.info(".........Starting Training Model..........") if get_real_rank() % 8 == 0: pprint(config) logger.info(".........Model Compiling, Please Wait a Moment...........") try: rank = get_rank() from taskd.api.taskd_worker_api import init_taskd_worker from taskd.api.taskd_worker_api import start_taskd_worker init_taskd_worker(rank,5000) start_taskd_worker() except Exception as e: print("failed to call mindcluster taskd") model.train(config.runner_config.epochs, dataset, callbacks=callbacks, dataset_sink_mode=config.runner_config.sink_mode, sink_size=config.runner_config.sink_size, initial_epoch=config.runner_config.initial_epoch)Note
以上代码init_taskd_worker(rank,5000)中的入参5000为/user/cluster-info/profiling的上限大小,详细说明请参见def init_taskd_worker(rank_id: int, upper_limit_of_disk_in_mb: int = 5000, framework: str = "pt") -> bool中“upper_limit_of_disk_in_mb”参数。
-
-
修改任务YAML。详细请参见PyTorch场景的步骤5。
-
开启轻量profiling获取落盘数据。详细请参见PyTorch场景的步骤6。
-
-
落盘数据按rank进行分类,轻量profiling数据写在容器内的/user/cluster-info/profiling路径。
-
对于存在环境变量MINDX_TASK_ID的Pod,rank 0数据在容器内的路径为/user/cluster-info/profiling/$MINDX_TASK_ID/0。
Note
- 如无该环境变量,默认会落盘到名为default_task_id_时间戳的文件夹内。
- /user/cluster-info/profiling达到配置的上限大小(PyTorch场景参考4.b;MindSpore场景参考3.b)后,将进行文件老化,默认每次删除修改时间最早的20%个文件。老化过程中仅删除profiling目录下rank文件夹中的以数字命名的文件,建议不手动添加其他文件到profiling文件夹下。如果用户手动添加其他文件,TaskD不会将该文件删除,但该文件会占用空间。
- 轻量profiling文件以时间戳命名,各条记录以换行分割,每次追加写入rank下最新文件。最新文件大小超过10MB时,TaskD会新建profiling文件。如果使用NFS等网络存储方式,当数据同步较慢时,可能存在文件大小未达到10MB即创建新文件的情况。
使用其他版本TaskD
MindCluster集群调度组件结合MindStudio提供的profiling能力,对集群中的性能劣化故障(慢节点)提供诊断功能。该功能提供动态打点和打点数据持久化功能、可动态启停训练任务打点功能,无需重启任务进行诊断,对训练无损耗。
当前支持的打点数据如表1所示。
表 1 打点数据说明
| 打点数据的类型 | 支持的AI框架 | 提供支持的组件 |
|---|---|---|
FP (标识前向传播数据) |
PyTorch 仅支持单算子场景。 |
mstx_torch_plugin |
Step (标识Step时延) |
PyTorch、MindSpore |
|
Communication (标识通信算子) |
PyTorch、MindSpore |
|
SaveCheckpoint (标识SaveCheckpoint耗时) |
PyTorch、MindSpore |
|
DataLoader (标识DataLoader耗时) |
PyTorch、MindSpore |
|
- 当前Step、SaveCheckpoint、FP、DataLoader仅支持同步开启。如需关闭以上四类打点数据,需同时关闭Communication。
- Communication通信算子数据支持单独开启、关闭。
- 动态轻量打点功能与MindStudio的全量打点功能不可同时开启,开启全量打点功能会导致性能劣化故障不能正常采集数据。
- (可选)已安装ClusterD、Ascend Device Plugin和Volcano(以上MindCluster组件版本均需与TaskD配套)
- 在容器内安装torch_npu(可选,PyTorch场景需安装、版本号≥7.0.0)、MindSpore(可选,MindSpore场景需安装、版本号≥2.6.RC1)、CANN(必选,版本号≥8.1.RC1)、TaskD(必选,版本号≥7.0.RC1)
表 2 准备软件包
| 软件包 | 是否必选 | 说明 | 获取方法 | 使用场景 |
|---|---|---|---|---|
| mstx_torch_plugin | 否 | Ascend PyTorch Profiler中的采集并解析msproftx数据功能已经内置了通信算子的打点。为了方便用户在不修改业务代码的基础上获取更多关键阶段的耗时数据,mstx_torch_plugin在Ascend PyTorch Profiler内置了dataloader、forward、step、save_checkpoint这四个关键阶段函数的打点。
|
获取链接 | PyTorch |
本方案仅针对7.1.RC1以下版本的TaskD组件。如使用7.1.RC1及以上版本的组件请参见使用7.1.RC1及以上版本TaskD章节。
-
PyTorch场景
-
(可选)在容器内安装mstx_torch_plugin。
-
下载mstx_torch_plugin的whl包。whl包链接:mstx_torch_plugin。
-
安装软件包。
pip install mstx_torch_plugin-1.0-py3-none-any.whl -
在AI任务执行脚本中import导入该whl包。
需保证import的顺序在import torch和import torch_npu后面,示例如下。
import torch import torch_npu import mstx_torch_plugin
-
-
(可选)非原生优化器或不使用mstx_torch_plugin的情况下,为获取训练的Step耗时数据需修改训练脚本中的训练迭代循环,需增加Step打点代码。
以下示例为PyTorch-MindSpeed场景,需修改./mindspeed_llm/training/training.py文件,增加如下加粗字段。
def train(forward_step_func, model, optimizer, opt_param_scheduler, train_data_iterator, valid_data_iterator, process_non_loss_data_func, config): # Cache into one-logger for callback …… …… if is_profile_enabled(): prof = get_profiler() prof.start() step_id = iteration while iteration < args.train_iters: stream = torch.npu.current_stream() # 获取当前环境的执行流,用于获取NPU侧时间 range_id = torch.npu.mstx.range_start(f"step {step_id}", stream) # 标识当前训练step的开始 …… …… if args.manual_gc: if args.manual_gc_interval != 0 and iteration % args.manual_gc_interval == 0: gc.collect() if is_profile_enabled(): prof.step() step_id +=1 # 训练step加一,用于标识下一step torch.npu.mstx.range_end(range_id) # 标识当前训练step的结束 -
在容器内,以CANN软件包的运行用户登录环境,执行source ${install_path}/set_env.sh命令设置环境变量。其中${install_path}为CANN软件的安装目录。示例如下。
source /usr/local/Ascend/cann/set_env.sh -
训练启动前,在训练脚本中导入LD_PRELOAD环境变量。该环境变量允许系统提前加载指定的so文件。示例如下。
export LD_PRELOAD=/usr/local/Ascend/cann/lib64/libmspti.so:/usr/local/python3.10.5/lib/python3.10/site-packages/taskd/python/cython_api/libs/libtaskd.so-
libmspti.so:该so由MindStudio提供,集成在CANN包内。当使用默认安装路径时,路径为:/usr/local/Ascend/cann/lib64/libmspti.so。
-
libtaskd.so:该so由TaskD组件提供,安装该whl包后,路径为:TaskD所在路径/taskd/python/cython_api/libs/libtaskd.so。
TaskD所在路径可通过以下命令进行查询。回显中的Location字段即为TaskD所在路径。
pip show taskd
-
-
在分布式环境初始化完成,能够获取到全局rank之后,修改训练脚本,在训练进程内部拉起TaskD Worker。
以下示例为PyTorch-MindSpeed场景,需修改QWEN3_for_PyTorch_2.7_code/mindspeed_llm/training/training.py文件,在代码中增加如下加粗字段。
def pretrain(train_valid_test_dataset_provider, model_provider, model_type, forward_step_func, process_non_loss_data_func=None, extra_args_provider=None, args_defaults={}): print_rank_0('time to initialize megatron (seconds): {:.3f}'.format( time.time() - _TRAIN_START_TIME)) print_datetime('after megatron is initialized') import torch.distributed as dist if dist.is_initialized(): rank = dist.get_rank() from taskd.api.taskd_worker_api import init_taskd_worker from taskd.api.taskd_worker_api import start_taskd_worker init_taskd_worker(rank,5000) start_taskd_worker() app_metrics['app_model_init_finish_time'] = one_logger_utils.get_timestamp_in_ms() one_logger_utils.on_pretrain_start()Note
以上代码init_taskd_worker(rank,5000)中的入参5000为/user/cluster-info/profiling的上限大小,详细说明请参见def init_taskd_worker(rank_id: int, upper_limit_of_disk_in_mb: int = 5000, framework: str = "pt") -> bool中“upper_limit_of_disk_in_mb”参数。
-
- 挂载轻量profiling配置文件:需将宿主机上任务对应的data-trace ConfigMap落盘到/user/cluster-info/datatrace-config/命名空间.data-trace-任务名称/文件夹下。将名为profilingSwitch的文件挂载到容器指定路径:/user/cluster-info/datatrace-config/。
- 挂载轻量profiling落盘文件:轻量profiling数据写在容器内的/user/cluster-info/profiling路径下。如需在宿主机获取,请修改任务YAML,将该路径挂出。
-
容器内YAML挂载示例如下。
volumeMounts: - name: profilingdata mountPath: /user/cluster-info/ - name: profileswitch mountPath: /user/cluster-info/datatrace-config -
宿主机内YAML挂载示例如下。
volumes: - name: profileswitch hostPath: path: /user/cluster-info/datatrace-config/default.data-trace-default-test-pytorch-fault-mixtral - name: profilingdata hostPath: path: /home/profilingdatapath
-
-
开启轻量profiling获取落盘数据。修改任务对应的data-trace ConfigMap或ClusterD提供的gRPC接口,接口信息见ModifyTrainingDataTraceSwitch,动态开启或关闭轻量profiling能力。
以default命名空间下的名为default-test-pytorch-fault-mixtral的任务为例,以编辑ConfigMap的方式开启轻量profiling获取落盘数据,示例如下。
-
在master节点执行以下命令查询该任务对应的配置ConfigMap。
kubectl get cm -
执行以下命令,创建配置轻量profiling获取落盘数据所需ConfigMap文件。
-
将以下内容写入datacm.yaml。
apiVersion: v1 kind: ConfigMap metadata: name: data-trace-default-test-pytorch-fault-mixtral # cm的名字需以data-trace为前缀+任务名 labels: reset: "true" data: profilingSwitch: '{"CommunicationOperator":"off","Step":"on","SaveCheckpoint":"on","FP":"on","DataLoader":"on"}' -
在master节点执行以下命令,创建ConfigMap。
kubectl apply -f datacm.yaml回显如下所示,表示ConfigMap创建成功。
configmap/data-trace-default-test-pytorch-fault-mixtral created
-
-
kubectl edit cm data-trace-default-test-pytorch-fault-mixtral -
如需开启通信算子,请将CommunicationOperator字段的取值改为“on”。
apiVersion: v1 data: profilingSwitch: '{"CommunicationOperator":"on","Step":"on","SaveCheckpoint":"on","FP":"on","DataLoader":"on"}'Note
开启通信算子后可能造成训练性能下降,不建议常态开启通信算子。
-
按“Esc”键,输入:wq!保存并退出。
-
-
-
MindSpore场景
-
在容器内,以CANN软件包的运行用户登录环境,执行source ${install_path}/set_env.sh命令设置环境变量。其中${install_path}为CANN软件的安装目录。示例如下。
source /usr/local/Ascend/cann/set_env.sh -
训练启动前,在训练脚本中导入LD_PRELOAD环境变量。该环境变量允许系统提前加载指定的so文件。示例如下。
export LD_PRELOAD=/usr/local/Ascend/cann/lib64/libmspti.so:/usr/local/python3.10.5/lib/python3.10/site-packages/taskd/python/cython_api/libs/libtaskd.so-
libmspti.so:该so由MindStudio提供,集成在CANN包内。当使用默认安装路径时,路径为:/usr/local/Ascend/cann/lib64/libmspti.so。
-
libtaskd.so:该so由TaskD组件提供,安装该whl包后,路径为:TaskD所在路径/taskd/python/cython_api/libs/libtaskd.so。
TaskD所在路径可通过以下命令进行查询。回显中的Location字段即为TaskD所在路径。
pip show taskd
-
-
在分布式环境初始化完成,能够获取到全局rank之后,修改训练脚本,在训练进程内部拉起TaskD Worker。
以下示例为MindSpore-MindFormers场景,需修改./mindformers/trainer/base_trainer.py文件,在代码中增加如下加粗字段。
def training_process( self, config: Optional[Union[dict, MindFormerConfig, ConfigArguments, TrainingArguments]] = None, network: Optional[Union[Cell, PreTrainedModel]] = None, dataset: Optional[Union[BaseDataset, GeneratorDataset]] = None, optimizer: Optional[Optimizer] = None, callbacks: Optional[Union[Callback, List[Callback]]] = None, compute_metrics: Optional[Union[dict, set]] = None, **kwargs): …… …… logger.info(".........Starting Training Model..........") if get_real_rank() % 8 == 0: pprint(config) logger.info(".........Model Compiling, Please Wait a Moment...........") try: rank = get_rank() from taskd.api.taskd_worker_api import init_taskd_worker from taskd.api.taskd_worker_api import start_taskd_worker init_taskd_worker(rank,5000) start_taskd_worker() except Exception as e: print("failed to call mindcluster taskd") model.train(config.runner_config.epochs, dataset, callbacks=callbacks, dataset_sink_mode=config.runner_config.sink_mode, sink_size=config.runner_config.sink_size, initial_epoch=config.runner_config.initial_epoch)Note
以上代码init_taskd_worker(rank,5000)中的入参5000为/user/cluster-info/profiling的上限大小,详细说明请参见def init_taskd_worker(rank_id: int, upper_limit_of_disk_in_mb: int = 5000, framework: str = "pt") -> bool中“upper_limit_of_disk_in_mb”参数。
-
修改任务YAML。详细请参见PyTorch场景的步骤6。
-
开启轻量profiling获取落盘数据。详细请参见PyTorch场景的步骤7。
-
-
落盘数据按rank进行分类,轻量profiling数据写在容器内的/user/cluster-info/profiling路径。
-
对于存在环境变量MINDX_TASK_ID的Pod,rank 0数据在容器内的路径为/user/cluster-info/profiling/$MINDX_TASK_ID/0。
Note
- 如无该环境变量,默认会落盘到名为default_task_id_时间戳的文件夹内。
- /user/cluster-info/profiling达到配置的上限大小(PyTorch场景参考步骤5;MindSpore场景参考步骤3)后,将进行文件老化,默认每次删除修改时间最早的20%个文件。老化过程中仅删除profiling目录下rank文件夹中的以数字命名的文件,建议不手动添加其他文件到profiling文件夹下。如果用户手动添加其他文件,TaskD不会将该文件删除,但该文件会占用空间。
- 轻量profiling文件以时间戳命名,各条记录以换行分割,每次追加写入rank下最新文件。最新文件大小超过10MB时,TaskD会新建profiling文件。如果使用NFS等网络存储方式,当数据同步较慢时,可能存在文件大小未达到10MB即创建新文件的情况。
慢节点&慢网络故障
简介
MindCluster集群调度组件结合MindCluster Ascend FaultDiag(故障诊断工具)提供的在线诊断能力,为集群中的慢节点&慢网络故障提供诊断功能。
使用慢节点&慢网络故障诊断功能前,需增加NodeD中CPU和内存的资源大小,在NodeD启动YAML文件中更改资源信息。
当前YAML文件内容如下:
resources:
requests:
memory: 300Mi
cpu: 500m
limits:
memory: 300Mi
cpu: 500m
修改后YAML文件内容如下:
resources:
requests:
memory: 10Gi
cpu: 5000m
limits:
memory: 10Gi
cpu: 5000m
ClusterD与FD-OL(Fault Diagnose Online)框架在同一进程中,都部署在管理节点。ClusterD启动时将自动拉起FD-OL框架。
慢节点诊断
对于AI集群中出现的节点训练性能劣化现象,提供支持实时检测计算域问题或网络导致的慢节点,以便用户通过切换或其他方式隔离慢节点。
当前仅支持与ClusterD和NodeD集成进行在线部署,请参见安装部署章节完成ClusterD和NodeD部署。
- 慢节点算法:基于训练场景关键性能指标,感知实时劣化状态;针对通信算子、计算算子同步关系,实现慢计算卡、慢通信域问题定界。
- 慢节点清洗:对节点内部增量数据转化并清洗,生成清洗结果csv文件。
- 慢节点调度:调度慢节点整体流程,控制数据清洗和慢节点算法。
前提条件
已完成性能劣化故障的部署。
启动慢节点诊断任务。
-
为获取并行域信息,需在训练脚本的训练迭代循环中增加获取并行域信息的函数调用。以下示例为PyTorch-MindSpeed场景,需在./mindspeed_llm/training/training.py文件中增加如下加粗字段。
def train(forward_step_func, model, optimizer, opt_param_scheduler, train_data_iterator, valid_data_iterator, process_non_loss_data_func, config): …… if is_profile_enabled(): prof = get_profiler() prof.start() m_iter = 0 while iteration < args.train_iters: …… args.curr_iteration = iteration loss_dict, skipped_iter, grad_norm, num_zeros_in_grad = \ train_step(forward_step_func, train_data_iterator, model, optimizer, opt_param_scheduler, config) iteration += 1 m_iter += 1 if m_iter == 5: from taskd.python.adaptor.pytorch.group_info import dump_group_info dump_group_info() batch_size = mpu.get_data_parallel_world_size() * \ args.micro_batch_size * \ get_num_microbatches() -
使用kubectl apply -f ajob-2pod-16npu.yaml命令,创建慢节点诊断任务写入configMap。

-
ajob-2pod-16npu.yaml内容如下所示,各回显数据说明请见表1。

以下为YAML示例,不可以直接拷贝编译运行,仅供参考。
--- apiVersion: v1 kind: ConfigMap metadata: name: ras-feature-slownode-default-test-pytorch-2pod-16npu # The value of JobName must be the same as the name attribute of the following job. The prefix ras-feature-slownode- cannot be modified. namespace: mindx-dl labels: fd-ol-slow-node: "true" data: FeatConf: | {"jobName":"default-test-pytorch-2pod-16npu","jobNamespace":"default","normalNumber":20,"nSigma":3,"degradationPercentage":0.3,"nConsecAnomaliesSignifySlow":3,"nSecondsDoOneDetection":30,"clusterMeanDistance":1.3,"cardOneNode":16,"SlowNode":1} ---表 1 YAML文件回显说明
字段名 默认值 说明 jobNamespace default 任务所在的namespace。 jobName - 任务名。 normalNumber 20 计算初始阈值(正常数量)。 nSigma 3个 设置σ的个数以计算其上下界。 degradationPercentage 0.3 阈值,劣化的百分比,0.3表示劣化30%。 nConsecAnomaliesSignifySlow 3次 设置异常次数,连续出现多次异常后才进行检测。 nSecondsDoOneDetection 30秒 设置间隔时长,进行检测,单位为秒。 clusterMeanDistance 1.3 聚类后,两个类别之间的阈值距离(mean1、mean2)。 cardOneNode 16张卡 一个节点的卡片数量。 slowNode 默认为1,开启任务。 是否开启任务。
- 1:开启任务。
- 0:关闭任务。
在创建慢节点任务后,可通过查询ClusterD和NodeD的日志查看其诊断任务详情。
方式一:通过K8s日志查询集群侧慢节点诊断日志
-
通过kubectl get pods -n mindx-dl命令,查询启动的ClusterD和NodeD节点数据。

-
再使用kubectl logs -n mindx-dl clusterd-7d5db546d8-kdslz | grep "got degradation, slow rank"查询日志数据。
-
若日志中出现如下图所示,则表明出现节点劣化。

方式二:通过落盘日志查询集群侧慢节点诊断日志
-
使用cat /var/log/mindx-dl.clusterd.clusterd.log | grep "got degradation, slow rank"命令查询日志数据。
-
若日志中出现如下图所示,则表明出现节点劣化。

方式三:查询节点侧的慢节点诊断日志。
使用kubectl logs -n mindx-dl node-9ld8k | grep "is degradation"命令进行查询,若日志中出现如下图所示数据,则表明出现节点劣化。

| 故障码 | 故障说明 | 故障级别 |
|---|---|---|
| 110001010 | 慢节点故障,一次性消息上报。 | SubHealthFault:亚健康故障。 |
| 100001011 | 故障劣化已恢复。 | NotHandleFault:暂不处理故障。 |
慢网络诊断
支持提供参数面网络连通性检测,实时进行网络监测和异常上报,辅助故障分析和定界定位,提前预警网络故障和亚健康风险信息,保障集群网络的长期稳定运行。
当前仅支持与ClusterD和NodeD集成进行在线部署,请参见安装部署章节完成ClusterD和NodeD部署。
- 慢网络算法:对节点之间的网络拨测数据进行分析、检测,并输出网络诊断结果。
- 慢网络调度:把控探测任务启停,上报故障结果,调度慢网络整体流程。
-
配置共享存储。
ClusterD和NodeD通过共享存储进行交互,两者的共享存储根路径需要保持一致。共享目录的根路径属主为9000用户,与ClusterD运行用户一致。
-
配置server。

-
修改NodeD配置。

-
修改ClusterD配置。

-
执行kubectl get pods -o wide -A命令出现如下示例,则表示已完成共享存储配置。

-
-
开启故障检测开关。
-
登录环境,进入NodeD解压目录。
-
执行以下命令创建名为pingmesh-config的ConfigMap文件。pingmesh-config.yaml为pingmesh配置文件,可从NodeD安装包中获取。
kubectl apply -f pingmesh-config.yaml回显示例如下:
configmap/pingmesh-config created -
执行以下命令编辑pingmesh-config文件,该文件中各参数的填写说明如下表所示。
kubectl edit cm -n cluster-system pingmesh-config表 1 pingmesh-config文件参数说明
参数 取值 说明 app pingmesh ConfigMap其中一个label的key。 global - 集群配置信息。 "1" 超节点ID 超节点ID为1的配置示例,用户可根据实际情况进行修改或新增。当配置了某个超节点后,NodeD会采用超节点的配置信息而忽略global配置信息。 activate - on:开启
- off:关闭
是否启用pingmesh功能。 task_interval [1~60] pingmesh任务间隔时间。单位为秒。
-
网络检测的pingmesh结果将写入文件<nodename>.log中,该文件中各字段的详细说明如下表所示。
表 2 <nodename>.log文件参数说明
| 参数 | 取值 | 说明 |
|---|---|---|
| uid | 长度为64的字符串 | 本次pingmesh任务的ID。 |
| config | 字符串 | 本次pingmesh任务的用户配置。 |
| physicID | [0~15] | NPU卡物理ID。 |
| taskID |
|
任务ID。 |
| DestNum | [0~47] | 本次pingmesh目标地址数量。 |
| source_addr | IPv4网络地址 | 源地址。 |
| target_addr | IPv4网络地址 | 目标地址。 |
| suc_pkt_num | - | 发送成功的包数量。 |
| fail_pkt_num | - | 发送失败的包数量。 |
| max_time |
|
最长响应时间。 |
| min_time |
|
最短响应时间。 |
| avg_time |
|
平均响应时间。 |
| tp95_time |
|
处于95%位置时的响应时间。 |
| reply_stat_num | - | 本次查询到的响应数量。 |
| ping_total_num | - | 本次任务累计的响应数量。 |
慢网络诊断到故障,会通过gRPC上报至ClusterD的公共故障管理中心。
ConfigMap文件会显示相关信息,5秒钟之后自动清除。

| 故障码 | 故障说明 | 故障级别 |
|---|---|---|
| 200001010 | 某节点中产生/恢复慢网络。 | NotHandleFault:暂不处理故障。 |
| 200001011 | 超节点内的节点间产生/恢复慢网络。 | NotHandleFault:暂不处理故障。 |
| 200001012 | 不是卡故障导致的慢网络。 | NotHandleFault:暂不处理故障。 |
故障处理
故障决策说明
在故障检测完成后,针对每一种故障模式,断点续训通过故障处理或故障容错来恢复训练业务。断点续训特性根据恢复粒度由粗到细提供Job级别重调度、Pod级别重调度、进程级别重调度、弹性训练、进程级在线恢复、算子级在线恢复多层故障处理系统。用户可根据实际情况选择使用对应的子特性。
上图中,容错速度代表故障发生到故障恢复的速度,成功率代表故障发生后故障完成恢复的成功率,易用性代表用户使用或集成的成本。
Job级别重调度、Pod级别重调度、进程级别重调度可支持当前断点续训支持的全部故障模式,但依赖存在备份冗余计算服务器资源。如果存在不可修复的硬件故障且无备份冗余计算服务器时,可以通过配置弹性训练功能进行缩容训练。进程级在线恢复当前支持片上内存故障和网络故障。算子级在线恢复当前支持芯片网络故障和灵衢网络故障。
断点续训多层故障处理系统不同层级根据恢复粒度由细到粗可以逐级回退,如图2所示,如果上一层恢复失败则可以回退到下一层处理方式。
-
重调度模式:将任务调度到健康的芯片上,并隔离故障芯片。
重调度模式默认为Job级别重调度,每次故障会停止所有的Pod。但在大规模任务中,停止所有Pod后再重调度的成本较高,存在故障恢复时间过长的问题。除此之外断点续训还提供Pod级别重调度功能,用户可根据任务规模配置,在故障时刻只停止故障相关的Pod后重调度少量Pod,从而达成故障的快速恢复。为了进一步缩短故障恢复时间、降低故障影响范围,断点续训还提供进程级别重调度及进程级在线恢复功能。
表 1 各种重调度级别的差异
重调度的级别 恢复训练耗时 配置步骤 说明 Job级别重调度 Job级重调度的恢复时间较长,随着任务规模增加恢复时间超线性劣化。 Job级重调度操作步骤简单,使用MindCluster的用户仅打开配置开关即可使用。
关键配置步骤请参见配置Job级别重调度。
为了进一步降低恢复中资源调度时间,用户可以选择在Job级重调度上开启Pod级重调度能力。 Pod级别重调度 Pod级重调度可以将资源调度时间缩短,且与任务规模无关。但是,Pod级重调度并不能优化训练初始化过程中的时间开销,整体恢复时间仍然会随着任务规模增加而超线性劣化。 Pod级重调度用户需要额外在训练容器中集成训练进程管理能力,使用MindCluster的用户具备对应进程管理能力后即可使用。
关键配置步骤请参见配置Pod级别重调度。
为了进一步降低训练初始化中的恢复时间,用户可以选择在Pod级重调度上开启进程级重调度能力。 进程级别重调度(进程级恢复) 进程级重调度可以减少训练初始化时间,将整体恢复时间缩短,且与任务规模无关或者弱相关。 相比Pod级重调度,进程级重调度用户需要额外在训练框架中集成高可用训练能力,使用MindCluster的用户需要修改训练脚本,并开启对应配置开关后使用。
关键配置步骤请参见配置进程级别重调度。
为了解决大规模场景下MTBF时间较短的问题,进一步降低整体恢复时间,用户可以选择在进程级重调度上开启进程级在线恢复能力。 进程级在线恢复 进程级在线恢复比起进程级重调度,恢复训练耗时更低。 相比进程级重调度,进程级在线恢复用户需要配置对应的配置开关后使用。
关键配置步骤请参见配置进程级在线恢复。
当前进程级在线恢复支持片上内存故障和网络故障,其余故障场景将回退其他处理方式。 算子级在线恢复 - 关键配置步骤请参见配置算子级在线恢复。 - -
重调度模式存在以下两种重调度策略。
- 直接重调度:训练过程中发生集群调度组件可以探测到的硬件故障,系统将故障节点或芯片进行隔离,直接对任务进行重调度。
- 无条件重试:训练过程中发生集群调度组件不能探测到的故障,导致任务容器异常退出,系统无条件对任务进行重调度。
表 2 重调度策略说明
重调度策略 说明 支持的故障类型 直接重调度 系统将故障的节点或芯片进行隔离,然后直接对任务进行重调度。 已知的节点故障或重调度处理级别芯片故障。 无条件重试 系统对配置了无条件重试次数的任务,进行指定次数内的重调度。
成功重调度后,任务可重试次数将减1,当可重试次数为0时无法再次触发重调度。
如需使用无条件重试功能,需在YAML中配置fault-retry-times参数,详细参数说明请参见YAML参数说明。
由于参数面网络故障或者训练相关软件故障等,导致任务异常退出,Pod的Status变为Failed状态的相关故障。
Job级别重调度
Job级别重调度即每次故障停止所有Pod,重新创建并重调度所有Pod后,重启训练任务。重调度模式默认为Job级别重调度。
了解Job级别重调度的关键配置步骤,请参见配置Job级别重调度。
- 本功能仅支持在6.0.RC2及以上版本中使用。
- 大规模K8s集群场景下,ConfigMap映射时延不可控,建议RankTable使用共享存储方式。
表 1 Job级别重调度支持的产品和框架
| 产品类型 | 硬件形态 | 训练框架 |
|---|---|---|
| Atlas 训练系列产品 |
[!NOTE] 说明 若Atlas 800 训练服务器的芯片工作模式为SMP模式,且每个Pod申请的NPU数量为1、2时,不支持使用重调度模式。查询和设置NPU芯片工作模式的详细介绍请参见《Atlas 800 训练服务器 iBMC用户指南(型号 9000)》中的“查询和设置NPU芯片工作模式(npuworkmode)”章节。 |
|
| Atlas A2 训练系列产品 |
|
|
| Atlas A3 训练系列产品 |
|
|
| A200T A3 Box8 超节点服务器 | A200T A3 Box8 超节点服务器 |
|
训练过程中如果出现了软硬件故障,将导致训练状态异常。Job级别重调度首先销毁所有的训练容器,然后隔离故障设备,再重新将训练容器调度启动。训练容器重新启动后重新拉起训练,该行为类似训练首次拉起过程。
在以上原理图中,各个步骤的说明如下。
- 检测到故障后,首先删除当前任务所有的Pod和容器。
- 隔离故障所在的设备,防止再次使用该设备。
- 重新创建和调度训练Pod和容器。
- 容器启动后,拉起训练进程恢复训练任务。
Pod级别重调度
Pod级别重调度即每次故障只停止故障相关的Pod,重新创建并重调度故障相关的Pod后,重启训练任务。如果当前故障不能恢复,则回退至Job级重调度模式。相比于Job级别重调度,Pod级别重调度会减少部分资源调度、Pod创建的时间。
了解Pod级别重调度的关键配置步骤,请参见配置Pod级别重调度。
- 在大集群训练任务中使用Pod级别重调度时,建议设置open files参数(可以打开的最大文件数目)足够大,设置过小可能导致Pod重调度出现异常。例如执行ulimit -n 100000命令,将open files参数设置为100000。
- 当训练任务的annotation中hccl/rankIndex字段为0的Pod发生故障时,不触发Pod级别重调度和进程级别重调度,直接触发Job级别重调度。
- 请勿使用ConfigMap挂载RankTable文件,否则可能会导致任务重调度失败。
表 1 重调度支持的产品和框架
|
||
训练过程中如果出现了软硬件故障,将导致训练状态异常。Pod级别重调度首先销毁当前任务中故障的Pod和容器,并通知其他训练容器中的管理进程销毁所有训练进程,然后隔离故障设备,再重新将训练容器调度启动。待训练容器重新启动后,通知所有容器中的管理进程重新拉起训练进程恢复训练。
- 检测到故障后,仅删除当前任务中故障的Pod和容器,销毁所有训练进程。
- 隔离故障所在的设备,防止再次使用该设备。
- 重新创建和调度训练Pod和容器。
- 容器启动后,拉起训练进程恢复训练。
进程级别重调度
进程级别重调度即每次故障只停止故障相关节点的进程,根据配置策略判断是否退出故障节点。
- recover策略:将故障节点的容器迁移到健康节点;
- recover-in-place策略:对于发生以下两类故障的节点,仅重启故障进程,不迁移故障节点的容器。若多个节点同时发生故障,则只发生以下两类故障的节点仅重启故障进程,不迁移容器,发生其他类型故障的节点会迁移容器。若多个节点发生故障的类型只包含业务进程异常故障,则所有故障节点均会迁移容器。
- 业务进程异常故障。
- RestartRequest和RestartBusiness级别的芯片故障。
不能恢复则回退至Job级或Pod级重调度模式。相比于Pod级别重调度,本功能仅重调度故障进程,减少了大量进程间不同步的等待耗时。同时利用了新的HCCL建链方案大大降低了建链耗时,且通过NPU卡间的参数面高速网络P2P传递CKPT信息,避免了CKPT保存和加载的耗时。
了解进程级别重调度的关键配置步骤,请参见配置进程级别重调度。
Note
- 参数面传递CKPT信息依赖故障卡中的全量优化器副本,如果不存在全量优化器副本则回退为加载存储中的CKPT文件恢复参数。
- 优化器副本依赖额外的显存占用,如果用户的显存较为紧张,可选择本地加载模式,无论是否存在优化器副本都直接加载存储中的CKPT文件恢复参数。
- 对于PyTorch训练框架,需配套MindSpeed版本使用,版本配套请参见MindSpeed-LLM。
- 对于MindSpore训练框架,需配套MindFormers版本使用,版本配套请参见MindSpore MindFormers。
- 当训练任务的annotation中hccl/rankIndex字段为0的Pod发生故障,且需迁移容器时,不触发Pod级别重调度和进程级别重调度,直接触发Job级别重调度。
- 不能和优雅容错功能同时开启。若同时开启,断点续训将通过Job级别重调度恢复训练。
- MindSpore场景下,为保证本功能的正常使用,请将MindSpore和MindIO安装在同一路径下。
- MindSpore场景下,受框架机制限制,进程级重调度存在极小概率失败风险。
- 请勿使用ConfigMap挂载RankTable文件,否则可能会导致任务重调度失败。
- PyTorch只支持单算子模式、基于Megatron框架的模型。
- 只支持acjob类型训练任务。
- 只支持单容器迁移,不支持按照亲和性迁移。
- 不支持多模态模型。
- 不支持开启watchdog功能。
- 不支持在保存Checkpoint期间触发进程级别重调度。
- Atlas A3 训练系列产品场景下,若发生NPU掉卡类、OS断连类的故障,可导致进程级别重调度失败。
- 当故障发生在HCCL建链阶段时,会导致进程级别重调度失败。如果除训练初始化的HCCL建链外,还存在其他训练阶段的HCCL建链,可参考配置HCCL主动触发建链章节进行提前建链,防止故障出现在HCCL建链阶段。
- 暂不支持在IPv6场景下使用。
表 1 重调度支持的产品和框架
训练过程中如果出现了软硬件故障,将导致训练状态异常。进程级重调度根据配置策略首先销毁故障的训练进程或容器,并通知其他训练容器中的训练进程暂停当前训练任务,然后隔离故障设备,再重新将训练容器调度启动。故障训练容器重新启动后,通知所有容器中的训练进程进行集合通信重建链。建链完成后,将CKPT通过参数面发送给新拉起的训练进程恢复参数,恢复后所有进程重新执行当前step恢复训练。
在以上原理图中,各个步骤的说明如下。
- 设备出现硬件故障后,MindCluster在服务器上的检测组件上报故障信息到ClusterD中,软件故障由容器内MindIO Controller感知并上报到ClusterD。
- ClusterD将故障服务器上的任务容器退出故障训练进程,重新调度到备用的服务器上。
- ClusterD通知Master节点上的MindIO Controller进行容错,容错流程包括通知停止训练、通知全局故障、通知恢复策略。
- MindIO Controller通知每个训练进程中的MindIO Processor,MindIO Processor调用PTA强制停止训练进程。MindIO Processor清理正常节点的资源,销毁通信域,清理后等待新进程加入。
- 备用服务器上的管理进程拉起训练进程后,创建新的MindIO Processor,MindIO Controller通知每个训练进程中的MindIO Processor恢复训练。
- 各个进程进行集合通信建链。
- 正常服务器上的NPU通过参数面将CKPT传递到备用服务器上,完成参数状态恢复后继续训练。
在进程级别重调度中,集群大脑会根据全局故障信息决策恢复策略并将策略下发到MindIO,调度器需要支持故障Pod调度,而非整个任务重调度,支持恢复策略依次回退。在训练容器中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。随后,创建DP副本组和优化器副本,以保障模型参数的冗余备份。在异常发生时,通过异常捕获装饰器捕获故障模式,在恢复时执行算子资源清理,节点重启后触发通信重建。通过参数面在线修复和状态回滚,完成进程级重调度恢复。
对于非MindSpeed-LLM和MindCluster平台用户,需在框架侧完成表2的功能适配。
表 2 进程级别重调度框架适配功能点
根据全局故障信息决策恢复策略,并下发到MindIO,支持恢复策略回退,进程级重调度失败回退到Pod级别、Job级别重调度。 |
|||
进程级在线恢复
进程级在线恢复(Step级别重计算恢复)主要针对以下2种故障类型进行故障处理:
-
网络故障:当前仅支持以下两种场景。
- HCCS L1-L2端口或链路故障时,BGP切路后,若开启算子级在线恢复且执行失败后进行Step级重试,实现进程不退出的故障快速恢复;若关闭算子级在线恢复,则对训练进程进行Step级重试,实现进程不退出的故障快速恢复。
- RoCE到上级端口或链路故障,且开启算子级在线恢复并执行失败时,对训练进程进行Step级重试,实现进程不退出的故障快速恢复。
-
片上内存故障:片上内存上出现的不可纠正错误(如故障码0x80E01801),先隔离故障片上内存空间,然后对训练进程进行Step级重试,实现进程不退出的故障快速恢复。
在以上2种场景下,如果故障不能恢复,则回退至重调度模式。
相比于进程级别重调度,进程级在线恢复不会重调度故障进程,减少了大量进程间不同步的等待耗时。同时通过NPU卡间的参数面高速网络P2P传递CKPT信息,避免了CKPT保存和加载的耗时。
该故障处理模式默认关闭,若要开启请参见(可选)配置组件。
了解进程级在线恢复的关键配置步骤,请参见配置进程级在线恢复。
Note
- 参数面传递CKPT信息依赖未故障卡中的全量优化器副本,如果不存在全量优化器副本,则回退为加载存储中的CKPT文件恢复参数。
- 优化器副本依赖额外的显存占用,如果用户的显存较为紧张,可选择本地加载模式,无论是否存在优化器副本都直接加载存储中的CKPT文件恢复参数。
- 对于PyTorch训练框架,需配套MindSpeed版本使用,版本配套请参见MindSpeed-LLM。
- 对于MindSpore训练框架,需配套MindFormers版本使用,版本配套请参见MindSpore MindFormers。
- 依赖于PyTorch的内存管理机制,仅在PYTORCH_NO_NPU_MEMORY_CACHING未配置时才能使用此功能。
- 针对部分片上内存故障场景无法生效,例如HCCL集合通信使用的内存地址故障,仍需通过进程级重调度或更上层的容错方案恢复。
- 针对MindSpeed-LLM、MindSpeed等模型或训练脚本中定义的全局变量发生故障的场景,详细处理策略请参见FAQ。
- 与优雅容错不能同时开启。若同时开启,断点续训将通过Job级别重调度恢复训练。
- MindSpore场景下,为保证本功能的正常使用,请将MindSpore和MindIO安装在同一路径下。
- MindSpore场景下,需要在启动TaskD Manager前设置export TASKD_PROCESS_ENABLE="on"。
- 请勿使用ConfigMap挂载RankTable文件,否则可能会导致任务重调度失败。
- 不支持多模态模型。
- 不支持MC2开启场景。
- 不支持开启watchdog功能。
- 当故障发生在HCCL建链阶段时,会导致进程级在线恢复失败。如果除训练初始化的HCCL建链外,还存在其他训练阶段的HCCL建链,可参考配置HCCL主动触发建链章节进行提前建链,防止故障出现在HCCL建链阶段。
- 暂不支持在IPv6场景下使用。
表 1 网络故障进程级在线恢复支持的产品和框架
表 2 片上内存故障进程级在线恢复支持的产品和框架
训练过程中如果出现了片上内存故障或网络故障,将导致训练状态异常。进程级在线恢复首先通知所有训练进程停止当前训练,然后保留当前训练信息并修复故障。修复完成后,所有训练进程回退训练状态到当前上一个Step结束时,正常服务器通过参数面将CKPT传递到故障服务器上,完成参数恢复后重新执行当前Step,然后恢复训练任务。
在以上原理图中,各个步骤的说明如下。
- 设备出现片上内存故障或网络故障后,MindCluster在服务器上的检测组件上报故障信息到集群大脑ClusterD中。
- 片上内存故障或网络故障被CANN软件感知,经训练框架上报给MindIO Processor和MindIO Controller。
- MindIO Controller向集群大脑请求决策是否进行Step级别重计算恢复,集群大脑综合集群其他节点的健康状态给出决策。
- MindIO Controller通知每个训练进程中的MindIO Processor,调用训练框架停止任务、修复故障,保留通信域信息。
- 正常服务器上的NPU通过参数面将CKPT传递到故障(已修复)服务器上,完成参数状态恢复后继续训练,重新启动当前Step计算。
在进程级在线恢复中,集群大脑根据故障信息识别网络故障和片上内存故障,下发对应恢复策略,支持恢复策略回退。在训练容器中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。随后,创建DP副本组和优化器副本,以保障模型参数的冗余备份。在异常发生时,通过异常捕获装饰器捕获故障模式,在恢复时针对不同故障执行算子资源清理、UCE模型优化器重建、参数面在线修复、状态回滚,完成进程级在线恢复。
对于非MindSpeed-LLM、MindCluster平台用户,针对不同故障需在框架侧完成以下功能适配。
表 3 进程级在线恢复针对网络故障框架适配功能点
表 4 进程级在线恢复针对片上内存故障框架适配功能点
算子级在线恢复
Atlas A3 训练系列产品支持在发生参数面网络故障时,HCCL会执行通信算子重传。在故障进程不退出的情况下,算子级在线恢复可容忍更长时间的网络异常,训练任务不中断。
若网络故障的算子级在线恢复(HCCL通信算子重执行)执行失败,则回退至进程级在线恢复
了解算子级在线恢复的关键配置步骤,请参见配置算子级在线恢复。
Note
HCCL(Huawei Collective Communication Library,华为集合通信库)是华为专为昇腾(Ascend)AI处理器设计的分布式通信库,旨在优化多设备(如NPU/GPU)间的高效协作,以加速深度学习模型的分布式训练,适用于需要大规模算力的AI场景。在分布式训练中,HCCL负责协调多个昇腾处理器之间的数据同步(如梯度聚合、参数更新),减少通信开销,提升训练效率。
当前支持在以下2种故障场景下使用算子级在线恢复功能。
- 对于芯片网络相关故障,当算子重传成功时,Volcano会将任务作为亚健康任务处理。当算子重传失败时,Volcano触发重调度处理。
- 对于灵衢总线设备相关故障,HCCL执行算子级在线恢复后,Volcano会将任务作为亚健康任务处理。
- 本特性不支持MC2开启场景。
- 不支持开启watchdog功能。
表 1 支持的产品和框架
在以上原理图中,各个步骤的说明如下。
- 训练过程中,发生HCCS网络平面LinkDown故障或RoCE网络平面LinkDown故障。
- CANN检测到网络故障,当前算子终止后,进行网络链路恢复(HCCS网络平面进行BGP切路,RoCE网络平面进行借轨通信),通信链路恢复后进行网络算子重执行。
- 算子重执行成功后,恢复训练迭代。
借轨通信任务暂停与回切
Atlas A3 训练系列产品场景下,MindCluster集群调度组件提供训练任务借轨通信的暂停与回切功能。即在训练过程中,使用主动借轨回切接口,可自由切换NPU芯片使用的RoCE网口。
使用借轨回切功能时,NPU芯片的组网关系可参考《Ascend Training Solution 组网指南(Atlas A3训练产品)》中的“网络平面介绍 > 参数面网络 > 端口对接策略”章节。
了解借轨通信任务暂停与回切功能的详细配置方法,请参见配置借轨通信任务暂停与回切。
-
调用借轨回切接口执行借轨回切动作前,请先了解NPU芯片组网关系,保证目标NPU的网络链路正常,如果目标NPU为linkdown状态会导致操作失败。
-
以上述组网指南中的接口对接关系为例,对于以下几种情况,调用SwitchNicTrack接口时,指定的dev与op如下:
- 若将device0,device8从QDD8借轨切到QDD7,传参dev为[device0,device8],op为[true,true]
- 若将device0,device8从QDD7回切到QDD8,传参dev为[device0,device8],op为[false,false]
- 如果单独将device0从QDD8的PortA借轨切到QDD7的PortA,传参dev为[device0],op为[true]
- 如果单独将device0从QDD7的PortA回切到QDD8的PortA,传参dev为[device0],op为[false]
- 如果将Leaf1下的全部device借轨切到Leaf2下,传参dev为[device0,device8,device2,device10,device4,device12,device6,device14 ],op为[true,true,true,true,true,true,true,true]
- 如果将Leaf2下的全部device回切到Leaf1下,传参dev为[device0,device8,device2,device10,device4,device12,device6,device14 ],op为[false,false,false,false,false,false,false,false]
当前支持在以下2种场景下使用借轨通信任务暂停与回切功能。
- 交换机升级场景:人工触发借轨后升级交换机,再回切。
- 故障处理场景:发生借轨的故障端口在修复完成后,再做人工回切。
- 请在训练正常迭代后,再进行借轨或回切指令的下发。
- 确保已开启进程级恢复相关功能特性。
- 暂不支持在IPv6场景下使用。
- 仅支持Pod间为Roce通信的场景。
表 1 支持的产品和框架
在以上原理图中,各个步骤的说明如下。
- AI平台集成ClusterD,调用ClusterD的gRPC接口下发切换操作,指定需要切换的NPU卡。
- ClusterD通知MindIO暂停训练。
- TaskD Manager通知所有TaskD Worker调用训练框架接口执行切换操作。
- 训练框架按照通信域逐一调用CANN接口执行切换操作。
- ClusterD判断所有NPU卡的切换操作完成后,再由TaskD通知MindIO在切换完成后继续执行下一个Step训练。
在借轨通信任务暂停与回切中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。通过主动调用优雅暂停机制,完成当前卡上任务暂停和任务切换。集群大脑需提供对外接口,接收切换指令并管理借轨通信流程。
对于非MindSpeed-LLM、MindCluster平台用户,需在框架侧完成表2的功能适配。
表 2 借轨通信任务暂停与回切框架适配功能点
(可选)优雅容错
Note
该功能已经日落。PyTorch框架在7.2.RC1之后的版本不再支持;MindSpore框架在7.1.RC1之后的版本不再支持。
当用户进行没有备用资源的训练任务,或者期望设备自动恢复时,可以选择使用优雅容错功能。即当训练时的芯片设备出现故障后,系统将尝试对故障芯片进行自动恢复,如果可以恢复,则在保持Pod运行状态下,将任务原地拉起继续训练,不能恢复则回退至重调度模式。
优雅容错功能无需进行资源调度,即可自动将故障设备恢复。但是它无法降低训练初始化中的恢复时间,通常情况下,优雅容错所需恢复时间大于进程级重调度和进程级在线恢复功能。
了解优雅容错的关键配置步骤,请参见配置优雅容错。
- 当前只支持芯片故障使用优雅容错功能。
- 优雅容错功能与进程级别重调度、进程级在线恢复功能不能同时开启。若同时开启,断点续训将通过Job级别重调度恢复训练。
- 暂不支持在IPv6场景下使用。
表 1 优雅容错支持的产品和框架
在节点或芯片故障处理过程中,若使用重调度模式,需要运维人员手动恢复设备。若任务恢复不及时可能导致训练集群中出现大量散点故障,降低集群算力利用率。因此,断点续训在重调度模式上增加了优雅容错功能,用于优化NPU芯片的部分故障容错能力。
NPU芯片故障中的部分故障可以通过退出芯片上的训练进程以及热复位芯片来恢复,优雅容错功能即针对这部分故障进行恢复处理,不需要重调度任务。
Ascend Device Plugin负责故障的上报以及设备的恢复,管理进程(PyTorch场景下为Elastic Agent组件,MindSpore场景下为TaskD组件)根据Ascend Device Plugin上报的信息进行训练进程的停止与重新拉起,完成故障恢复(不能恢复则回退至重调度模式)。集成优雅容错模式需要在业务容器中添加管理进程,管理进程需要具备故障感知、停止训练任务和重启训练任务等能力。
优雅容错模式直接将故障上报到业务容器内的管理进程中(通常通过挂载文件的方式),容器内的管理进程读取故障文件信息获取到故障信息,获取故障信息的流程如图1所示。
优雅容错模式将故障区分为以下四类,无需处理、重新执行业务、需要复位芯片和需要重调度,对于每类故障的处理如图2所示。
在线压测
MindCluster支持训练在线压测特性,即在训练过程中可以调用在线压测接口,暂停指定训练任务,对任务使用的节点进行硬件P2P或AIC压力测试。若不存在故障则恢复训练;若存在故障则隔离故障节点,触发断点续训。
- 对于PyTorch训练框架,需配合MindSpeed-LLM 2.3.0版本使用,版本配套请参见MindSpeed-LLM。
- 对于MindSpore训练框架,需配合MindFormers master版本使用,版本配套请参见MindSpore MindFormers。
- 请在训练正常迭代后,再进行在线压测指令的下发。
- 确保已开启进程级恢复相关功能特性。
- 压测过程中不支持重启ClusterD,如果ClusterD异常重启,需要重启训练并下发压测任务。
- 压测过程中,需要关闭热复位功能。
- P2P压测需确保device侧有10G以上的空闲内存。
- 需要在节点增加nodeDEnable=on标签,保证出现压测的节点可以隔离。
- 对于MindSpore训练框架,需要在启动TaskD Manager前设置export TASKD_PROCESS_ENABLE="on"。
- 暂不支持在IPv6场景下使用。
表 1 在线压测支持的产品和框架
在以上原理图中,各个步骤的说明如下。
- AI平台集成ClusterD,调用ClusterD的gRPC接口下发压测操作,指定需要压测的节点。
- ClusterD通知MindIO暂停训练。
- TaskD Manager通知指定TaskD Worker调用训练框架接口执行压测操作。
- 训练框架调用指定NPU卡上的CANN接口执行压测操作。
- ClusterD判断指定NPU卡的压测操作完成后,再由TaskD通知MindIO在压测完成后继续执行下一个Step训练。
在在线压测中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。通过主动调用优雅暂停机制,完成当前卡上任务暂停,暂停后进行硬件压力测试,测试完成后继续训练。集群大脑需提供对外接口,接收压测指令并管理压测流程。
对于非MindSpeed-LLM、MindCluster平台用户,需在框架侧完成表2的功能适配。
表 2 在线压测框架适配功能点
亚健康热切
训练任务配置为亚健康热切策略(hotSwitch)后,当发生亚健康故障时,拉起备份节点后暂停训练进程,再使用备份节点重新拉起训练任务。
-
对于PyTorch训练框架,需配合MindSpeed-LLM 2.3.0版本使用,版本配套请参见MindSpeed-LLM。
-
对于MindSpore训练框架,需配合MindFormers master版本使用,版本配套请参见MindSpore MindFormers。
-
只支持PyTorch单算子模式、基于Megatron框架的模型以及acjob类型训练任务。
-
MindSpore场景下,为保证本功能的正常使用,请将MindSpore和MindIO安装在同一路径下。
-
不支持多模态模型。
-
不支持开启watchdog功能。
-
训练任务未出迭代时触发热切,可能会造成MindIO阻塞,最后触发Job级别重调度。
-
当训练任务的annotation中hccl/rankIndex字段为0的Pod发生亚健康故障时,不支持触发亚健康热切。
-
以下异常情况会回退至Job级别重调度,且任务亚健康处理策略降级为ignore,不再处理亚健康故障:
- 备份Pod拉起后,训练暂停失败。
- 备份Pod拉起后,MindCluster等待上报训练暂停状态超时(15分钟)。
- 备份Pod运行失败。
- 原Pod删除后,训练恢复失败。
- 原Pod删除后,MindCluster等待上报训练恢复状态超时(15分钟)。
-
配置亚健康热切策略后,会自动增加进程级恢复开关,若发生非亚健康故障,将触发进程级恢复流程。
-
无备节点场景下,无法完成热切流程,任务亚健康处理策略降级为ignore,不再处理亚健康故障。
-
暂不支持在IPv6场景下使用。
表 1 亚健康热切支持的产品和框架
在以上原理图中,各个步骤的说明如下。
- ClusterD通过Ascend Device Plugin感知到亚健康故障。
- ClusterD根据配置策略决策是否进行亚健康热切恢复。
- ClusterD通知Ascend Operator拉起备份Pod。
- Volcano调度备份Pod。
- 备份Pod中创建新的MindIO Processor,MindIO Processor向MindIO Controller发起注册。
- MindIO Controller下发训练暂停通知。
- MindIO Controller通知ClusterD训练暂停。
- ClusterD通知Volcano删除故障Pod。
- ClusterD通知MindIO恢复训练。
在亚健康热切中,集群大脑根据亚健康故障信息,为故障Pod设置注解,拉起并调度备份Pod,通知热切策略到MindIO,训练切换到备份Pod后恢复训练。在训练容器中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。在异常发生时,通过异常捕获装饰器捕获故障模式。在新节点启动后,正常节点暂停训练,之后重建通信域,完成新节点参数面恢复,训练状态完成后完成节点热切换。
对于非MindSpeed-LLM、MindCluster平台用户,需在框架侧完成表2的功能适配。
表 2 亚健康热切框架适配功能点
弹性训练
当出现硬件故障,且K8s集群中无可用备份资源时,MindCluster会先按照数据并行域缩容部分节点继续训练,当集群中有可用空闲资源时,再触发扩容恢复原有规模训练。相比于进程级别重调度,解决了集群中无可用备份资源被重调度的问题。
-
仅支持PyTorch配合MindSpeed-LLM 2.3.0版本使用,版本配套请参见MindSpeed-LLM。
-
仅支持acjob类型训练任务。
-
依赖于MindIO的优化器副本,需要存在全量优化器副本,故需要安装MindIO和TaskD配合使用。
-
不能和优雅容错功能同时开启。
-
当训练任务的annotation中hccl/rankIndex字段为0的Pod发生故障时,不支持触发弹性训练。
-
不支持多模态模型。
-
不支持开启watchdog功能。
-
由于弹性训练会额外创建新的通信组,因此可能会导致片上内存占用增加。
-
暂不支持在IPv6场景下使用。
增加内存大小计算公式:增加内存最大值(MB)= HCCL_BUFFSIZE * 2 * 9,其中,HCCL_BUFFSIZE默认为200MB,HCCL_BUFFSIZE的说明详细请参见《CANN 环境变量参考》中的“HCCL_BUFFSIZE”章节。
更多使用约束可参考MindSpeed-LLM弹性训练功能使用约束。
表 1 弹性训练支持的产品和框架
以上示意图仅以缩容1个DP域为例,实际弹性训练过程中可能会一次缩容多个DP域。图中每个方格代表一个rank。
- 按照TP(Tensor Parallelism,张量并行)、PP(Pipeline Parallelism,流水线并行)、DP(Data Parallelism,数据并行)正常进行分布式训练。
- 训练到某一时刻,若某张卡发生故障,且集群中无更多空闲资源可被调度进行断点续训,则按照DP域缩容,即缩容1个DP域对应的Pod(可能包含多个Pod)后继续训练。
- 缩容训练到某一时刻,集群中有空闲资源时,缩容的Pod会被重新调度,扩容恢复到原有规模继续训练。
在以上流程图中,各个步骤的说明如下。
- 设备出现硬件故障后,MindCluster在服务器上的检测组件上报故障信息到ClusterD中,软件故障由容器内MindIO Controller感知并上报到ClusterD。
- ClusterD将故障服务器上的任务容器销毁。
- 若没有备份节点调度新容器,ClusterD通知Master节点上的MindIO Controller进行缩容训练。
- MindIO Controller通知每个训练进程中的MindIO Processor,MindIO Processor调用PTA停止训练进程,清理正常节点的资源。
- MindIO Controller通知正常的训练进程中的MindIO Processor执行通信组重建等缩容流程,进行缩容训练。
- 检测到缩容时删除的Pod重调度成功。
- ClusterD通过TaskD Manager通知MindIO Controller执行扩容。
- MindIO Controller通知每个训练进程中的MindIO Processor,MindIO Processor调用PTA停止训练进程,清理正常节点的资源。
- 各个进程进行集合通信建链。
- 正常服务器上的NPU通过参数面将CKPT传递到备用服务器上,完成参数状态恢复后继续训练。
在弹性训练中,集群大脑会根据全局故障信息决策恢复策略,并将策略下发到MindIO。调度器需要支持故障Pod调度,而非整个任务重调度,支持恢复策略依次回退。在训练容器中,框架首先初始化MindIO服务。启动服务后优化器更新时会上报对应状态到MindIO。随后,创建DP副本组和优化器副本,以保证模型参数的冗余备份。当异常发生时,通过异常捕获装饰器捕获故障模式,并由MindIO上报给集群大脑决策。
- 当集群大脑检测到故障,且无冗余备份资源时,下发缩容策略到MindIO,执行算子资源清理、缩容重建,以缩容状态继续训练。
- 当集群大脑检测到有可用资源且新节点成功拉起时,下发扩容策略到MindIO,执行算子资源清理、扩容通信重建、扩容参数面恢复和扩容状态回滚,完成弹性扩容恢复原有规模继续训练。
对于非MindSpeed-LLM和MindCluster平台用户,需在框架侧完成表2的功能适配。
表 2 弹性训练框架适配功能点
表2中序号为1-6的适配项为MindIO TFT(MindCluster MindIO Training Fault Tolerance)公共逻辑,序号为17-18的适配项为断点续训公共逻辑,本章节不再详细描述。以下针对弹性训练特有功能点,基于Megatron 0.12.1版本进行简要介绍。
-
弹性训练回调注册
在训练拉起初始化时调用,将弹性训练缩容和扩容恢复过程中需要执行的回调函数注册到MindIO中,进而在恢复过程中被调用。
-
缩容重建
- 基于缩容后成员创建新的全局通信组并记录,后续将替代原全局通信组进行通信。
- 记录框架原始DP size、num_microbatches等参数作为后续扩容恢复使用,并更新为缩容后数据。
- 基于故障Rank信息重建缩容后其他局部通信组,并更新模型、优化器等实例对象中的通信组。
- 重建数据集、重新初始化部分框架实例、参数等。
-
扩容通信重建
- 重建扩容后全局和局部通信组,并更新模型、优化器等实例对象中的通信组。
- 恢复框架DP size等参数、重新初始化部分框架实例等。
-
扩容参数面恢复
- 为新拉起的rank训练进程和备份rank训练进程创建通信组,用于发送和接收优化器参数等。
- 备份rank训练进程向新拉起的rank训练进程发送恢复所需的优化器参数。
- 新拉起的rank训练进程接收优化器参数后,按需更新optimizer、opt_param_scheduler、全局args等参数。
-
扩容状态回滚
- 恢复框架num_microbatches等参数。
- 恢复训练前将优化器参数拷贝到模型参数中,并在对应DP域内进行一次all_gather通信操作,确保模型参数为最新状态。
- 修复打印训练迭代日志。
- 重建数据集,重新初始化部分框架实例、参数等。
- 销毁恢复过程中发送和接收参数的通信组。
-
新拉起节点torch通信适配
- 对于重启节点,从pretrain启动流程到进入train之间,会下发通信算子,但正常训练rank在该阶段并未与重启节点配套重建通信域,集合通信无法成功,因此直接跳过。
- 对于重启节点,从pretrain启动流程到进入train之间,会创建并行通信域,但正常训练rank在该阶段并未与重启节点配套重建通信域,对于gloo组会报错,因此直接跳过新建gloo通信组。
-
缩容训练全局组通信适配
在缩容训练过程中,由于故障节点已经被删除,因此使用原全局通信组通信会失败,需替换为缩容后的全局通信组。
-
缩容训练副本组通信适配
在LLM仓参考链接中,start_param_sync_wrapper、get_grad_norm_fp32_wrapper、get_parameter_state_dp_zero_wrapper等是为了适配缩容训练时副本组通信而patch,下面以get_parameter_state_dp_zero_wrapper为例介绍副本组适配原理:
假设当前tp=8、pp=1、dp=4。DP组分别为rank [0,8,16,24]、[1,9,17,25]、[2,10,18,26]、…、[7,15,23,31],按照副本优化器原理,副本组分别为rank [0,8]、[16,24]、[1,9]、[17,25]、[2,10]、[18,26]、…、[7,15]、[23,31],rank 0-15与rank 16-31互为副本。rank 31故障后,将rank 24-31对应DP域删除继续缩容训练。
原生Megatron会使用优化器实例的data_parallel_group_gloo成员变量对应的group(即DP组,在使用MindIO的优化器副本时为副本组)进行通信。缩容后不包含删除的rank 24-31的副本组,继续按照原有通信组进行通信,包含缩容rank的副本组使用组内正常rank与缩容rank对应的副本rank组成的缩容组进行通信,例如副本组rank [23,31]缩容后,通信使用的通信组为rank [23,15]。
-
缩容训练参数适配
在LLM仓参考链接中,patch_world_size_func_wrapper、log_wrapper、is_last_rank_wrapper、optimizer_param_scheduler_step_wrapper、track_app_tag_wrapper、print_rank_last_wrapper、num_floating_point_operations_wrapper等是为了适配global_batch_size、world_size等训练中使用的参数而patch。例如:原生使用dp_size*micro_batch_size*num_microbatches,缩容后各个DP内num_microbatches可能不一样,因此直接使用args.globatch_size。缩容后判断是否最后一个rank使用缩容后的全局组;全局组大小修改为缩容后的大小等。
-
梯度精度计算适配
在LLM仓参考链接1中,start_grad_sync_wrapper、forward_step_wrapper、elastic_training_get_forward_backward_func_wrapper以及LLM仓参考链接2所指向的loss_func的代码是为了适配因缩容导致的精度梯度变化而patch或修改。
- loss_func由每个micro_batch都要进行DP组内all_reduce通信修改为缩容训练时不进行通信,原因是缩容后每个DP域内num_micro_batches数量可能不一样,导致前几个DP会多执行一次all_reduce而卡住。
- start_grad_sync_wrapper中将梯度缩放因子gradient_scaling_factor修改为1.0 / (arguments.global_batch_size / arguments.micro_batch_size),即在原1/dp_size基础上再除以num_micro_batches。
- forward_step_wrapper将入参num_microbatches修改为1,目的是loss计算时不再除以num_microbatches,因为在start_grad_sync_wrapper中已经除以了num_microbatches。
- elastic_training_get_forward_backward_func_wrapper因为loss_func没有执行DP组内all_reduce,原生forward_backward_func执行完成后,在最后一个PP时将losses_reduced每个key的和(即所有micro_batch的lm loss相加)在DP组内执行all_reduce操作求和。
训练恢复
训练恢复原理说明
在完成故障处理后,训练进程会被重新拉起,拉起的训练进程需要完成模型权重的保存和加载,才能回到任务中断时的训练状态。在正常训练中,每隔一段时间保存训练模型权重的CKPT(Checkpoint)文件,在任务中断后,新拉起的进程可以加载之前保存的CKPT文件,从而恢复到之前保存点的模型权重状态,减少训练时间。对于不同框架,保存和加载CKPT的方法不一样,以下给出了TensorFlow、PyTorch、MindSpore保存和加载CKPT的示例,用户需按照示例修改自己的训练模型脚本。
-
保存CKPT。
def save_checkpoint(state, is_best, args, filename='checkpoint.pth.tar'): filename2 = os.path.join(args.save_ckpt_path, filename) torch.save(state, filename2) if is_best: shutil.copyfile(filename2, os.path.join(args.save_ckpt_path, 'model_best.pth.tar')) -
加载CKPT。
checkpoint = torch.load(args.checkpoint_path, map_location=loc) args.start_epoch = checkpoint['epoch'] best_acc1 = checkpoint['best_acc1'] model.load_state_dict(checkpoint['state_dict']) optimizer.load_state_dict(checkpoint['optimizer'])
-
保存CKPT。
ms.save_checkpoint(net, "./lenet.ckpt", choice_func=lambda x: x.startswith("conv") and not x.startswith("conv1")) -
加载CKPT。
param_dict = ms.load_checkpoint("./lenet.ckpt")
-
使用tf.compat.v1.train.CheckpointManager接口进行CKPT管理。
checkpoint_manager = tf.train.CheckpointManager( runnable.checkpoint, directory=flags_obj.model_dir, max_to_keep=10, step_counter=runnable.global_step, checkpoint_interval=checkpoint_interval) -
保存CKPT(创建一个新的CKPT)。
Save( Checkpoint_number=None, check_internal=True, options=None ) -
加载保存的CKPT(尝试加载从目录中的最新的CKPT)。
Restore_or_initialize()
周期性CKPT保存
现有大规模集群训练主要通过CKPT(Checkpoint)机制,即在训练过程中周期性保存训练过程数据(模型参数等)作为CKPT。当业务平台检测到故障发生后,可退出当前训练任务,通过重新加载CKPT数据,从CKPT保存时刻开始恢复训练,避免从头开始重新进行训练。
周期性CKPT保存分为2个部分:异步CKPT保存以及内存CKPT加载。
-
异步CKPT保存
MindIO ACP提供异步保存周期性CKPT的能力。未使用MindIO ACP时,需要将需要保存的参数从设备拷贝到主机侧,再从主机侧落盘到存储中,这一时间通常在分钟级。MindIO ACP提供异步落盘的能力,当需要保存的参数从设备拷贝到主机侧后,通过异步进程进行落盘到存储,不会阻塞训练进程,落盘的过程中训练可以继续进行。
-
内存CKPT加载
MindIO ACP提供基于内存的周期性CKPT加载的能力。在训练恢复时,通常需要从存储加载之前保存的周期性CKPT,加载完成后恢复训练状态再继续训练。但是,由于数据量较大和存储性能限制,大模型任务通常加载时间在分钟级。为了降低CKPT加载时间,从而降低训练恢复的时间,MindIO ACP提供基于内存的周期性CKPT加载机制,故障后直接基于内存加载,将降低大量加载的时间。
在使用故障重调度的CKPT保存能力时,需根据实际情况选择周期性保存CKPT频率,用户可参考如图1所示的推荐频率。
使用周期CKPT恢复能力,训练恢复后将丢失上一次周期保存点到故障点这一时间段的训练状态。因此,如果想要降低每次故障导致的训练状态损失,需要降低周期性保存的间隔。但是,每次保存需要中断训练后将CKPT从设备侧落盘到存储侧,这浪费了大量的训练时间。如果降低周期性保存的间隔,将导致训练时间的浪费,从而也会带来训练时间的损失。综上所述,如果单次保存时间恒定,通常需要作出保存损失和故障损失的综合权衡。
为了降低上述损失,需要降低单次保存时间。单次保存时间受到保存数据量及存储性能的影响,通常难以改变这两者。本产品提供MindIO ACP产品解决周期性CKPT恢复损失高的问题。
临终CKPT保存
尽管通过异步保存周期性CKPT能够降低周期性保存间隔,从而降低每次故障的损失,但是由于仍然具有保存开销,难以做到秒级的故障损失。因此,MindCluster集群调度组件提供临终保存CKPT能力,在故障时刻保存当前step初始的参数状态,从而将训练恢复的状态损失降低到一个“step”以内。
MindCluster MindIO Try To Persist(下文简称MindIO TTP)提供临终CKPT能力,帮助用户在故障时刻保存临终时刻CKPT。
了解临终CKPT保存的详细介绍,请参见故障恢复加速。
了解临终CKPT保存的配置步骤,请参见配置临终CKPT保存。
在临终CKPT中,框架首先初始化MindIO服务,启动服务后优化器更新时会上报对应状态到MindIO。随后,创建DP副本组和优化器副本,以保障模型参数的冗余备份。在异常发生时,通过异常捕获装饰器捕获故障模式,之后执行算子资源清理,基于副本完成临终CKPT保存。
对于非MindSpeed-LLM用户,需在框架侧完成表1的功能适配。
表 1 临终CKPT保存框架适配功能点
参数面CKPT传输恢复
通过临终CKPT能力可以将每次训练由于CKPT回滚机制导致的训练回滚损失降到一个“step”内,但是在故障时刻时需要进行落盘保存,并在容错完成训练恢复后需要加载存储中的CKPT进行恢复,将导致整体故障恢复时间延长。因此,为了降低故障恢复时间,MindCluster集群调度组件提供参数面CKPT传输恢复能力。
在故障时刻将参数状态保持在设备侧,在容错完成训练恢复时将正常卡内的参数状态通过参数面网络传输到容错处理的卡上,从而快速恢复容错处理卡的参数状态。当前该能力需要结合进程级别重调度和进程级在线恢复使用,不支持用户独立使用。
了解参数面CKPT的配置步骤,请参见配置参数面传参恢复。





















