旭日X3派开发板部署自己的yolov5模型

发布时间:2023年12月29日

参考:AI工具链 环境部署地平线X3J3算法工具链手册环境安装

使用Docker环境

在完成Docker环境安装后,需要将无root权限的用户添加到Docker用户组中。参考如下命令:

sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo systemctl restart docker  # CentOS7/Ubuntu
# re-login

如果您使用CPU Docker,请从 地平线天工开物cpu docker hub 获取本节需要使用的CentOS Docker镜像。 CPU镜像文件命名形式为 openexplorer/ai_toolchain_centos_7_xj3:{version}。
如果您使用GPU Docker,请从 地平线天工开物gpu docker hub 获取本节需要使用的Ubuntu Docker镜像。 GPU镜像文件命名形式为 openexplorer/ai_toolchain_ubuntu_gpu_xj3:{version}。
执行命令时将{version}替换为您获取到的版本号。

上述链接打不开,在地平线 XJ3 芯片工具链 版本发布及Filezilla使用教程中可使用wget命令下载:
首先确定一下自己后面要部署的开发板的gcc版本,在开发板的系统桌面中,打开终端,使用命令:gcc --version查看gcc版本,然后可在开发机(个人电脑)下载对应的CPU/GPU Docker。
如个人开发板为gcc(Ubuntu 9.3.0-10ubuntu2) 9.3.0 使用:

wget -c ftp://vrftp.horizon.ai/Open_Explorer_gcc_9.3.0/2.6.2b/horizon_xj3_open_explorer_v2.6.2b-py38_20230606.tar.gz

下载2.6.2版本的OE发布包,
下载好OE发布包后,在发布包所在位置打开终端,输入命令:

docker load -i docker_openexplorer_xxx.tar.gz

根据我的版本,运行:

docker load -i horizon_xj3_open_explorer_v2.6.2b-py38_20230606.tar.gz

出现问题提示:

open /var/snap/docker/common/var-lib-docker/tmp/docker-import-2833119952/horizon_xj3_open_explorer_v2.6.2b-py38_20230606/json: no such file or directory

下载2.5.2版本的OE发布包

wget -c ftp://vrftp.horizon.ai/Open_Explorer_gcc_9.3.0/2.5.2/horizon_xj3_openexplorer_v2.5.2_py38_20230331.tar.gz

下载好OE发布包后,在发布包所在位置打开终端,输入命令:

docker load -i horizon_xj3_openexplorer_v2.5.2_py38_20230331.tar.gz

依然不行,理解有误,docker load -i 可以拉取下载好的离线镜像,而且发现wget下载2.6.2版本的OE包时,终端提示:长度:1362805919 (1.3G) (非正式数据),因此决定使用下载的2.5.2版本。
尝试一下第一种方法,使用OE包,然后运行启动对应Docker的脚本:
因此可以先将OE发布包解压:

tar -xvf horizon_xj3_openexplorer_v2.5.2_py38_20230331.tar.gz

下载对应2.5.2版本的CPU Docker镜像

wget -c ftp://vrftp.horizon.ai/Open_Explorer_gcc_9.3.0/2.5.2/docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38.tar.gz

然后在解压后的OE包的一级目录直接运行以下脚本启动当前OE版本所对应的Docker容器(如果本地没有对应镜像,则脚本会自动从官方Docker hub拉取镜像)(刚才我们下载了离线的CPU Docker镜像):

sh run_docker.sh data

若您想要使用CPU版本Docker镜像则需要增加 cpu 参数:

sh run_docker.sh data/ cpu

运行均不行,查看run_docker.sh,发现其中命令设置的包的命名规则和最近发布的几个OE包好像不太一致,导致不可用。

我尝试直接用docker load -i 拉取下载好的2.5.2版本的CPU Docker镜像docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38.tar.gz

docker load -i docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38.tar.gz

发现在Docker桌面Image中已加载此版本的CPU Docker镜像

在这里插入图片描述下载2.5.2版本对应文档

wget -c ftp://vrftp.horizon.ai/Open_Explorer_gcc_9.3.0/2.5.2/horizon_xj3_openexplorer_v2.5.2_py38_doc.zip

可参考里面手册,里面3.2 宿主机开发环境提到:如果你不习惯基于docker进行开发,你可以在你的宿主机器上直接进行环境安装。既然已经下载了Docker镜像,先尝试一下使用Docker部署。

Docker镜像使用

拉取Docker镜像,使用命令:

docker pull docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

出现信息

Using default tag: latest
Error response from daemon: pull access denied for docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

拉取失败,好像是要登陆才能拉取,点击登陆,又无法访问,账号注册页面也无法访问。

