Atlas200 RC模式下容器推理构建与部署
1. 构建推理容器镜像
1.1 前提条件
-
容器场景,需用户自行安装docker(版本要求大于等于18.03)。
-
容器OS镜像可从Docker Hub拉取。
-
请按照
表1-1
所示,获取离线推理引擎包与业务推理程序压缩包。
表1-1 所需软件
软件包 说明 获取方法 Ascend-cann-nnrt_{version}_linux-aarch64.run 离线推理引擎包。*{version}*表示软件包版本。 获取链接获取链接 Dockerfile 制作镜像需要。 用户根据业务自行准备 ascend_install.info 软件包安装日志文件 从host拷贝“/etc/ascend_install.info”文件。以实际路径为准。 version.info driver版本信息文件 从host拷贝"/var/davinci/driver/version.info"文件。以实际路径为准。 业务推理程序压缩包 业务推理程序合集,支持tar、tgz格式。业务推理程序的压缩包格式,应为容器内自带的压缩程序支持的格式,且install.sh中解压业务推理程序压缩包的命令请根据实际格式适配。**说明:**容器内的运行用户需具备业务推理程序压缩包的相关权限。 用户根据业务自行准备 install.sh 业务推理程序的安装脚本。 run.sh 业务推理程序的运行脚本。
1.2. 操作步骤
- 将准备的软件包上传到Atlas 200 AI加速模块的同一目录(如“/home/test”)。我这里采用的是21.0.3.1大版本中的Ascend-cann-nnrt_5.0.3.1_linux-aarch64.run版本
- Ascend-cann-nnrt_5.0.3.1_linux-aarch64.run
- ascend_install.info
- version.info
- 业务推理程序压缩包
-
执行以下步骤准备dockerfile文件。
-
以root用户登录Atlas 200 AI加速模块,执行id HwHiAiUser命令查询并记录宿主机上HwHiAiUser用户的UID和GID。
-
进入 1 中软件包上传目录,执行以下命令创建dockerfile文件(文件名示例“Dockerfile”)。
vi Dockerfile
-
写入以下内容后执行
:wq
命令保存内容,内容以Ubuntu Arm操作系统为例。(以下内容仅为编写示例,请用户根据实际情况结合自身理解进行二次开发)
#操作系统及版本号,根据实际修改 FROM ubuntu:18.04 #设置离线推理引擎包参数 ARG NNRT_PKG #设置环境变量 ARG ASCEND_BASE=/usr/local/Ascend ENV LD_LIBRARY_PATH=\ $LD_LIBRARY_PATH:\ $ASCEND_BASE/nnrt/latest/lib64:\ /usr/lib64 ENV ASCEND_AICPU_PATH=$ASCEND_BASE/nnrt/latest #设置进入启动后的容器的目录,本示例以root用户运行为例,如果想使用非root用户运行,可将命令改为WORKDIR /home WORKDIR /root #拷贝离线推理引擎包 COPY $NNRT_PKG . COPY ascend_install.info /etc/ RUN mkdir -p /var/davinci/driver RUN mkdir -p /usr/lib64/aicpu_kernels COPY version.info /var/davinci/driver #安装离线推理引擎包 RUN umask 0022 && \ groupadd -g gid HwHiAiUser && useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser && usermod -u uid HwHiAiUser &&\ chmod +x ${NNRT_PKG} &&\ ./${NNRT_PKG} --quiet --install &&\ rm ${NNRT_PKG} #拷贝业务推理程序压缩包、安装脚本与运行脚本 ARG DIST_PKG COPY $DIST_PKG . COPY install.sh . COPY run.sh /usr/local/bin/ #运行安装脚本 RUN chmod +x /usr/local/bin/run.sh && \ sh install.sh && \ rm $DIST_PKG && \ rm install.sh #创建驱动进程访问目录 RUN mkdir –p /usr/slog #RUN mkdir –p /run/driver #RUN mkdir –p /var/driver #修改目录权限(非root用户运行时需要修改) #RUN chown –R HwHiAiUser: HwHiAiUser /usr/slog/ #RUN chown –R HwHiAiUser: HwHiAiUser /var/driver/ #USER HwHiAiUser
Dockerfile中
groupadd -g gid HwHiAiUser && useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser && usermod -u uid HwHiAiUser &&\
为在容器内创建HwHiAiUser用户。gid、uid为宿主机上HwHiAiUser用户的UID和GID,用户可根据 2.1自行替换,容器内的HwHiAiUser用户的UID和GID需要和宿主机保持一致。
-
在创建Dockerfile文件后,执行以下命令修改Dockerfile文件权限。
chmod 600 Dockerfile
-
“install.sh”脚本与“run.sh”脚本文件准备与dockerfile文件准备操作一致,文件内容如编写示例所示。
-
-
进入软件包所在目录,执行以下命令,构建容器镜像。
docker build -t image-name:tag **–build-arg NNRT_PKG=**nnrt-name **–build-arg DIST_PKG=**distpackage-name .
注意不要遗漏命令结尾的“.”,命令解释如所表1-2示。
表1-2 命令参数说明
参数 说明 image-name:tag 镜像名称与标签,用户可自行设置。 –build-arg 指定dockerfile文件内的参数。 NNRT_PKG nnrt-name为离线推理引擎包名称,注意不要遗漏文件后缀,请用户自行更换。 DIST_PKG distpackage-name为业务推理程序压缩包名称,注意不要遗漏文件后缀,请用户自行更换。 当出现“Successfully built xxx”表示镜像构建成功。
-
构建完成后,执行以下命令查看镜像信息。
docker images
显示示例:
REPOSITORY TAG IMAGE ID CREATED SIZE atlas200-rc-infer 21.0.3 1372d2961ed2 About an hour ago 249MB
1.3.编写示例
install.sh编写示例(请根据实际情况编写):
#!/bin/bash
#进入容器工作目录,本示例以root用户运行为例,如果想使用非root用户运行,可将命令改为cd /home
cd /root
#解压业务推理程序压缩包,请根据压缩包格式适配
tar xf dist.tar
run.sh编写示例(请根据实际情况编写):
#!/bin/bash
#安装后配置
source ~/.bashrc
. /usr/local/Ascend/nnrt/set_env.sh
#启动slogd守护进程
/var/slogd
#启动DMP(设备管理)守护进程
/var/dmp_daemon -I -U 8087 &
#进入业务推理程序的可执行文件所在目录(本示例以root用户运行为例,如果想使用非root用户运行,可将命令改为cd /home/dist)
cd /root/dist
#运行可执行文件
./main -i test.jpg
2. 部署推理容器
根据本文档,我生成了一个21.0.3.1版本的Docker image,你可以通过以下的命令下载到你的DLAP221设备,前提是你的系统版本也是21.0.3.1。
$docker pull shinerchen/atlas200-rc-infer:21.0.3
2.1. 操作步骤
-
以root用户登录Atlas 200 AI加速模块。
-
执行以下命令启动容器镜像(用户请根据实际情况修改)。
docker run -u root -it \
--device=/dev/davinci0 \
--device=/dev/davinci_manager \
--device=/dev/ascend_manager \
--device=/dev/svm0 \
--device=/dev/log_drv \
--device=/dev/event_sched \
--device=/dev/upgrade \
--device=/dev/hi_dvpp \
--device=/dev/memory_bandwidth \
--device=/dev/ts_aisle \
-v /usr/local/Ascend/driver/tools:/usr/local/Ascend/driver/tools \
-v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64 \
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
-v /var/hdc_ppc:/var/hdc_ppc \
-v /etc/hdcBasic.cfg:/etc/hdcBasic.cfg \
-v /sys:/sys \
-v /etc/sudoers:/etc/sudoers/ \
-v /etc/sys_version.conf:/etc/sys_version.conf \
-v /usr/lib64/aicpu_kernels:/usr/lib64/aicpu_kernels \
-v /var/log/npu/conf/slog/slog.conf:/var/log/npu/conf/slog/slog.conf \
atlas200-rc-infer:21.0.3 \
/bin/bash -c "/usr/local/Ascend/driver/tools/minirc_container_prepare.sh;/bin/bash"
docker run -it --device=/dev/davinci0 --device=/dev/davinci_manager --device=/dev/svm0 --device=/dev/log_drv --device=/dev/event_sched --device=/dev/upgrade --device=/dev/hi_dvpp --device=/dev/memory_bandwidth --device=/dev/ts_aisle -v /usr/local/Ascend/driver/tools:/usr/local/Ascend/driver/tools -v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64 -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi -v /var/hdc_ppc:/var/hdc_ppc -v /etc/hdcBasic.cfg:/etc/hdcBasic.cfg -v /etc/rc.local:/etc/rc.local -v /sys:/sys -v /usr/bin/sudo:/usr/bin/sudo -v /usr/lib/sudo/:/usr/lib/sudo/ -v /etc/sudoers:/etc/sudoers/ -v /etc/sys_version.conf:/etc/sys_version.conf atlas200-rc-infer:21.0.3 /bin/bash -c “/usr/local/Ascend/driver/tools/minirc_container_prepare.sh;/bin/bash”
如果以非root用户运行,请将以上命令中的**-c "/usr/local/Ascend/driver/tools/minirc_container_prepare.sh;/bin/bash"修改为-c “sudo /usr/local/Ascend/driver/tools/minirc_container_prepare.sh;/bin/bash”**
注意:不同的NNRT版本,docker run后续跟的指令会有所不同!同时尽量保持容器Image使用的NNRT版本与Host上使用的NNRT的版本一致!!
执行以上命令后,进入“/usr/local/bin”目录,执行run.sh脚本。
表2-12 参数解释
参数 | 参数说明 |
---|---|
–device | 表示映射的设备,davinci0需要根据实际设备名称修改。如果需要映射多个芯片,需要配置多个参数如:–device=/dev/davinci0 --device=/dev/davinci1。 |
atlas200-rc-infer 21.0.3 | 生成的镜像文件。 |
说明
本版本支持多个容器挂载同一块芯片:
-
建议最多不超过16个容器。
-
各容器通过抢占方式获取芯片算力,不支持内存隔离和算力切分。
-
默认关闭device共享模式:
-
请在宿主机上执行以下命令开启device共享:
npu-smi set -t device-share -i 0 -c 0 -d 1
可执行以下命令查询device共享状态:
npu-smi info -t device-share -i 0 -c 0
重启或升级后多容器共享功能关闭。
-
应用程序可调用DCMI接口开启,详情请参考《Atlas 200 AI加速模块 1.0.11及以上DCMI API参考》。
-
2.2. 启动推理
在容器的命令行中运行一下命令:
root@5d463645f1f2:~# run.sh
[Info ][2022-02-22 17:48:09:829320][ResourceManager.cpp InitResource:75] Initialized acl successfully.
[Info ][2022-02-22 17:48:09:896460][ResourceManager.cpp InitResource:84] Open device 0 successfully.
[Info ][2022-02-22 17:48:09:898240][ResourceManager.cpp InitResource:91] Created context for device 0 successfully
[Info ][2022-02-22 17:48:09:902650][ResourceManager.cpp InitResource:102] Init resource successfully.
[Info ][2022-02-22 17:48:09:902953][AclProcess.cpp InitResource:118] Created the acl context successfully.
[Info ][2022-02-22 17:48:09:903586][AclProcess.cpp InitResource:124] Created the acl stream successfully.
[Info ][2022-02-22 17:48:09:918111][ModelProcess.cpp Init:240] ModelProcess:Begin to init instance.
[Info ][2022-02-22 17:48:10:227129][AclProcess.cpp InitModule:87] Initialized the model process module successfully.
[Info ][2022-02-22 17:48:10:239245][AclProcess.cpp InitModule:92] Initialized the cast operator successfully.
[Info ][2022-02-22 17:48:10:239539][AclProcess.cpp InitModule:97] Initialized the argMax operator successfully.
[Info ][2022-02-22 17:48:10:241033][AclProcess.cpp InitModule:103] Loaded label successfully.
[Info ][2022-02-22 17:48:10:253339][AclProcess.cpp WriteResult:278] inference output index: 384
[Info ][2022-02-22 17:48:10:253603][AclProcess.cpp WriteResult:280] classname: 384: 'indri, indris, Indri indri, Indri brevicaudatus',
[Info ][2022-02-22 17:48:10:254320][AclProcess.cpp Process:465] [Process Delay] cost: 12.6347ms.
[Info ][2022-02-22 17:48:10:256725][ModelProcess.cpp DeInit:150] Model[resnet50][0] deinit begin
[Info ][2022-02-22 17:48:10:266301][ModelProcess.cpp DeInit:189] Model[resnet50][0] deinit success
[Info ][2022-02-22 17:48:10:275032][ResourceManager.cpp Release:44] Finalized acl successfully.
root@5d463645f1f2:~# npu-smi info
+------------------------------------------------------------------------------+
| npu-smi 21.0.3.1 Version: 21.0.3.1 |
+-------------------+-----------------+----------------------------------------+
| NPU Name | Health | Power(W) Temp(C) |
| Chip Device | Bus-Id | AICore(%) Memory-Usage(MB) |
+===================+=================+========================================+
| 0 310 | OK | 12.8 47 |
| 0 0 | NA | 0 4751 / 8192 |
+===================+=================+========================================+
root@5d463645f1f2:~#
3. Q&A
问题1:
发现运行docker image后,直接运行npu-smi info发生以下错误,找不到NPU设备
root@f75549a927c5:~# npu-smi info
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.405.381 [dm_udp.c:84][dmp] [__dm_send_msg 84] sendmsg fail:No such file or directory.
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.195 [dm_udp.c:129][dmp] [__dm_udp_send 129] __dm_send_msg: sendto fail.errno=2
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.258 [dm_msg_intf.c:734][dmp] [dm_send_req 734] failed call intf->send_msg, ret = 2
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.323 [dsmi_common.c:566][dmp] [dsmi_send_msg_rec_res 566] call dev_mon_send_request error:27.
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.386 [dsmi_dmp_command.c:644][dmp] [dsmi_cmd_get_board_id 644] dev(0) dsmi_send_msg_rec_res failed, ret = 27.
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.441 [dsmi_common_interface.c:1357][dmp] [dsmi_get_board_id 1357] devid 0 dsmi_cmd_get_board_id failed 27
[ERROR] DRV(12,npu-smi):2021-08-07-05:33:53.406.494 [dsmi_common_interface.c:1410][dmp] [dsmi_get_board_info 1410] devid 0 dsmi_board_id call error ret = 27!
+------------------------------------------------------------------------------+
| npu-smi 21.0.3.1 Version: 21.0.3.1 |
+-------------------+-----------------+----------------------------------------+
| NPU Name | Health | Power(W) Temp(C) |
| Chip Device | Bus-Id | AICore(%) Memory-Usage(MB) |
+===================+=================+========================================+
| 0 310 | OK | 12.8 47 |
| 0 0 | NA | 0 4751 / 8192 |
+===================+=================+========================================+
解决方法:
运行以下命令,或者先运行“run.sh",做一次推理,run.sh脚本中有调用以下命令。
root@a0784e7df16a:~# mkdir -p /usr/slog
root@a0784e7df16a:~# /var/slogd &
root@a0784e7df16a:~# mkdir -p /run/driver
root@a0784e7df16a:~# /var/dmp_daemon -I -U 8087 &
root@a0784e7df16a:~# npu-smi info
+------------------------------------------------------------------------------+
| npu-smi 21.0.3.1 Version: 21.0.3.1 |
+-------------------+-----------------+----------------------------------------+
| NPU Name | Health | Power(W) Temp(C) |
| Chip Device | Bus-Id | AICore(%) Memory-Usage(MB) |
+===================+=================+========================================+
| 0 310 | OK | 12.8 47 |
| 0 0 | NA | 0 4751 / 8192 |
+===================+=================+========================================+
问题2:
我们测试发现偶尔有docker service无法启动的问题,登录以后可以手动启动。
解决方法:
分析有可能是某些依赖的服务没有完全起来,导致的,所以我修改了docker的启动方式,修改/lib/systemd/system/docker.service文件,将启动的Type=notify改为idle。