保姆级教程 - atlas500部署yolov3-tiny检测实时视频流[1] - 内网环境下docker部署atlas500 开发环境

— 本教程详细介绍在华为atlas500智能小站上,部署自己的darknet版本的yolov3-tiny目标检测模型


经过多次踩坑,总结到,还是要多看官方文档,论坛文章仅能作为借鉴。毕竟软件生态版本迭代较快。相关技术文章具有时效性,和您的软件环境也不一定匹配,但还是想系统整理出文章,一起沟通讨论。

本教程主要涉及以下四部分:

  • (一)内网环境下DockerFile构建docker容器,并部署在atlas500(无法访问互联网)

  • (二)原生darknet yolov3-tiny的weight -> om 模型转换教程

  • (三)om模型在atlas500边端部署,实现有效推理

  • (四)前、后处理优化,aipp + dvpp 实现推理流程的速度优化

1、内网环境下atlas500 docker镜像部署开发环境
(1)前言

本文的设备情况:

本文默认读者已经根据500小站用户指南,完成设备上电等前置操作:https://support.huawei.com/enterprise/zh/doc/EDOC1100133176/c6355e39

小站是华为欧拉linux系统(aarch64架构),Ascend310芯片,本文的500完全隔绝外网 (正常的500可以连接外网),也没有apt-get install等方式安装软件,但是小站系统自带docker软件,仅用于模型边缘部署。

uname -a 查看系统架构信息:

Linux Euler 4.19.36-vhulk1907.1.0.h1017.eulerosv2r8.aarch64 #1 SMP Sat Mar 27 10:04:38 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux
(2)镜像构建方式

由于内网部署网络的限制,同时为软件环境修改方便,本文借助其他外网设备,通过DockerFile方式构建docker镜像,再把打包好的镜像文件上传至500小站使用。由于小站是aarch64架构,所用的apt源和开发软件的架构也要是aarch64架构,我们镜像构建和后续的模型转换在另一台可连接外网的atlas200 DK(arrch64)设备上操作。

由于设备不在身边,完全内网环境,通过公网ip远程登录。我们在构建docker时,需要了解后续的开发方式,准备所需软件环境。

经过研究文档发现,在昇腾设备上开发主要有两种方式:

  • 使用MindX SDK推理,MindX SDK是一种插件化编程方式,我理解是一个简化的推理SDK,少量代码开发,拼接几个预定义好的插件就可以实现应用开发,尝试过但遇到一些程序崩溃问题,同时觉得过于模板化,自主性不强,没有使用。
  • 基于ACL架构进行开发,这种算是采用ascend的API进行自主开发编译运行,并不需要从0开发,昇腾的样例仓中有很多参考项目,可以基于昇腾的sample开发:https://gitee.com/ascend/samples,同时参考Ascend的开发工具包 CANN推理的API文档,本文也是这种思路.
(3)镜像构建前置操作

拿到atlas500,可以ssh远程登录后,进入的初始系统是类似启动项,还不是Euler系统:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNNttvNI-1651218446083)(C:\Users\EDZ\Desktop\9a5c2bd8611648b94c56a485147676f.png)]
登录Euler系统之前,我们要在IES界面做一些操作:

  • ssh远程登录a500后,在IES:/ -> 界面,首先输入 sftp enable,终端返回 set enable success,即可开放atlas500的 /tmp 目录,进行远程文件传输。

    但/tmp目录仅有2G空间。并且是临时目录,固件升级等操作会将该目录清空,可仅用于文件传输目录,不可长时间存放文件。博主曾经将代码放到该目录下用Xftp打开文件编辑代码,这样很危险,/tmp被清空没有备份就凉凉了。

  • 重置会话超时时间,否则超时后,ssh会话会自动关闭,远程终端中断。

    在IES界面输入timeout 0 ,终端返回set success;然后输入develop (开发者模式),进入欧拉系统。再输入TMOUT=0:

    Euler:~ # TMOUT=0

    docker --version 查看atlas500 docker信息:

Euler:~ # docker --version
Docker version 18.09.0, build ebc4987

npu-smi info 查看gpu芯片信息:

其中,我的driver固件版本为21.0.4,CANN版本必须和固件版本配套,否则会遇到很多不可预料的问题。关于版本不匹配导致的问题见issues:https://gitee.com/ascend/samples/issues/I532OI?from=project-issue

