
# 训练作业卡死检测定位
#### 什么是训练作业卡死检测
训练作业在运行中可能会因为某些未知原因导致作业卡死，如果不能及时发现，就会导致无法及时释放资源，从而造成极大的资源浪费。为了节省训练资源成本，提高使用体验，ModelArts提供了卡死检测功能，能自动识别作业是否卡死，并在日志详情界面上展示，同时能配置通知及时提醒用户作业卡死。
#### 检测规则
卡死检测主要是通过监控作业进程的状态和资源利用率来判定作业是否卡死，会启动一个协程来周期性地监控上述两个指标的变化情况。卡死检测有单实例和全实例两种检测规则，是同时生效的。
- **单实例检测**
  - 进程状态：只要训练作业单实例中的进程IO存在变化，就进入下一个检测周期。如果在多个检测周期内，所有进程IO都没有变化，则进入资源利用率检测阶段。
  
  - 资源利用率：在作业单实例进程IO没有变化的情况下，采集一定时间段内的GPU利用率或NPU利用率，并根据这段时间内的GPU利用率或NPU利用率的方差和中位数来判断资源使用率是否有变化。如果没有变化，则判定作业卡死。
   
- **全实例检测**
  资源利用率：当作业在一段时间内所有运行中的实例的GPU利用率或者NPU利用率没有变化，同时每个实例的CPU使用也低于1核，则判定作业卡死。
  
