华为云AI开发平台ModelArts示例:从 0 到 1 制作自定义镜像并用于训练(Tensorflow+GPU)_云淘科技

本章节介绍如何从0到1制作镜像,并使用该镜像在ModelArts平台上进行训练。镜像中使用的AI引擎是Tensorflow,训练使用的资源是GPU。

本实践教程仅适用于新版训练作业。

场景描述

本示例使用 Linux x86_64 架构的主机,操作系统ubuntu-18.04,通过编写 Dockerfile 文件制作自定义镜像。

目标:构建安装如下软件的容器镜像,并在ModelArts平台上使用GPU规格资源运行训练任务。

ubuntu-18.04
cuda-11.2
python-3.7.13
mlnx ofed-5.4
tensorflow gpu-2.10.0

操作流程

使用自定义镜像创建训练作业时,需要您熟悉 docker 软件的使用,并具备一定的开发经验。详细步骤如下所示:

前提条件
Step1 创建OBS桶和文件夹
Step2 创建数据集并上传至OBS
Step3 准备训练脚本并上传至OBS
Step4 准备镜像主机
Step5 制作自定义镜像
Step6 上传镜像至SWR服务
Step7 在ModelArts上创建训练作业

前提条件

已注册华为帐号并开通华为云,且在使用ModelArts前检查账号状态,账号不能处于欠费或冻结状态。

Step1 创建OBS桶和文件夹

在 OBS 服务中创建桶和文件夹,用于存放样例数据集以及训练代码。需要创建的文件夹列表如表1所示,示例中的桶名称“test-modelarts” 和文件夹名称均为举例,请替换为用户自定义的名称。

创建 OBS 桶和文件夹的操作指导请参见创建桶和新建文件夹。

请确保您使用的 OBS 与 ModelArts 在同一区域。

表1 OBS桶文件夹列表

文件夹名称

用途

“obs://test-modelarts/tensorflow/code/”

用于存储训练脚本文件。

“obs://test-modelarts/tensorflow/data/”

用于存储数据集文件。

“obs://test-modelarts/tensorflow/log/”

用于存储训练日志文件。

Step2 创建数据集并上传至OBS

使用网站https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz,下载“mnist.npz”文件并上传至OBS桶的“obs://test-modelarts/tensorflow/data/”文件夹下。

Step3 准备训练脚本并上传至OBS

准备本案例所需的训练脚本mnist.py,并上传至OBS桶的“obs://test-modelarts/tensorflow/code/”文件夹下。

mnist.py文件内容如下:

import argparse
import tensorflow as tf

parser = argparse.ArgumentParser(description='TensorFlow quick start')
parser.add_argument('--data_url', type=str, default="./Data", help='path where the dataset is saved')
args = parser.parse_args()

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data(args.data_url)
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

