
# 使用Cloud Shell调试生产训练作业
ModelArts提供了Cloud Shell，可以登录运行中的容器，用于调试生产环境的训练作业。
#### 约束限制
仅专属资源池支持使用Cloud Shell登录训练容器，且训练作业必须处于"运行中"状态。
 #### 前提条件：给子账号配置允许使用Cloud Shell的权限
1. 使用主用户账号登录[华为云管理控制台](https://console.huaweicloud.com/console)，单击右上角用户名，在下拉框中选择"统一身份认证"，进入统一身份认证（IAM）服务。
2. 在统一身份认证服务页面的左侧导航选择"权限管理 \> 权限"，单击右上角的"创建自定义策略"按如下要求设置完成后单击"确定"。
   - "策略名称"：设置自定义策略名称，例如：允许通过Cloud Shell访问运行中的训练作业。
   
   - "策略配置方式"：选择可视化视图。
   
   - "策略内容"：允许，云服务中搜索ModelArts服务并选中，操作列中搜索关键词modelarts:trainJob:exec并选中，所有资源选择默认值。
    
3. 在统一身份认证服务页面的左侧导航选择"用户组"，在用户组页面查找待授权的用户组名称，在右侧的操作列单击"授权"，勾选步骤[2]创建的自定义策略，单击"下一步"，选择授权范围方案，单击"确定"。
   此时，该用户组下的所有用户均有权限通过Cloud Shell登录运行中的训练作业容器。
   如果没有用户组，也可以创建一个新的用户组，并通过"用户组管理"功能添加用户，并配置授权。如果指定的子用户没有在用户组中，也可以通过"用户组管理"功能增加用户。
   
 
#### 使用Cloud Shell
1. 参考[前提条件：给子账号配置允许使用Cloud Shell的权限]，完成配置。
2. 在[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)的左侧导航栏中选择"模型开发与训练 \> 模型训练"（旧版控制台："模型训练 \> 训练作业"）。
3. 在训练作业列表中，单击作业名称进入训练作业详情页面。
4. 在训练作业详情页面，单击"Cloud Shell"页签，登录训练容器。 连接成功后，Cloud Shell界面提示如下。
   图1Cloud Shell界面   
   ![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000001973746120.png "点击放大")
   当作业处于非运行状态或权限不足时会导致无法使用Cloud Shell，请根据提示定位原因即可。
   图2报错提示   
   ![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000001973586360.png "点击放大")
   ![](https://support.huaweicloud.com/develop-modelarts/public_sys-resources/note_3.0-zh-cn.png)
   部分用户登录Cloud Shell界面时，可能会出现路径显示异常情况，此时在Cloud Shell中单击回车键即可恢复正常。
   图3路径异常   
   ![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000001973586356.png "点击放大") 
 
#### 如何使训练作业保持运行中状态
由于需要训练作业处于"运行中"状态才能登录Cloud Shell，因此本文介绍如何使训练作业保持运行中状态，方便您快速通过Cloud Shell登录运行中的训练容器。
**通过在创建训练作业中配置保留时长使训练作业保持运行**
当用户在配置自定义作业时选择专属资源池时，支持在作业中"更多配置"选项勾选"保留时长"开关，选择保留时长，训练作业即可保持运行。
图4保留时长   
![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000002624992486.png "点击放大")
**通过Sleep命令使训练作业保持运行**
- 如果训练作业使用的是预置框架： 在创建训练作业时，"创建方式"选择"自定义算法"，"启动方式"选择"预置框架"，代码目录中新增sleep.py并将此脚本作为"启动文件"。这样启动的作业将会持续运行60分钟。您可通过Cloud Shell进入容器进行调试。
  sleep.py示例：
  ```
  import os
  os.system('sleep 60m')
  ```
  图5预置框架启动方式   
  ![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000002010226093.png "点击放大") 
- 如果训练作业使用的是自定义镜像 在创建训练作业时，"创建方式"选择"自定义算法"，"启动方式"选择"自定义"，"启动命令"输入"sleep 60m"。这样启动的作业将会持续运行60分钟。您可通过Cloud Shell进入容器进行调试。
  图6自定义启动方式   
  ![](https://support.huaweicloud.com/develop-modelarts/figure/zh-cn_image_0000001973746116.png "点击放大") 
#### 出错的任务如何卡在运行中状态
创建训练作业时，启动命令末尾新增"\|\| sleep 5h"，并启动训练作业，例如下方的cmd为您的启动命令：
```
cmd || sleep 5h
```
如果训练失败，则会执行sleep命令，此时可通过Cloud Shell登录容器镜像中调试。
![](https://support.huaweicloud.com/develop-modelarts/public_sys-resources/note_3.0-zh-cn.png)
在Cloud Shell中调试多节点训练作业时，需要在Cloud Shell中切换work0、work1来实现对不同节点下发启动命令，否则任务会处于等待其他节点的状态。
#### 如何防止Cloud Shell的Session断开
如果需要长时间运行某一个任务，为避免在期间连接断开导致任务失败，可通过使用screen命令使得任务在远程终端窗口运行。
1. 如果镜像中未安装screen，则执行"apt-get install screen"安装。
2. 创建screen终端。
   ```
   # 使用 -S 创建一个叫name的screen终端 
   screen -S name
   ```
   
3. 显示已创建的screen终端。
   ```
   screen -ls  
   There are screens on: 
   2433.pts-3.linux    (2013年10月20日 16时48分59秒)    (Detached) 
   2428.pts-3.linux    (2013年10月20日 16时48分05秒)    (Detached) 
   2284.pts-3.linux    (2013年10月20日 16时14分55秒)    (Detached) 
   2276.pts-3.linux    (2013年10月20日 16时13分18秒)    (Detached) 
   4 Sockets in /var/run/screen/S-root.
   ```
   
4. 连接"screen_id"为"2276"的screen终端。
   ```
   screen -r 2276
   ```
   
5. 按下"Ctrl"+"a"+"d"键离开screen终端。离开后，screen会话仍将是活跃的，之后可以随时重新连接。
更多Screen使用说明可参考[Screen User's Manual](https://www.gnu.org/software/screen/manual/screen.html#Getting-Started)。
#### 如何保证Cloud Shell与控制台执行训练启动命令的结果一致
- **问题现象**
  在某些场景下，通过控制台输入训练作业启动命令，在启动命令传入后台执行之前，未能正确处理训练作业实例中\~/.bashrc文件在非交互式SSH会话中的额外输出（如欢迎语、调试信息、命令输出等），导致其执行结果与在Cloud Shell中手动执行训练启动命令的结果不一致。
  
- **解决方案**
  您可以在控制台输入框中先加载\~/.bashrc，再执行训练启动命令。如训练作业启动脚本为main.sh，在执行启动脚本前，可以按照如下示例代码执行：
  ```
  source /home/ma-user/.bashrc ; bash ${MA_JOB_DIR}/demo-code/main.sh
  ```
  在执行模型训练脚本之前，先加载\~/.bashrc。.bashrc中的环境变量以及额外输出提前加载运行，运行完毕再执行训练启动脚本，不影响启动命令的执行。
  
 
#### 通过py-spy工具分析卡死进程的调用栈并结合代码分析定位卡死问题
本文指导用户通过py-spy工具分析卡死进程的调用栈并结合代码分析定位卡死问题。
1. 在[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，选择"模型开发与训练 \> 模型训练"（旧版控制台："模型训练 \> 训练作业"）。
2. 在训练作业详情页面，选择Cloud Shell页签，登录训练容器（训练作业需处于运行中）。
3. 安装py-spy工具。 
   ```
   # 通过utils.sh脚本自动配置python环境
   source /home/ma-user/modelarts/run/utils.sh
   # 安装py-spy
   pip install py-spy
   # 如果超时提示connection broken by 'ProxyError('Cannot connect to proxy.')则表示用户设置了proxy，需要先关掉
   export no_proxy=$no_proxy,repo.myhuaweicloud.com（此处需要替换成对应局点的pip源地址）
   pip install py-spy
   ```
   
   
4. 查看堆栈。py-spy工具的具体使用方法可参考[py-spy官方文档](https://github.com/benfred/py-spy)。
   
   ```
   # 找到训练进程的PID
   ps -ef
   # 查看进程12345的进程堆栈
   # 如果是8卡的训练作业，一般用此命令依次去查看主进程起的对应的8个进程的堆栈情况
   py-spy dump --pid 12345
   ```
   
   
 