系统预置了卡死检测的环境变量"MA_HANG_DETECT_TIME=30"，表示检测到指标异常并持续30分钟则判定作业卡死。如果需要修改卡死检测时间，则可以修改环境变量"MA_HANG_DETECT_TIME"的值，具体操作指导请参见[管理训练容器环境变量](https://support.huaweicloud.com/develop-modelarts/develop-modelarts-0104.html)。
![](https://support.huaweicloud.com/trouble-modelarts/public_sys-resources/caution_3.0-zh-cn.png)
- 由于检测规则的局限性，当前卡死检测存在一定的误检率。如果是作业代码本身逻辑（如长时间sleep）导致的卡死，请忽略。
- 如果对于误检有疑问或者卡死问题无法自行解决，您可以前往[ModelArts开发者论坛](https://bbs.huaweicloud.com/forum/forum-718-1.html)进行提问或者搜索问题。
 
#### 约束限制
卡死检测仅支持资源类型为GPU和NPU的训练作业。
#### 操作步骤
卡死检测无需额外配置，作业运行中会自动执行检测。检测到作业卡死后会在训练作业详情页提示作业疑似卡死。如需检测到卡死后发送通知（短信、邮件等）请在作业创建页面配置事件通知。
#### 常见案例
1. **复制数据卡死**
   **问题现象**
   调用mox.file.copy_parallel复制数据时卡死。
   **解决方案**
   - 复制文件和文件夹均可采用：
     ```
     import moxing as mox
     mox.file.set_auth(is_secure=False)
     ```
     
   
   
   
   - 复制单个大文件5G以上时可采用：
     ```
     from moxing.framework.file import file_io
     ```
     查看当前moxing调用的接口版本：file_io._LARGE_FILE_METHOD，如果输出值为1则为V1版本，如果输出值为2，则为V2版本。
     V1版本修改：file_io._NUMBER_OF_PROCESSES=1
     V2版本修改：file_io._LARGE_FILE_METHOD = 1，将模式设置成V1然后用V1的方式修改规避，也可以直接file_io._LARGE_FILE_TASK_NUM=1。
     
   
   - 复制文件夹时可采用：
     ```
     mox.file.copy_parallel(threads=0,is_processing=False)
     ```
     
    
2. **训练前卡死**
   作业为多节点训练，且还未开始训练时发生卡死，可以在代码中加入os.environ\["NCCL_DEBUG"\] = "INFO"，查看NCCL DEBUG信息。
   - **问题现象** 1
     日志中还未出现NCCL DEBUG信息时已卡死。
     **解决方案1**
     检查代码，检查是否有参数中未传入"master_ip"和"rank"参数等问题。
     
   
   - **问题现象2**
     分布式训练的日志中，发现有的节点含有GDR信息，而有的节点无GDR信息，导致卡死的原因可能为GDR。
     ```
     # 节点A日志
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-1:1136:1191 [2] NCCL INFO Channel 00 : 3[5f000] -> 10[5b000] [receive] via NET/IB/0/GDRDMA
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-1:1140:1196 [6] NCCL INFO Channel 00 : 14[e1000] -> 15[e9000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-1:1141:1187 [7] NCCL INFO Channel 00 : 15[e9000] -> 11[5f000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-1:1138:1189 [4] NCCL INFO Channel 00 : 12[b5000] -> 14[e1000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-1:1137:1197 [3] NCCL INFO Channel 00 : 11[5f000] -> 16[2d000] [send] via NET/IB/0/GDRDMA
     # 节点B日志
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-2:1139:1198 [2] NCCL INFO Channel 00 : 18[5b000] -> 19[5f000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-2:1144:1200 [7] NCCL INFO Channel 00 : 23[e9000] -> 20[b5000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-2:1142:1196 [5] NCCL INFO Channel 00 : 21[be000] -> 17[32000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-2:1143:1194 [6] NCCL INFO Channel 00 : 22[e1000] -> 21[be000] via P2P/IPC
     modelarts-job-a7305e27-d1cf-4c71-ae6e-a12da6761d5a-worker-2:1141:1191 [4] NCCL INFO Channel 00 : 20[b5000] -> 22[e1000] via P2P/IPC
     ```
     **解决方案2**
     在程序开头设置"os.environ\["NCCL_NET_GDR_LEVEL"\] = '0'"关闭使用GDR，或者寻找运维人员将机器添加GDR。
     
   
   - **问题现象3**
     NCCL信息中报出Got completion with error 12, opcode 1, len 32478, vendor err 129等通信信息时，说明当前网络不是很稳定。
     **解决方案3**
     可加入3个环境变量。
     - NCCL_IB_GID_INDEX=3： 使用RoCE v2协议，默认使用RoCE v1，但是v1在交换机上没有拥塞控制，可能丢包，而且后面的交换机不会支持v1，就无法启动。
     
     - NCCL_IB_TC=128：数据包走交换机的队列4通道，这是RoCE协议标准。
     
     - NCCL_IB_TIMEOUT=22：把超时时间设置长一点，正常情况下网络不稳定会有5秒钟左右的间断，超过5秒就返回timeout了，改成22预计有二十秒左右，算法为4.096 µs \* 2 \^ timeout。
      
    
3. **训练中途卡死**
   - **问题现象1**
     检测每个节点日志是否有报错信息，某个节点报错但作业未退出导致整个训练作业卡死。
     **解决方案1**
     查看报错原因，解决报错。
     
   
   - **问题现象2**
     作业卡在sync-batch-norm中或者训练速度变慢。pytorch如果开了sync-batch-norm，多机会慢，因开了sync-batch-norm以后，每一个iter里面每个batch-norm层都要做同步，通信量很大，而且要所有节点同步。
     **解决方案2**
     关掉sync-batch-norm，或者升pytorch版本，升级pytorch到1.10。
     
   
   - **问题现象3**
     作业卡在TensorBoard中，出现报错：
     ```
     writer = SummaryWriter('./path/to/log')
     ```
     **解决方案3**
     存储路径设为本地路径，如cache/tensorboard，不要使用OBS路径。
     
   
   - **问题现象4**
     使用pytorch中的dataloader读数据时，作业卡在读数据过程中，日志停在训练的过程中并不再更新日志。
     **解决方案4**
     用dataloader读数据时，适当减小num_worker。
     
    
4. **训练最后一个epoch卡死**
   **问题现象**
   通过日志查看数据切分是否对齐，如果未对齐，容易导致部分进程完成训练退出，而部分训练进程因未收到其他进程反馈卡死，如下图同一时间有的进程在epoch48，而有的进程在epoch49。
   ```
   loss exit lane:0.12314446270465851
   step loss is 0.29470521211624146
   [2022-04-26 13:57:20,757][INFO][train_epoch]:Rank:2 Epoch:[48][20384/all] Data Time 0.000(0.000) Net Time 0.705(0.890) Loss 0.3403(0.3792)LR 0.00021887
   [2022-04-26 13:57:20,757][INFO][train_epoch]:Rank:1 Epoch:[48][20384/all] Data Time 0.000(0.000) Net Time 0.705(0.891) Loss 0.3028(0.3466) LR 0.00021887
   [2022-04-26 13:57:20,757][INFO][train_epoch]:Rank:4 Epoch:[49][20384/all] Data Time 0.000(0.147) Net Time 0.705(0.709) Loss 0.3364(0.3414)LR 0.00021887
   [2022-04-26 13:57:20,758][INFO][train_epoch]:Rank:3 Epoch:[49][20384/all] Data Time 0.000 (0.115) Net Time 0.706(0.814) Loss 0.3345(0.3418) LR 0.00021887
   [2022-04-26 13:57:20,758][INFO][train_epoch]:Rank:0 Epoch:[49][20384/all] Data Time 0.000(0.006) Net Time 0.704(0.885) Loss 0.2947(0.3566) LR 0.00021887
   [2022-04-26 13:57:20,758][INFO][train_epoch]:Rank:7 Epoch:[49][20384/all] Data Time 0.001 (0.000) Net Time 0.706 (0.891) Loss 0.3782(0.3614) LR 0.00021887
   [2022-04-26 13:57:20,759][INFO][train_epoch]:Rank:5 Epoch:[48][20384/all] Data Time 0.000(0.000) Net Time 0.706(0.891) Loss 0.5471(0.3642) LR 0.00021887
   [2022-04-26 13:57:20,763][INFO][train_epoch]:Rank:6 Epoch:[49][20384/all] Data Time 0.000(0.000) Net Time 0.704(0.891) Loss 0.2643(0.3390)LR 0.00021887
   stage 1 loss 0.4600560665130615 mul_cls_loss loss:0.01245919056236744 mul_offset_loss 0.44759687781333923 origin stage2_loss 0.048592399805784225
   stage 1 loss:0.4600560665130615 stage 2 loss:0.048592399805784225 loss exit lane:0.10233864188194275
   ```
   **解决方案**
   使用tensor的切分操作对齐数据。
   
   
 
