# 使用预置镜像制作自定义镜像用于训练模型
#### 使用预置框架构建自定义镜像原理介绍
如果先前基于预置框架且通过指定代码目录和启动文件的方式来创建的训练作业；但是随着业务逻辑的逐渐复杂，您期望可以基于预置框架修改或增加一些软件依赖的时候，可以使用预置框架构建自定义镜像，即在创建训练作业页面选择预置框架名称后，在预置框架版本下拉列表中选择"自定义"。
该方式的训练流程与直接基于预置框架创建的训练作业相同，例如：
- 系统会自动注入一系列环境变量，如下所示。
  - PATH=${MA_HOME}/anaconda/bin:${PATH}
  
  - LD_LIBRARY_PATH=${MA_HOME}/anaconda/lib:${LD_LIBRARY_PATH}
  
  - PYTHONPATH=${MA_JOB_DIR}:${PYTHONPATH}
   
- 选择的启动文件将会被系统自动以python命令直接启动，因此请确保镜像中的Python命令为您预期的Python环境。通过系统自动注入的PATH环境变量，可以参考下述命令确认训练作业最终使用的Python版本。
  - export MA_HOME=/home/ma-user; docker run --rm {image} ${MA_HOME}/anaconda/bin/python -V
  
  - docker run --rm {image} $(which python) -V
   
- 系统会自动添加预置框架关联的超参。
 
#### 使用预置框架构建训练镜像
ModelArts平台提供了Tensorflow，PyTorch，MindSpore等常用深度学习任务的基础镜像，镜像里已经安装好运行任务所需软件。当基础镜像里的软件无法满足您的程序运行需求时，您可以基于这些基础镜像制作一个新的镜像并进行训练。
您可以参考如下步骤基于训练基础镜像来构建新镜像。
1. 安装Docker。如果**docker images** 命令可以执行成功，表示Docker已安装，此步骤可跳过。
   以linux x86_64架构的操作系统为例，获取Docker安装包。您可以使用以下指令安装Docker。
   ```
   curl -fsSL get.docker.com -o get-docker.sh
   sh get-docker.sh
   ```
   
2. 准备名为context的文件夹。
   ```
   mkdir -p context
   ```
   