Docker配置阿里云镜像源

首先去阿里云官网,注册登录账号,选择容器镜像服务->实例列表
在这里插入图片描述
在这里可以创建个人实例,根据提示和自己情况创建填写命名空间,仓库名称、摘要等信息创建,在创建实例的镜像仓库可以看到基本信息。
登录阿里云Docker Registry

docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

点击镜像工具->镜像加速器,在此页面可以看到个人的加速器地址和针对不同操作系统的配置镜像加速器的操作文档,按文档操作即可。
之后,在终端运行命令:

docker info

之后终端出现信息:

 Registry Mirrors:
  https://xxx.mirror.aliyuncs.com/
 Live Restore Enabled: false

说明配置阿里云镜像源成功,使用命令:

docker images

查看仓库中镜像,可以看到只有一个hello-world示例镜像

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    9c7a54a9a43c   7 months ago   13.3kB

终端切换到2.5.2版本的CPU Docker镜像所在位置,运行命令:

docker load -i docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38.tar.gz

Loaded image: openexplorer/ai_toolchain_ubuntu_20_xj3_cpu:v2.5.2,然后运行命令:

docker images

可以看到已有CPU Docker镜像,IMAGE ID为edb84072ae7b

REPOSITORY                                    TAG       IMAGE ID       CREATED        SIZE
openexplorer/ai_toolchain_ubuntu_20_xj3_cpu   v2.5.2    edb84072ae7b   8 months ago   3.99GB

然后我根据基本信息里的操作指南使用命令:

docker pull registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:[镜像版本号]

镜像版本号替换为我们要使用的镜像

docker pull registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

拉取失败,显示:

Error response from daemon: manifest for registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38 not found: manifest unknown: manifest unknown

我在想是不是阿里云里的仓库是不是没有我们要使用的这个仓库,查看镜像仓库里的镜像版本发现无内容。
在基本信息里的操作指南中,3. 将镜像推送到Registry,使用这个里面的命令并将
[ImageId]替换为edb84072ae7b,镜像版本号替换为我们要使用的镜像,即使用命令:

docker tag edb84072ae7b registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

而后接着输入:

docker push registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

推送成功后,显示:

... 
f5b03de2a7b2: Pushed 
d543b8cad89e: Pushed 
docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38: digest:
...

查看镜像仓库里的镜像版本发现已有docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38。使用下面命令1拉取:

docker pull registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

出现错误:

error during connect: Post "http://%2Fhome%2Ftjuqz%2F.docker%2Fdesktop%2Fdocker.sock/v1.43/images/create?fromImage=registry.cn-hangzhou.aliyuncs.com%2Fswench%2Fopenexplorer&tag=docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38": EOF

去阿里云网站查看镜像仓库,发现阿里云账号登录失效,猜想可能是这个原因。
重新登录后,运行上面提到的命令1拉取镜像,拉取成功。

explorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38
registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview registry.cn-hangzhou.aliyuncs.com/swench/openexplorer:docker_openexplorer_ubuntu_20_xj3_cpu_v2.5.2_py38

运行命令:hb_mapper显示hb_mapper:未找到命令,之前入门指南的文章中提到
后续进行模型转换时,使用horizon_bpu环境,可使用命令 source activate horizon_bpuconda activate horizon_bpu 进入模型转换环境,切换为horizon_bpu环境后,运行:hb_mapper显示:

TypeError: Descriptors cannot be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
 1. Downgrade the protobuf package to 3.20.x or lower.
 2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).

More information: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates

根据提示是可将protobuf版本降至3.20.x或更低,运行以下命令使用清华源镜像安装3.19.0

pip install protobuf==3.19.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

出现提示:

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
horizon-tc-ui 1.18.2 requires protobuf==3.19.4, but you have protobuf 3.19.0 which is incompatible.
onnx 1.15.0 requires protobuf>=3.20.2, but you have protobuf 3.19.0 which is incompatible.

horizon-tc-ui 1.18.2 requires protobuf3.19.4,不过onnx 1.15.0 requires protobuf>=3.20.2,安装protobuf3.19.4,降低onnx版本

pip install protobuf==3.19.4 -i https://pypi.tuna.tsinghua.edu.cn/simple

经过我试验,可安装onnx==1.11.0

pip install onnx==1.11.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

再次运行:hb_mapper显示hb_mapper的用法提示,这个hb_mapper后面进行模型转换会用到:

...
Commands:
  checker    check whether the model meet the requirements.
  infer      inference and dump output feature as float vector.
  makertbin  transform caffe model to quantization model, generate runtime...

准备模型和数据集

打开终端,进入OE包首层路径