下载固件时,会有版本的对应关系:https://www.hiascend.com/hardware/firmware-drivers?tag=community

比如下图:CANN的5.0.4版本,必须对应21.0.4的固件版本。但我在使用时发现,社区版的固件更新是滞后的。导致一直在使用低版本的固件,出现很多玄学问题,最后版本匹配后就解决了。

固件升级,选择智能边缘管理系统升级最方便,参考文档:(https://support.huawei.com/enterprise/zh/doc/EDOC1100133173/dede8113)

在构建docker 镜像前我们要确定CANN的版本,本文选用 昇腾CANN社区版(5.0.4.alpha002),后续的操作应严格按照CANN对应的文档来,CANN文档分为训练和推理,请移步: 昇腾CANN社区版(5.0.4.alpha002)(训练)昇腾CANN社区版(5.0.4.alpha002)(推理)

(4)DockerFile 构建docker 镜像

由于a500的网络原因,我们用身边的一台atlas200 dk进行docker 镜像部署,好处在于都是aarch64 架构,感觉构建镜像时会更顺利。用其他linux设备是一样的。

DockerFile基于ubuntu18.04进行构建,包括安装atlas500部署所用的Ascend-cann-nnrt_5.0.4.alpha002_linux-aarch64.run、以及后台AI引擎所需的python依赖、redis、linux所需的必要软件。

在此解释一下CANN分为cann-toolkit 和 cann-nnrt ;区别大致是toolkit包更完整,包含开发,推理训练都可以;nnrt是离线推理引擎包,较为轻量,包含开发、推理应用。像模型转换操作就只能用cann-toolkit包。因为我们只在500部署,所以选用nnrt包。

- Dockerfile文件作为参考

基于sample样例进行开发时,要看清楚软件版本,比如python版本

其中的MindX SDK安装是可选操作,后续的文章没有用到。

其中,以root用户登录小站,执行id HwHiAiUser命令查询并记录宿主机上HwHiAiUser用户的UID和GID。

groupadd -g gid HwHiAiUser && useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser && usermod -u uid HwHiAiUser &&\

为在容器内创建HwHiAiUser用户。gid、uid为宿主机上HwHiAiUser用户的UID和GID,容器内的HwHiAiUser用户的UID和GID需要和宿主机保持一致。

FROM ubuntu:18.04

# 更换aliyun镜像源,安装linux必要的依赖 
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN set -ex && apt-get update -y 2> /dev/null && apt install vim -y 2> /dev/null && apt install sudo -y 2> /dev/null \
	&& apt-get install -y cmake curl g++ pkg-config libxcb-shm0-dev libxcb-xfixes0-dev tesseract-ocr libblas3 liblapack3 liblapack-dev libblas-dev gfortran libhdf5-dev libffi-dev ffmpeg wget

# install redis-server5.0.5
WORKDIR /root
RUN apt-get update && mkdir /root/redis
WORKDIR /root/redis

RUN apt-get install software-properties-common -y \
	&& apt-get update \
	&& apt-get install gcc -y \
	&& apt-get install --reinstall make \
	&& wget http://download.redis.io/releases/redis-5.0.5.tar.gz \
	&& tar zxvf redis-5.0.5.tar.gz
WORKDIR ./redis-5.0.5
RUN make && make install

# 复制配置文件到容器,并运行redis
COPY ./redis.conf /etc/ 
CMD redis-server /etc/redis.conf

#Using douban pipy mirror setup software	
RUN apt-get install python3.6 -y \
        && rm /usr/bin/python3 \
        && ln -s /usr/bin/python3.6 /usr/bin/python3 \
        && apt-get install python3-pip -y \
        && /usr/bin/python3 -m pip install --upgrade pip --user -i https://mirrors.huaweicloud.com/repository/pypi/simple \
	&& /bin/bash -c "source ~/.bashrc"

WORKDIR /home/docker/docker_atlas500/
COPY packages/ ./packages

# 很多库没有在线安装arm版,下载离线包安装, 安装包放在dockerfile同级的packages目录
RUN ls -la ./packages \
	&& echo `pwd` \
	&& echo `ls` \
	&& pip3 install --upgrade pip \
	&& cd packages/requests-offline \
	&& pip3 install certifi-2019.9.11-py2.py3-none-any.whl \
	&& pip3 install chardet-3.0.4-py2.py3-none-any.whl \
	&& pip3 install idna-2.8-py2.py3-none-any.whl \
	&& pip3 install urllib3-1.25.7-py2.py3-none-any.whl \
	&& cd requests-2.22.0 \
	&& cd ../../ \
	&& rm -rf packages/ \
	&& pip3 install opencv-python-headless redis tqdm tzlocal==2.1 pytesseract -i https://pypi.tuna.tsinghua.edu.cn/simple		# 无法直接安装opencv-python,解决方法是安装opencv-python-headless

#设置离线推理引擎包参数
ARG NNRT_PKG
#设置环境变量
ARG ASCEND_BASE=/usr/local/Ascend

ENV LD_LIBRARY_PATH=\
$LD_LIBRARY_PATH:\
$ASCEND_BASE/nnrt/latest/acllib/lib64:\
/home/data/miniD/driver/lib64			# 关联宿主机npu的路径

ENV ASCEND_AICPU_PATH=\
$ASCEND_BASE/nnrt/latest
#设置进入启动后的容器的目录
WORKDIR /root
#拷贝离线推理引擎包
COPY $NNRT_PKG .

#安装CANN离线推理引擎包,此处参考:官方文档,要保证和HwHiAiUser用户的UID和GID一致
RUN umask 0022 && \
    groupadd -g 1001 HwHiAiUser && useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser && usermod -u 1001 HwHiAiUser &&\
    chmod +x ${NNRT_PKG} &&\
    ./${NNRT_PKG} --quiet --install &&\
    rm ${NNRT_PKG}

# Ascend-mindxsdk-mxmanufacture_2.0.1_linux-aarch64(可选)
ARG SDK_PKG

# 设置工作路径
WORKDIR /root
# 安装到home
COPY $SDK_PKG .
# 安装MindX SDK mxmanufacture
RUN chmod +x ${SDK_PKG} &&\
	./${SDK_PKG} --quiet --install &&\
	rm ${SDK_PKG} &&\
	/bin/bash -c "source ~/.bashrc"

docker 镜像构建过程,也可以参考官方文档https://support.huawei.com/enterprise/zh/doc/EDOC1100133176/63895f14

  • dockerfile 构建镜像

在200dk或其他linux设备均可构建镜像:

docker build -t atlas500_last:v5 --build-arg NNRT_PKG=Ascend-cann-nnrt_20.3.0_linux-aarch64.run --build-arg SDK_PKG=Ascend-mindxsdk-mxmanufacture_2.0.1_linux-aarch64.run .

其中,-t指明镜像名和版本号;–build-arg NNRT_PKG=“输入cann-nnrt包的路径” ;–build-arg SDK_PKG= “输入MindX SDK的路径” (可选)

构建镜像结束:

docker images # 查看镜像

  • 将镜像文件导出,通过/tmp目录上传至atlas500

可以看到我的镜像已经很大了,我们在dockerfile中构建时,可以将不用的软件包删除,比如MindX sdk

docker save a920 > atlas500_last.tar		
  • atlas500运行镜像生成容器
docker run --privileged --network=host --device=/dev/davinci0 --device=/dev/davinci_manager --device=/dev/hisi_hdc --device /dev/devmm_svm -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi -v /home/data/miniD/driver/lib64:/home/data/miniD/driver/lib64 -v /run/board_cfg.ini:/run/board_cfg.ini -it atlas500_last:v5 /bin/bash

其中,–privileged开启特权模式,容器才能调用宿主机的npu芯片,即device。

–network=host 开启宿主机的网络映射,容器才能和宿主机一样访问网络。

-it atlas500_last:v5,指明容器的名称: 版本号

  • 简单docker操作

docker ps 查看容器:

如果没有刚生成的容器,可能是挂起了, docker ps --all查看所有容器。

docker start containerID 即可启动容器

Euler:~ # docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
06654b02ee44        atlas500   "/bin/bash"    2 months ago      Up 4 days              gagarin

docker exec -it 0665 /bin/bash 进入容器

进入容器后,检查输入npu-smi info 出现芯片信息,检查相关软件环境,即安装成功。

进行推理之前,需要到容器中CANN的安装目录下,激活环境

我的路径在:

cd /usr/local/Ascend/nnrt/	
source set_env.sh

至此,我们完成atlas上CANN等开发环境的docker镜像部署!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