图文讲解Atlas 500适配yolov5进行物体检测丨【我的华为云体验之旅】
1 yolov5模型概述
yolov5是 YOLO算法 (You Only Look Once)的第5个版本,YOLO可以说是当前实时对象检测算法中的佼佼者,它由Redmon等人在2016年的一篇论文中命名的,目前广泛应用于多种AI 目标对象检测场景中,可以非常方便的检测出图像中的对象类别,比如人、车、动物等。虽然在某些场景下, yolov4的算法推理精度优于目前的yolov5,但是yolov5的某些新特征却更加具有吸引力。比如,yolov5在检测平均精度降低不多的基础上,具有推理模型文件更小,训练时间和推理速度更短的特点,这样在对精度要求不高的情况下,采用yolov5在模型构建、模型部署等方面将更加方便,而且推理速度更快。
官网源码地址路径为: https://github.com/ultralytics/yolov5 ,在官网上也给出了yolov5 (6.0 releases)不同模型(YOLOv5s、YOLOv5m和 YOLOv5n 等)的速度分析对比图,具体如下所示:
官网也给出了不同的releases版本文件,可以访问网址 https://github.com/ultralytics/yolov5/releases 来查看。目前最新的为6.0,但考虑到需要和Atlas 500智能小站适配,这里选择 4.0 及以下版本。下面给出 4.0 releases的各权重文件的分析对比图,如下所示:
从上图可以看出,YOLOv5s的权重文件(params)只有7.3M,而且推理速度最快为2.2ms 。但是精度是最差的,YOLOv5m的权重文件为21.4M,而且推理速度为2.9ms 。推理精度最好的为YOLOv5x ,但权重文件为87.7M 。因此,YOLOv5s更适合在移动设备上进行部署。关于选择什么权重文件,需要根据自己的部署环境和精度要求来具体分析。
2 Atlas 500 智能小站概述
基于华为Ascend处理器开发AI应用程序,一般需要搭建开发环境和运行环境。开发环境可以在非昇腾设备和昇腾设备上进行搭建。而运行环境则需要在昇腾AI设备上进行搭建。其中的 Atlas 500 是华为面向广泛边缘应用场景的轻量边缘设备,具有超强计算性能、大容量存储、配置灵活、体积小、支持温度范围宽、环境适应性强、易于维护管理等特点。它主要应用在智能视频监控、分析、数据存储等应用场景,可以广泛部署在各类边缘、中心机房,满足在社区、园区、商场、超市等复杂环境区域的应用。关于各类硬件设备,可以参考官网:https://www.hiascend.com/document?tag=hardware 。
其中的华为Atlas 500小站硬件的官网地址如下:https://support-it.huawei.com/server-3d/res/server/atlas500/index.html 华为Atlas 500小站示意图如下:
官网给出的产品特定如下:
边缘场景易用性
实时性:它可以在本地处理数据,提供实时的响应。
低带宽:只将必要的信息传送到云上。
隐私保护:客户可以决定要传送到云上和保留在本地的信息。所有传送到云上的信息都是可以加密的。
16路视频分析和存储能力
支持16路视频分析能力(最大16路1080p解码,22TOPS INT8算力)。
支持12TB存储容量,16路1080p@4Mb码流视频缓存7天,8路1080p@4Mb码流视频缓存30天。
极强环境适应能力,边缘环境部署
工业防护等级:IP40。
无风扇设计,支持-40℃~+70℃宽温度工作环境。
灵活选配,无线回传
支持选配3G或4G模块(无线回传)。
可靠性高
系统内所有固件均有双镜像备份,故障时可自动进行主备区切换。
支持软件、硬件故障检测与告警。
提供双机解决方案,内置双机备份软件,支持两台Atlas 500 智能小站组成双机备份系统,单台Atlas 500 智能小站故障时自动发起倒换。
3 Atlas 500 yolov5 适配过程
Atlas 500 智能小站自带的欧拉操作系统,在模型迁移和安装相关库方面相对来说,较为繁琐。因此,我们可以通过制作Docker镜像来部署。关于如何在Atlas 500 上构建Docker镜像,可以参考之前的博文《华为Atlas 500小站Docker镜像制作》,这里不再赘述。首先我们需要用SSH 来登录Atlas 500 ,成功登录后,首先查看一下制作的镜像文件,可以输入 docker images 来查看,示例如下所示:
Euler:/opt/mount/docker05 # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
workload-image v1.0 5533b1d161d8 4 weeks ago 585MB
ubuntu 18.04 7266638574fb 2 months ago 56.6MB
k8s.gcr.io/pause latest 3df7a9f2d9f8 16 months ago 1.57MB
其中的 workload-image 为制作的镜像文件,下面启动该镜像,并指定 -v 参数来挂载宿主机目录到Docker 容器中,这样二者可以共享一些目录和存储。其中的/home/data/miniD/driver/lib64 为 Atlas 500 智能小站的NPU驱动,npu-smi 工具可以查看npu相关信息,可以用来验证NPU芯片是否可用。启动Docker容器命令如下所示:
docker run --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 \
-v /opt/mount/docker05:/opt/mount/docker05 \
-it workload-image:v1.0 bash
正常启动后,会切换到Docker容器中,首先输入如下命令进行NPU状态查看:
root@c25e51b32a55:~# npu-smi info
显示信息如下则表示NPU可以使用,可以进行下一步操作。经过实际操作,发现Atlas 500只能有一个Docker容器可以使用NPU资源。npu-smi info 显示结果如下所示:
其中的 NPU Chip 代表 NPU芯片,这里的device id 为 0 ,Name Device 为 310 ,代表华为Ascend 310 。Health Bus-Id 为 OK ,则说明正常可以使用。下面需要安装PyACL 相关的依赖项,执行如下命令:
#更新
apt-get update
#安装 pip3
apt-get install python3-pip
# 只能用python3.6 进行安装python依赖库
python3.6 -m pip install --upgrade pip --user -i https://mirrors.huaweicloud.com/repository/pypi/simple
python3.6 -m pip install Cython numpy tornado==5.1.0 protobuf --user \
-i https://mirrors.huaweicloud.com/repository/pypi/simple
# 安装 wget
apt-get install wget
# 安装 vim
apt-get install vim
# 安装opencv-python
python3.6 -m pip install opencv-python==4.5.4.60 --user -i https://mirrors.huaweicloud.com/repository/pypi/simple
# fix ImportError: libGL.so.1
apt install libgl1-mesa-glx
成功安装后,可以输入如下命令进行验证,如果在python交互环境中,可以成功导入 import cv2 则说明 OpenCV依赖安装成功,具体示意如下所示 :
root@c25e51b32a55:~# python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> print(cv2.__version__)
4.5.4
>>>
然后继续安装 ffmpeg 以及相关依赖项,执行如下命令 :
apt-get install -y libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev
apt-get install pkg-config libxcb-shm0-dev libxcb-xfixes0-dev
#安装 av 库
python3.6 -m pip install av==6.2.0 -i https://mirrors.huaweicloud.com/repository/pypi/simple
apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk
# 安装 x264 x265
apt-get install x264 x265
# 安装PIL和 requests
python3.6 -m pip install Pillow requests -i https://mirrors.huaweicloud.com/repository/pypi/simple
# 安装numpy
python3.6 -m pip install numpy -i https://mirrors.huaweicloud.com/repository/pypi/simple
# 安装 ffmpeg
apt-get install ffmpeg
最后,配置一下环境变量,执行如下命令 :
vi ~/.bashrc
在末尾添加如下配置 :
export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/atc/lib64:/usr/local/Ascend/nnrt/latest/acllib/lib64:/home/data/miniD/driver/lib64:$LD_LIBRARY_PATH
export PATH=/usr/local/Ascend/ascend-toolkit/latest/atc/bin:/usr/local/Ascend/ascend-toolkit/latest/atc/ccec_compiler/bin:$PATH
export PYTHONPATH=/usr/local/Ascend/ascend-toolkit/latest/toolkit/python/site-packages:/usr/local/Ascend/ascend-toolkit/latest/atc/python/site-packages:/usr/local/Ascend/nnrt/latest/pyACL/python/site-packages/acl:$PYTHONPATH
export ASCEND_AICPU_PATH=/usr/local/Ascend/nnrt/latest:$ASCEND_AICPU_PATH
export ASCEND_OPP_PATH=/usr/local/Ascend/ascend-toolkit/latest/opp
export TOOLCHAIN_HOME=/usr/local/Ascend/ascend-toolkit/latest/toolkit:${TOOLCHAIN_HOME}
以上路径位置,需要根据自己的实际情况来进行调整。为了更好的后续进行部署,不要重新进行环境配置,这里将容器镜像导出为文件,可以进行备份,以后可以基于导出的文件来进行还原。执行如下命令 :
# 将id为c25e51b32a55的容器提交改变到atlas500-python:v2.0 镜像
docker commit c25e51b32a55 atlas500-python:v2.0
# 将atlas500-python:v2.0 镜像导出为atlas500-python-opencv4.5-ffmepg.tar 文件
docker save -o atlas500-python-opencv4.5-ffmepg.tar atlas500-python:v2.0
这样我们可以通过相关命令,将这个文件通过 Atlas 500 的临时文件目录(貌似大小为2G左右)拷贝到其他环境中,下面的命令可以参考:
# 拷贝到临时目录
Euler:/opt/mount/docker05 # cp atlas500-workload-image.tar /tmp
#修改权限,这样可以通过sftp进行下载
Euler:/opt/mount/docker05 # chmod 777 /tmp/*
# 启动Docker 容器
Euler:/opt/mount/docker05 # docker start c25e51b32a55
# 进入Docker 容器
Euler:/opt/mount/docker05 # docker attach c25e51b32a55
root@c25e51b32a55:~#
另外,需要在Docker容器中执行如下命令,来安装一些辅助工具:
#vim 中文乱码解决方法
vi /etc/vim/vimrc
################添加如下配置 #########
set fileencodings=utf-8,gb2312,gbk,gb18030
set termencoding=utf-8
set encoding=prc
#####################################
# 安装 ping 工具
apt-get install -y inetutils-ping
下面需要准备适配需要的相关软件,这里需要使用ATC工具进行模型转换,这个具体过程可以参考《Atlas 500 Docker ATC模型转换镜像搭建》,下面切换到ATC工具所在的Ubuntu环境,由于Atlas 500 CPU 性能比较弱,因此可以在X86机器上进行ATC相关模型的转换工作。下面基于yolov4 4.0版本来进行相关适配操作。首先,登录ATC所在的操作系统,以root用户来进行操作。执行如下命令:
su root
cd mysoft
# 下载 yolov5-4.0
wet https://github.com/ultralytics/yolov5/archive/v4.0.tar.gz
#重命名
mv v4.0.tar.gz yolov5-4.0.tar.gz
#解压
tar -xzf yolov5-4.0.tar.gz
#切换目录
cd yolov5-4.0
#下载权重文件
wget https://github.com/ultralytics/yolov5/releases/download/v4.0/yolov5s.pt
wget https://github.com/ultralytics/yolov5/releases/download/v4.0/yolov5m.pt
下面给出至关重要的一步,修改官网export.py中的源码,将 opset_version= 12 修改为 opset_version= 11 。执行命令如下所示:
vi models/export.py
修改内容如下所示:
执行导出模型操作 ,从 yolov5m.pt 导出为 yolov5m.onnx 模型,具体命令如下所示 :
#onnx >= 1.9 & numpy >= 1.17
python3 -m pip install onnx
python3.6 models/export.py --weights ./yolov5m.pt --img 640 --batch 1
成功执行,此时可以查看生成的文件名称,执行 ls 命令查看文件列表 ,界面如下所示 :
下面对 yolov5m.onnx 模型进行修改,这里执行如下命令:
python3 modify_yolov5.py yolov5m.onnx yolov5m
###########################################
root@jackpc:/home/jack/mysoft/yolov5-4.0# ls
data models train.py yolov5_modified.onnx
detect.py modify_yolov5.py tutorial.ipynb yolov5m.onnx
Dockerfile README.md utils yolov5m.pt
hubconf.py requirements.txt weights yolov5m.torchscript.pt
LICENSE test.py yolov5m.mlmodel
其中的 yolov5_modified.onnx 则为修改过的 onnx 模型。下面需要查看这个模型的可视化结构,vi 新建一个view_onnx.py文件,并执行 python3 -m pip install netron 来安装netron工具。view_onnx.py文件内容如下所示:
# python3 -m pip install netron
import netron
netron.start('./yolov5-4.0/yolov5_modified.onnx')
启动一下netron来查看模型网络结构,执行如下命令:
root@jackpc:/home/jack/mysoft# python3.6 view_onnx.py
Serving './yolov5-4.0/yolov5_modified.onnx' at http://localhost:8080
Running Firefox as root in a regular user's session is not supported....
打开浏览器,输入网址 http://localhost:8080/ 进行访问,这里我们需要从图上找到3个out 节点,并记住其名称 ,这里可能每个模型的名称是不同的,所以需要通过图形来确定。我这里的三个 out 节点截图如下所示:
上述3个图的out node名称分别为 : Conv_324 ;Conv_340 和 Conv_356 。下面给出具体的ATC转换代码:
# ATC环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
# ATC转换,注意--out_nodes 的Conv 名称
atc --model=yolov5_modified.onnx --framework=5 --output=yolov5m_b1
--soc_version=Ascend310 --insert_op_conf=aipp_rgb.cfg
--input_format=NCHW --input_shape="images:1,3,640,640"
--out_nodes="Conv_324:0;Conv_340:0;Conv_356:0"
--output_type="Conv_324:0:FP32;Conv_340:0:FP32;Conv_356:0:FP32"
--log=info
其中 aipp_rgb.cfg 配置文件内容如下所示,可以通过vi 命令创建:
root@jackpc:/home/jack/mysoft/yolov5-4.0# vi aipp_rgb.cfg
###########################
aipp_op {
aipp_mode : static
related_input_rank : 0
input_format : RGB888_U8
csc_switch : false
rbuv_swap_switch : true
src_image_size_w : 640
src_image_size_h : 640
crop : false
min_chn_0 : 0
min_chn_1 : 0
min_chn_2 : 0
var_reci_chn_0 : 0.0039216
var_reci_chn_1 : 0.0039216
var_reci_chn_2 : 0.0039216
}
ATC执行成功后,生成 yolov5m_b1.om 文件,操作过程示意界面如下所示:
将生成的 yolov5m_b1.om 文件拷贝出来,并上传到Atlas 500 上备用。进入上述构建的Docker容器中,然后执行如下命令,解压构建的测试项目:
root@c25e51b32a55:~# mkdir myai
root@c25e51b32a55:~# cd myai
root@c25e51b32a55:~/myai# cp /opt/mount/docker05/pyacl_yolov5.tar .
root@c25e51b32a55:~/myai# ls
pyacl_yolov5.tar
root@c25e51b32a55:~/myai# tar -xvf pyacl_yolov5.tar
root@c25e51b32a55:~/myai# cd pyacl_yolov5
root@c25e51b32a55:~/myai/pyacl_yolov5# ls
acl_demo.py aclnet data model readme.md result.jpg scripts
root@c25e51b32a55:~/myai/pyacl_yolov5#
其中的 yolov5m_b1.om 文件处于 model目录中,acl_demo.py为推理程序的启动文件,内容如下所示:
import cv2
from time import *
from aclnet.net import Net
from aclnet.common import AscendResource
from aclnet.utils import yolov5PostProcess, letterbox
from aclnet.coco128 import *
import sys
classes = 80
img_width = 640
img_height = 640
device_id = 0
anchors = [[(10, 13), (16, 30), (33, 23)], # stride_32
[(30, 61), (62, 45), (59, 119)], # stride_16
[(116, 90), (156, 198), (373, 326)]] # stride_8
if __name__ == "__main__":
with AscendResource(device_id) as aclres:
model = Net(aclres, sys.argv[1])
image = cv2.imread(sys.argv[2])
image = letterbox(image, (img_width, img_height))
begin_time = time()
result = model.run([image])
rects = yolov5PostProcess(result, anchors, img_width, classes)
for rect in rects:
name = get_name_bycls(rect[2])
print("[x1, y1, x2, y2]:", rect[0][0], rect[0][1], rect[1][0], rect[1][1], rect[2] , name, rect[3])
cv2.rectangle(image, (rect[0][0], rect[0][1]), (rect[1][0], rect[1][1]), (0, 255, 0), 1)
cv2.putText(image, name, (rect[0][0], rect[0][1] - 20), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 0, 0), 2)
cv2.imwrite('result.jpg', image)
end_time = time()
print('total run time:', end_time - begin_time)
执行如下命令进行推理:
python3 acl_demo.py ./model/yolov5m_b1.om ./data/test1.jpg
输出信息截图如下所示:
测试输入的test1.jpg经过推理后,会写入result.jpg中 ,将其拷贝出来进行查看:
root@c25e51b32a55:~/myai/pyacl_yolov5# cp result.jpg /opt/mount/docker05/
Euler:/opt/mount/docker05 # cp /opt/mount/docker05/result.jpg /tmp/
Euler:/opt/mount/docker05 # chmod 777 /tmp/result.jpg
写入的result.jpg文件显示如下所示:
最后,给出几个可以参考的且非常有用的华为官方链接 :
https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=118598
https://gitee.com/ascend/samples/tree/master/python/environment
https://www.hiascend.com/zh/software/modelzoo/detail/1/f7338e43cf024ea1851fb46041be1dea
【我的华为云体验之旅】有奖征文火热进行中:https://bbs.huaweicloud.com/activity/CloudStory.html
- 点赞
- 收藏
- 关注作者
评论(0)