cd horizon_xj3_open_explorer_v2.5.2-py38_20230331

也可先进入OE包即horizon_xj3_open_explorer_v2.5.2-py38_20230331文件夹,右键选择打开终端。
然后激活horizon_bpu环境

conda activate horizon_bpu

然后根据教程,下一步是,在OE包中创建data文件夹,/data 为数据集文件目录,如果该目录不存在会导致加载问题,创建好后再运行命令:

// 运行脚本进入CPU docker容器
sh run_docker.sh /data cpu

出现问题:

Docker version is v2.5.2
Dataset path is /home/tjuqz/horizon_xj3_open_explorer_v2.5.2-py38_20230331/data
OpenExplorer package path is /home/tjuqz/horizon_xj3_open_explorer_v2.5.2-py38_20230331
run_docker.sh: 19: [: cpu: unexpected operator
Run in GPU mode
docker: Error response from daemon: unknown or invalid runtime name: nvidia.
See 'docker run --help'.

根据终端中提示信息,查看OE包中的run_docker.sh其中第19行,后面网上查阅得知ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了,执行时可以把sh换成 bash 来执行。

bash run_docker.sh data/ cpu

成功

Docker version is v2.5.2
Dataset path is /home/tjuqz/horizon_xj3_open_explorer_v2.5.2-py38_20230331/data
OpenExplorer package path is /home/tjuqz/horizon_xj3_open_explorer_v2.5.2-py38_20230331
Unable to find image 'openexplorer/ai_toolchain_ubuntu_20_xj3_cpu:v2.5.2' locally
v2.5.2: Pulling from openexplorer/ai_toolchain_ubuntu_20_xj3_cpu
Digest: sha256:e47c6d874426d1bea80b681a8e867ea43b9236aa2b54979d95706eb5f42b85b5
Status: Downloaded newer image for openexplorer/ai_toolchain_ubuntu_20_xj3_cpu:v2.5.2
root@1ff840d9d93f:/open_explorer# 

参考社区帖主的很好的一篇博客文章[BPU部署教程] 一文带你轻松走出模型部署新手村,个人理解run_docker.sh里面语句其实就是将开发机中的一些文件和Docker镜像做一个连接,这样开发机中的文件和文件中数据可以在Docker镜像中使用。

模型

将自己训练转换后的yolov5模型xxx.onnx(根据自己模型名称替换)放置在OE包中创建的data文件夹下,
然后在终端运行cd data即:

root@1ff840d9d93f:/open_explorer# cd data

验证模型

使用hb_mapper checker后面跟对应参数对模型进行验证,可参考上面博客文章和之前入门指南文章提到的yolov5s_v2.0文件夹下的04_detection下03_yolov5s下mapper中的01_check_X3.sh里面命令,接着运行命令:

hb_mapper checker --model-type onnx --model xxx.onnx --march bernoulli2

命令行出现:

...
...
INFO End model checking....

无其他错误提示信息,应该是没有问题的,模型检查过程中的输出信息保存在hb_mapper_checker.log文件中,可查看具体输出信息。

转换模型准备

转换模型需要配置目标的yaml文件,入门指南文章提到的yolov5s_v2.0文件夹下的yolov5s_config_X3.yaml和02_preprocess.sh和data_preprocess.py可作为参考
将yolov5s_config_X3.yaml复制到data文件夹下,并新建model_output文件夹存放转换后的可上板使用的模型、calibration_data_rgb_f32文件夹存放模型校准所需数据。
修改yolov5s_config_X3.yaml中onnx_model: ‘./xxx.onnx’;output_model_file_prefix: ‘xxx_672x672_nv12’,input_shape: ‘1x3x640x640’(训练模型时,自己使用的图片统一resize到了640x640)
具体查看yolov5s_config_X3.yaml中注释和各参数含义,根据自己所用模型进行修改。

准备校准数据

yolov5s_v2.0文件夹中的参考使用的是coco数据集,将自己训练模型使用的数据(选择了50张作为校准数据)放在/ddk/samples/ai_toolchain/horizon_model_convert_sample/04_detection/03_yolov5s/mapper下的coco文件夹中,在终端一步步运行下列指令:
首先将进入04_detection/03_yolov5s/mapper

root@1ff840d9d93f:/open_explorer/data# cd ../ddk/samples/ai_toolchain/horizon_model_convert_sample/04_detection/03_yolov5s/mapper

将preprocess中target_size=(300, 300),修改为target_size=(640, 640),(640,640)为训练时使用的图片输入大小,根据自己情况修改。
然后运行02_preprocess.sh

bash 02_preprocess.sh

终端出现:

write:./calibration_data_bgr_f32/1.bgr
write:./calibration_data_bgr_f32/2.bgr
write:./calibration_data_bgr_f32/3.bgr
write:./calibration_data_bgr_f32/5.bgr
write:./calibration_data_bgr_f32/6.bgr
write:./calibration_data_bgr_f32/7.bgr

转换后的数据文件夹为calibration_data_bgr_f32,将其中数据放置到/data/calibration_data_rgb_f32下

转换模型

root@1ff840d9d93f:/open_explorer/ddk/samples/ai_toolchain/horizon_model_convert_sample/04_detection/04_ssd_mobilenetv1/mapper# cd ../../../../../../../data

然后运行:

root@1ff840d9d93f:/open_explorer/data# hb_mapper makertbin --config ./yolov5s_config_X3.yaml          --model-type  onnx

终端出现提示信息:

...
INFO End Model Convert

转换的过程中的输出信息保存在hb_mapper_makertbin.log文件中,可查看具体输出信息;转换后的模型保存在model_output文件夹下。

模型上板运行

在model_output文件夹中右键选择打开终端,将转换后的xxx_672x672_nv12.bin文件复制到之前文章提到的开发板存放模型的文件路径下,使用命令:

sudo cp -i xxx_672x672_nv12.bin /media/tjuqz/rootfs/opt/hobot/model/x3/basic

其中 /media/xxx/rootfs/opt/hobot/model/x3/basic根据开发板的存储卡使用读卡器挂载在你电脑上的位置名称确定,xxx根据自己电脑而定进行替换,可查看文件属性得到。
另外复制几张测试图片到开发板yolov5示例程序文件夹中,如test中含几张测试图片,在test所在文件路径下右键打开终端,使用命令:

sudo cp -r test /media/xxx/rootfs/app/pydev_demo/07_yolov5_sample

运行示例程序

在板端进入app/pydev_demo/07_yolov5_sample文件夹中,修改test_yolov5.py约第39行语句models = dnn.load('../models/xxx_672x672_nv12.bin'),约第48行img_file = cv2.imread (./test/测试图片名称.jpg),约第56行prediction_bbox = postprocess(outputs, model_hw_shape=(640, 640), origin_image = img_file),postprocess.py中约第21行num_classes = 1,约第35~39行为:

=注意==

pred_sbbox = model_output[0].reshape([1, 20, 20, 3, 
																	6]).transpose([0, 3, 1, 2, 4])
pred_mbbox = model_output[1].reshape([1, 40, 40, 3, 
																	6]).transpose([0, 3, 1, 2, 4])
pred_lbbox = model_output[2].reshape([1, 80, 80, 3, 
																	6]).transpose([0, 3, 1, 2, 4])

我使用博主bubbling的1.0分支的代码,使用PascalVOC格式的VOC2017数据集,训练好的模型转换后,改成上面语句,在板子上成功运行了,但识别的一塌糊涂,框画得一言难尽。(现在感觉是模型转onnx过程的问题,后续看看),下篇文章使用官方2.0分支训练部署模型。
对应的语句应该改为下面这样。
=注意==

pred_sbbox = model_output[0].reshape([1, 80, 80, 3, 
																	6]).transpose([0, 3, 1, 2, 4])
pred_mbbox = model_output[1].reshape([1, 40, 40, 3, 
																	6]).transpose([0, 3, 1, 2, 4])
pred_lbbox = model_output[2].reshape([1, 20, 20, 3, 
																	6]).transpose([0, 3, 1, 2, 4])

可以看出其跟图片大小的关系,80 = 640 / 8, 40 = 640 / 16, 20 = 640 / 32,示例使用的图片大小为(672,672)。
右键选择打开终端,使用命令:

sudo python3 ./test_yolov5.py

可以看到检测结果图片result.jpg,可在postprocess.py中约第118行修改结果的名称。

模型调优

终端进入模型所在位置,使用命令:

root@1ff840d9d93f:/open_explorer# cd data/model_output

地平线提供的 hb_perf 以模型转换得到的 ***.bin为输入,可以直接得到模型预期上板性能(不含CPU部分的计算评估),工具使用方式如下:

root@1ff840d9d93f:/open_explorer/data/model_output# hb_perf  xxx.bin

成功运行后会在OE包的/data/model_output/hb_perf_result/xxx_672x672_nv12文件路径下生成评估文件。

=建议先跟教程走一遍,理解模型转换的各个步骤,在/ddk/samples/ai_toolchain/horizon_model_convert_sample/04_detection/03_yolov5s中的代码看一看各个部分的含义,也可在此文件夹下完成模型的转换

文章来源:https://blog.csdn.net/qq_45194239/article/details/134973028
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。