model.compile(optimizer='adam',
              loss=loss_fn,
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

Step4 准备镜像主机

准备一台 Linux x86_64 架构的主机,操作系统使用ubuntu-18.04。您可以准备相同规格的 弹性云服务器ECS 或者应用本地已有的主机进行自定义镜像的制作。

购买ECS服务器的具体操作请参考购买并登录弹性云服务器。镜像选择公共镜像,推荐使用ubuntu18.04的镜像。

图1 创建ECS服务器-选择X86架构的公共镜像

Step5 制作自定义镜像

目标:构建安装好如下软件的容器镜像,并使用 ModelArts 训练服务运行。

ubuntu-18.04
cuda-11.1
python-3.7.13
mlnx ofed-5.4
mindspore gpu-1.8.1

此处介绍如何通过编写 Dockerfile 文件制作自定义镜像的操作步骤 。

安装 Docker。

以 Linux x86_64 架构的操作系统为例,获取 Docker 安装包。您可以使用以下指令安装 Docker。关于安装 Docker 的更多指导内容参见 Docker 官方文档。

curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh

如果 docker images 命令可以执行成功,表示 Docker 已安装,此步骤可跳过。

确认 Docker Engine 版本。执行如下命令。

docker version | grep -A 1 Engine

命令回显如下。

 Engine:
  Version:          18.09.0

推荐使用大于等于该版本的 Docker Engine 来制作自定义镜像。

准备名为 context 的文件夹。

mkdir -p context

准备可用的pip源文件 pip.conf 。本示例使用华为开源镜像站提供的pip源,其 pip.conf 文件内容如下。

[global]
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
timeout = 120

在华为开源镜像站 https://mirrors.huaweicloud.com/home 中,搜索 pypi ,也可以查看 pip.conf 文件内容。

下载tensorflow_gpu-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl文件。

使用网站https://pypi.org/project/tensorflow-gpu/2.10.0/#files,下载tensorflow_gpu-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl文件。

下载 Miniconda3 安装文件。

使用地址 https://repo.anaconda.com/miniconda/Miniconda3-py37_4.12.0-Linux-x86_64.sh, 下载 Miniconda3 py37 4.12.0 安装文件(对应 python 3.7.13)。

编写容器镜像Dockerfile文件。

在 context 文件夹内新建名为Dockerfile的空文件,并将下述内容写入其中。

# 容器镜像构建主机需要连通公网

# 基础容器镜像, https://github.com/NVIDIA/nvidia-docker/wiki/CUDA
#
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
# require Docker Engine >= 17.05
#
# builder stage
FROM nvidia/cuda:11.2.2-cudnn8-runtime-ubuntu18.04 AS builder

# 基础容器镜像的默认用户已经是 root
# USER root

# 使用华为开源镜像站提供的 pypi 配置
RUN mkdir -p /root/.pip/
COPY pip.conf /root/.pip/pip.conf

# 拷贝待安装文件到基础容器镜像中的 /tmp 目录
COPY Miniconda3-py37_4.12.0-Linux-x86_64.sh /tmp
COPY tensorflow_gpu-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl /tmp

# https://conda.io/projects/conda/en/latest/user-guide/install/linux.html#installing-on-linux
# 安装 Miniconda3 到基础容器镜像的 /home/ma-user/miniconda3 目录中
RUN bash /tmp/Miniconda3-py37_4.12.0-Linux-x86_64.sh -b -p /home/ma-user/miniconda3

# 使用 Miniconda3 默认 python 环境 (即 /home/ma-user/miniconda3/bin/pip) 安装 tensorflow whl
RUN cd /tmp && \
    /home/ma-user/miniconda3/bin/pip install --no-cache-dir \
    /tmp/tensorflow_gpu-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

RUN cd /tmp && \
    /home/ma-user/miniconda3/bin/pip install --no-cache-dir keras==2.10.0

# 构建最终容器镜像
FROM nvidia/cuda:11.2.2-cudnn8-runtime-ubuntu18.04

COPY MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64.tgz /tmp

# 安装 vim / curl / net-tools / mlnx ofed(依然使用华为开源镜像站)
RUN cp -a /etc/apt/sources.list /etc/apt/sources.list.bak && \
    sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \
    sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \
    echo > /etc/apt/apt.conf.d/00skip-verify-peer.conf "Acquire { https::Verify-Peer false }" && \
    apt-get update && \
    apt-get install -y vim curl net-tools iputils-ping && \
    # mlnx ofed
    apt-get install -y python libfuse2 dpatch libnl-3-dev autoconf libnl-route-3-dev pciutils libnuma1 libpci3 m4 libelf1 debhelper automake graphviz bison lsof kmod libusb-1.0-0 swig libmnl0 autotools-dev flex chrpath libltdl-dev && \
    cd /tmp && \
    tar -xvf MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64.tgz && \
    MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64/mlnxofedinstall --user-space-only --basic --without-fw-update -q && \
    cd - && \
    rm -rf /tmp/* && \
    apt-get clean && \
    mv /etc/apt/sources.list.bak /etc/apt/sources.list && \
    rm /etc/apt/apt.conf.d/00skip-verify-peer.conf

# 增加 ma-user 用户 (uid = 1000, gid = 100)
# 注意到基础容器镜像已存在 gid = 100 的组,因此 ma-user 用户可直接使用
RUN useradd -m -d /home/ma-user -s /bin/bash -g 100 -u 1000 ma-user

# 从上述 builder stage 中拷贝 /home/ma-user/miniconda3 目录到当前容器镜像的同名目录
COPY --chown=ma-user:100 --from=builder /home/ma-user/miniconda3 /home/ma-user/miniconda3

# 设置容器镜像默认用户与工作目录
USER ma-user
WORKDIR /home/ma-user

# 设置容器镜像预置环境变量
# 请务必设置 PYTHONUNBUFFERED=1, 以免日志丢失
ENV PATH=/home/ma-user/miniconda3/bin:$PATH \
    LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH \
    PYTHONUNBUFFERED=1

关于 Dockerfile 文件编写的更多指导内容参见 Docker 官方文档。

下载MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64.tgz。

进入地址https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/,单击“Download”,“Version”选择“5.4-3.5.8.0-LTS”,“OSDistributionVersion”选择“Ubuntu 18.04”,“Architecture”选择“x86_64”,下载MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64.tgz。

将上述 Dockerfile文件、 Miniconda3 安装文件等放置在 context 文件夹内,context 文件夹内容如下。

context
├── Dockerfile
├── MLNX_OFED_LINUX-5.4-3.5.8.0-ubuntu18.04-x86_64.tgz
├── Miniconda3-py37_4.12.0-Linux-x86_64.sh
├── pip.conf
└── tensorflow_gpu-2.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

构建容器镜像。在Dockerfile文件所在的目录执行如下命令构建容器镜像tensorflow:2.10.0-ofed-cuda11.2。

1
docker build . -t tensorflow:2.10.0-ofed-cuda11.2

构建过程结束时出现如下构建日志说明镜像构建成功。

Successfully tagged tensorflow:2.10.0-ofed-cuda11.2

Step6 上传镜像至SWR服务

登录容器镜像服务控制台,选择区域。

图2 容器镜像服务控制台

单击右上角“创建组织”,输入组织名称完成组织创建。请自定义组织名称,本示例使用“deep-learning”,下面的命令中涉及到组织名称“deep-learning”也请替换为自定义的值。

图3 创建组织

单击右上角“登录指令”,获取登录访问指令。

图4 登录指令

以root用户登录本地环境,输入登录访问指令。
上传镜像至容器镜像服务镜像仓库。

使用docker tag命令给上传镜像打标签。

#region和domain信息请替换为实际值,组织名称deep-learning也请替换为自定义的值。
sudo docker tag tensorflow:2.10.0-ofed-cuda11.2 swr.{region-id}.{domain}/deep-learning/tensorflow:2.10.0-ofed-cuda11.2
#此处以华为云cn-north-4为例
sudo docker tag tensorflow:2.10.0-ofed-cuda11.2 swr.cn-north-4.myhuaweicloud.com/deep-learning/tensorflow:2.10.0-ofed-cuda11.2

使用docker push命令上传镜像。

#region和domain信息请替换为实际值,组织名称deep-learning也请替换为自定义的值。
sudo docker push swr.{region-id}.{domain}/deep-learning/tensorflow:2.10.0-ofed-cuda11.2
#此处以华为云cn-north-4为例
sudo docker push swr.cn-north-4.myhuaweicloud.com/deep-learning/tensorflow:2.10.0-ofed-cuda11.2

完成镜像上传后,在“容器镜像服务控制台>我的镜像”页面可查看已上传的自定义镜像。

“swr.cn-north-4.myhuaweicloud.com/deep-learning/tensorflow:2.10.0-ofed-cuda11.2”即为此自定义镜像的“SWR_URL”。

Step7 在ModelArts上创建训练作业

登录ModelArts管理控制台,检查当前账号是否已完成访问授权的配置。如未完成,请参考使用委托授权针对之前使用访问密钥授权的用户,建议清空授权,然后使用委托进行授权。
在左侧导航栏中选择“训练管理 > 训练作业”,默认进入“训练作业”列表。
在“创建训练作业”页面,填写相关参数信息,然后单击“下一步”。

创建方式:选择“自定义算法”。
镜像来源:选择“自定义”。
镜像地址:Step5 制作自定义镜像中创建的镜像。“swr.cn-north-4.myhuaweicloud.com/deep-learning/tensorflow:2.10.0-ofed-cuda11.2”。
代码目录:设置为OBS中存放启动脚本文件的目录,例如:“obs://test-modelarts/tensorflow/code/”,训练代码会被自动下载至训练容器的“${MA_JOB_DIR}/code”目录中,“code”为OBS存放代码路径的最后一级目录,可以根据实际修改。
启动命令:“python ${MA_JOB_DIR}/code/mnist.py” ,此处的“code”为用户自定义的OBS存放代码路径的最后一级目录,可以根据实际修改。
训练输入:点击“增加训练输入”,参数名称设置为“data_path”,选择OBS中存放“mnist.npz”的目录,例如“obs://test-modelarts/tensorflow/data/mnist.npz”,获取方式设置为“超参”。
资源池:选择公共资源池。
资源类型:选择GPU规格。
计算节点个数:1个。
永久保存日志:打开。
作业日志路径:设置为OBS中存放训练日志的路径。例如:“obs://test-modelarts/mindspore-gpu/log/”。

在“规格确认”页面,确认训练作业的参数信息,确认无误后单击“提交”。
训练作业创建完成后,后台将自动完成容器镜像下载、代码目录下载、执行启动命令等动作。

训练作业一般需要运行一段时间,根据您的训练业务逻辑和选择的资源不同,训练时长将持续几十分钟到几小时不等。训练作业执行成功后,日志信息如下所示。

图5 GPU 规格运行日志信息

父主题: 模型训练

同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家