3. 准备可用的pip源文件pip.conf 。本示例使用华为开源镜像站提供的pip源，其pip.conf文件内容如下。
   ```
   [global]
   index-url = https://repo.huaweicloud.com/repository/pypi/simple
   trusted-host = repo.huaweicloud.com
   timeout = 120
   ```
   ![](https://support.huaweicloud.com/docker-modelarts/public_sys-resources/note_3.0-zh-cn.png)
   在华为开源镜像站https://mirrors.huaweicloud.com/home中，搜索pypi，可以查看pip.conf文件内容。
   
4. 参考如下Dockerfile文件内容来基于ModelArts提供的训练基础镜像来构建一个新镜像。将编写好的Dockerfile文件放置在context文件夹内。训练基础镜像地址请参见[ModelArts统一镜像](https://support.huaweicloud.com/docker-modelarts/docker-modelarts_6022.html)。
   ```
   FROM {ModelArts提供的训练基础镜像地址}
   # 配置pip
   RUN mkdir -p /home/ma-user/.pip/
   COPY --chown=ma-user:ma-group pip.conf /home/ma-user/.pip/pip.conf
   # 设置容器镜像预置环境变量
   # 将python解释器路径加入到PATH环境变量中
   # 请务必设置PYTHONUNBUFFERED=1, 以免日志丢失
   ENV PATH=${ANACONDA_DIR}/envs/${ENV_NAME}/bin:$PATH \
       PYTHONUNBUFFERED=1
   RUN /home/ma-user/anaconda/bin/pip install --no-cache-dir numpy
   ```
   
5. 构建新镜像。在Dockerfile文件所在的目录执行如下命令构建容器镜像training:v1。
   ```
   docker build . -t training:v1
   ```
   
6. 将构建好的新镜像上传至SWR。
   1. 登录[容器镜像服务控制台](https://console.huaweicloud.com/swr/#/swr/dashboard)，选择区域。
   
   2. 在控制台主页面单击"创建组织"，输入组织名称完成组织创建。您可以自定义组织名称，本示例使用"deep-learning"，实际操作时请重新命名一个组织名称。后续所有命令中使用到组织名称deep-learning时，均需要替换为此处实际创建的组织名称。
   
   3. 创建完毕后，在控制台主页面单击"登录指令"，获取登录访问指令。以root用户登录ECS环境，输入登录指令，具体可参考[在ECS上构建自定义镜像并在Notebook中使用](https://support.huaweicloud.com/docker-modelarts/docker-modelarts_0011-0.html)。
      图1在ECS中执行登录指令   
      ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002556251304.png "点击放大") 
   
   4. 登录SWR后，使用**docker tag** 命令给上传镜像打标签。下面命令中的组织名称deep-learning，请替换为[上文]中实际创建的组织名称，以下所有命令中的deep-learning都需要替换。
      ```
      sudo docker tag tf-1.13.2:latest swr.实际域名.com/deep-learning/tf-1.13.2:latest
      ```
      
   
   5. 使用**docker push** 命令上传镜像。
      ```
      sudo docker push swr.实际域名.com/deep-learning/tf-1.13.2:latest
      ```
      
   
   6. 完成镜像上传后，在"容器镜像服务控制台\>我的镜像"页面可查看已上传的自定义镜像。 "swr.\<region\>.myhuaweicloud.com/deep-learning/tf-1.13.2:latest"即为此自定义镜像的"SWR_URL"。
      
    
7. 在ModelArts上创建训练作业。
   1. 登录[ModelArts管理控制台](https://console.huaweicloud.com/modelarts/)，在左侧导航栏按需选择以下操作。
      - 新版控制台：选择"模型开发与训练 \> 模型训练"，进入训练作业列表。
      
      - 旧版控制台：选择"模型训练 \> 训练作业"，进入训练作业列表。
      
      - 单击"创建训练作业"，进入创建训练作业页面，填写作业信息。根据新版和旧版控制台不同，配置方法如下：
        - 新版控制台：创建方式参考[表1]，其他创建训练任务参数参考[创建自定义训练作业](https://support.huaweicloud.com/develop-modelarts/develop-modelarts-0006.html)。
           表1训练配置 
          | 参数名称      | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
          |:---|:---|
          | 预置模板（可选） | 单击"选择预置模板"，根据需求过滤预置模板的类型（当前支持文本生成和图像理解）、品牌（当前支持Qwen），选择模板。 选择预置模板后，部分模板将自动填充当前作业的描述（可选）、选择镜像、启动命令、代码目录、本地代码目录和环境变量等。请以实际情况为准。 用户也可在此基础上进行调整配置。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
          | 选择镜像      | 指定运行训练代码的容器镜像，有以下两种镜像： **预置镜像：**选择平台提供的常用框架镜像（如PyTorch 1.8、TensorFlow 2.1），适合大多数常见场景。 **自定义镜像：**选择使用您自己制作并推送至SWR镜像仓库的镜像或已注册镜像。 - 支持在SWR基础版和企业版的仓库中选择镜像。  - 已注册镜像：用户在ModelArts的"资产管理 \> 镜像"中已注册的镜像。   当平台预置的基础镜像无法满足您的依赖需求时，支持自定义镜像进行训练，所需镜像需提前注册到ModelArts镜像管理上。                                                                                                                                                                                                    |
          | 启动命令     | 容器启动后执行的命令，用以启动您的训练脚本。 - 如果训练启动脚本用的是py文件，例如"train.py"，则启动命令如下所示。 ``` python ${MA_JOB_DIR}/demo-code/train.py ```   - 如果训练启动脚本用的是sh文件，例如"main.sh"，则启动命令如下所示。 ``` bash ${MA_JOB_DIR}/demo-code/main.sh ```    启动命令支持使用";"和"\&\&"拼接多条命令，命令中的"demo-code"为存放代码目录的最后一级OBS目录，以实际情况为准。 说明： 为保证数据安全，请勿输入敏感信息，例如明文密码。                                                                                                                                                                                                                                                     |
          | 代码目录（可选）   | 选择训练代码文件所在的OBS目录。当"选择镜像"选择"预置镜像"时，该参数必填；当"选择镜像"选择"自定义镜像"时，该参数可选。用户自己的OBS桶可以在界面选择，也可以手动输入路径，路径格式以"obs://"开头并以"/"结尾，例如"obs://bucketname/path/"。其他人的共享桶路径仅支持手动输入地址。obs桶中后缀为.txt、.py、.sh、.yaml的文件可以在线编辑，后缀为.log、.json、.md的文件可以在线查看。 - 需要提前将代码上传至OBS桶中，目录内文件总大小必须小于或等于5GB，文件数必须小于或等于1000个，文件深度必须小于或等于32。如果有预训练模型也请放置在代码目录下。  - 训练代码文件会在训练作业启动的时候被系统自动下载到训练容器的"${MA_JOB_DIR}/demo-code"目录中，"demo-code"为存放代码目录的最后一级OBS目录。例如，"代码目录"选择的是"obs://test/code"，则训练代码文件会被下载到训练容器的"${MA_JOB_DIR}/code"目录中。   |
          | 代码备份目录（可选） | 选择将**代码目录**下的文件备份到指定OBS目录。 - 需要提前创建obs目录。比如obs中创建目录为obs://test/record-dir。  - 训练作业启动的时候会自动地将训练容器本地代码最后一级**文件** **夹** 及文件夹中的**所有** **文件** 备份至${MA_RECORD_CODE_DIR_OBS}/${ma_job_name}-${MA_TASK_NAME}-${task_index}/user-job-dir/demo-code，demo-code为训练容器中本地代码目录的最后一级文件夹名称。 例如，代码备份目录选择的是obs://test/record-dir，训练容器中本地代码目录默认是/home/ma-user/modelarts/user-job-dir/test-code，则训练容器中本地代码文件夹test-code及test-code文件夹下的文件会被备份至obs://test/record-dir/${ma_job_name}-${MA_TASK_NAME}-${task_index}/user-job-dir/test-code目录中。                                                                                                 |
          | 本地代码目录    | 用于指定训练容器的本地目录，启动训练时系统会将代码目录下载至此目录，默认本地代码目录为"/home/ma-user/modelarts/user-job-dir"。 本地代码目录不支持在/home/ma-user/modelarts/\*，/home/ma-user/modelarts-dev/\*，/home/ma-user/infer/\*目录下，也不支持配置成/home/ma-user。 单击右侧的"运行环境预览"，可以查看训练作业的工作目录。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
          | 环境变量       | 根据业务需求增加环境变量。训练容器中预置的环境变量请参见[管理训练容器环境变量](https://support.huaweicloud.com/develop-modelarts/develop-modelarts-0104.html)。 - 单击"添加"，添加环境变量信息，总数不超过100条。  - 单击"本地上传"可以本地批量导入环境变量，需要按模板填写环境变量且总数不能超过100条，否则会导入失败。   说明： 为保证数据安全，请勿输入敏感信息，例如明文密码。                                                                                                                                                                                                                                                                                                                             |
             
          
        
        - 旧版控制台：创建方式参考[表2]，其他参数填写请参考[创建生产训练作业](https://support.huaweicloud.com/develop-modelarts/develop-modelarts-0022.html)。
           表2创建训练作业的创建方式（使用自定义镜像） 
          | 参数名称  | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
          |:---|:---|
          | 创建方式  | 必选，选择"自定义算法"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
          | 启动方式  | 必选，选择"自定义"。 ![](https://support.huaweicloud.com/docker-modelarts/figure/zh-cn_image_0000002631402738.png "点击放大")                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
          | 镜像    | 必填，单击右边的"选择"，从容器镜像中选择[将构建好的新镜像上传至SWR。]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
          | 代码目录 | 选择训练代码文件所在的OBS目录。如果自定义镜像中不含训练代码则需要配置该参数，如果自定义镜像中已包含训练代码则不需要配置。 - 需要提前将代码上传至OBS桶中，目录内文件总大小要小于或等于5GB，文件数要小于或等于1000个，文件深度要小于或等于32。  - 训练代码文件会在训练作业启动的时候被系统自动下载到训练容器的"${MA_JOB_DIR}/demo-code"目录中，"demo-code"为存放代码目录的最后一级OBS目录。例如，"代码目录"选择的是"obs://test/code"，则训练代码文件会被下载到训练容器的"${MA_JOB_DIR}/code"目录中。   |
          | 运行用户ID | 容器运行时的用户ID，该参数为选填参数，建议使用默认值1000。 如果需要指定uid，则uid数值需要在规定范围内，不同资源池的uid范围如下： - 公共资源池：1000-65535  - 专属资源池：0-65535                                                                                                                                                                                                        |
          | 启动命令   | 必填，镜像的启动命令。 运行训练作业时，当"代码目录"下载完成后，"启动命令"会被自动执行。 - 如果训练启动脚本用的是py文件，例如"train.py"，则启动命令如下所示。 ``` python ${MA_JOB_DIR}/demo-code/train.py ```   - 如果训练启动脚本用的是sh文件，例如"main.sh"，则启动命令如下所示。 ``` bash ${MA_JOB_DIR}/demo-code/main.sh ```    启动命令支持使用";"和"\&\&"拼接多条命令，命令中的"demo-code"为存放代码目录的最后一级OBS目录，以实际情况为准。                |
          | 本地代码目录 | 指定训练容器的本地目录，启动训练时系统会将代码目录下载至此目录。 此参数可选，默认本地代码目录为"/home/ma-user/modelarts/user-job-dir"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
          | 工作目录   | 训练时，系统会自动cd到此目录下执行启动文件。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
             
          
         
       
    
 
