从训练成生成的our.pt到our.onnx再到our.rknn模型转换流程(RK3588全)
- 本文是在前一篇文章的基础上完成的,《yolov8s.pt转换成onxx再转换成rknn模型用于RK3588》,这篇文章,可以转换成功,但是转换后推理结果慢而且乱画框,怀疑是版本太高,与板子版本不匹配。
- 最后决定在板子提供的硬件文档中,找到了部分转换方法,并结合自己在网上搜的内容,成功完成模型转换,并在板子上进行验证。
our.pt转换成our.onnx
这步转换需要用到瑞芯微提供的转换工具
下载airockchip_yolov5
下载地址:https://github.com/airockchip/yolov5
-
该工具的作用如
README_rkopt.md
文件中所述
-
导出onnx的命令是:
python export.py --rknpu --weight yolov5s.pt
,yolov5s.pt是模型权重 -
和
ultralytics_yolov5
官方的不同之处
- 总结:为了能将yolov5用在硬件上,瑞芯微提供了这个转换工具,与
ultralytics_yolov5
官方提供的网络结构有以下三个不同点- 优化 focus/SPPF块,以求在相同的结果下获得更好的性能
- 更改输出节点,从模型中删除post_process。(模型中的
后处理块
不利于量化) - 使用
ReLU
代替SiLU
作为激活层(仅在训练新模型时有效),该代码在yolov5-master\models\common.py
中体现出来。只有用这个代码进行训练的时候,这个激活函数才会被修改。
- 总结:为了能将yolov5用在硬件上,瑞芯微提供了这个转换工具,与
-
本工具是基于https://github.com/ultralytics/yolov5/releases/tag/v7.0改的,该句来自
README_rkopt.md
文件中Source部分的描述。
-
本次演示中使用的pt文件是我们
自己训练生成
的,名为our.pt
创建模型转换环境
大家买板子的时候,厂家都会提供很多文档,其中应该也包含着模型转换的流程,在我们的文档只提供有onnx转rknn的流程(也许有全流程,但我没找到),文档一般都会说明模型转换的环境,如下图所示:
- 我们的文档名称为: Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf
- 位于虚拟机路径:/home/tronlong/RK3588/rk3588_linux_release_v1.2.1/external/rknn-toolkit2/doc
注:但是在实际转换中,有的版本不一样其实也可以
使用lsb_release -a
查看虚拟机版本
这里可以看到我们的虚拟机版本是Ubuntu20.04版本,所以我们需要装左边对应的版本。
在虚拟机中安装环境
打开终端依次执行如下命令
-
安装
Python3 工具及依赖库
sudo apt-get install python3 python3-dev python3-pip sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc
-
安装
virtualenv
工具sudo apt install virtualenv
-
创建虚拟环境
-
在桌面打开终端执行:
virtualenv -p /usr/bin/python3 convert_model
,可以看到我的python版本是3.8.10,符合要求的python为3.8版本,创建的虚拟环境的name
为convert_model
。
-
进入创建的虚拟环境
source convert_model/bin/activate
注: 我把虚拟创建到桌面了,上述命令仅在桌面打开终端时可以用,不然就需要改路径(执行的是convert_model/bin/activate文件)
-
进入LinuxSDK源码
rknn-toolkit2/
目录
cd /home/tronlong/RK3588/rk3588_linux_release_v1.2.1/external/rknn-toolkit2/
-
安装 依赖库,我的python版本是3.8.10,所以这里执行命令
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r doc/requirements_cp38-1.5.0.txt
安装cp38的txt
-
接下来安装 RKNN-Toolkit2
pip3 install packages/rknn_toolkit2-1.5.0+1fa95b5c-cp38-cp38-linux_x86_64.whl
-
-
参考
Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf
文档中的3.1.1 通过pip install命令安装
部分 -
参考
Rockchip_User_Guide_RKNN_Toolkit2_CN-1.5.0.pdf
文档中的3.1.1 通过pip install命令安装
部分
开始转换
-
切换路径到瑞芯微提供的转换工具,如下图所示,我的路径是在
/home/tronlong/RK3588/rk3588_linux_release_v1.2.1/airockchip_yolov5/yolov5-master
- 然后修改
models/yolo.py
文件中的Detect
类中的forward
方法为
注: 经过实验发现,如果不修改原来的def forward(self, x): z = [] # inference output for i in range(self.nl): x[i] = self.m[i](x[i]) # conv return x
forward
方法,推理结果会乱画框。
- 然后修改
-
cd切换到export.py所在的目录下,执行命令
python export.py --rknpu --weight our.pt
这里的our.pt
是我们训练生成的pt。
注: 在运行的过程中,也会有缺少库或者版本不匹配的问题,这个时候针对下载就行了。- 有时库下载不下来,这个需要使用国内镜像下载,网上搜索即可。
-
例如:pip3 install ipython -i https://pypi.tuna.tsinghua.edu.cn/simple
其中的-i https://pypi.tuna.tsinghua.edu.cn/simple
就是添加镜像的意思 -
后边有我创建好的环境库文件
requirements.txt
,可以按照那个创建环境。具体做法:进入创建好的虚拟环境,执行pip install -r requirements.txt
-
- 有时库下载不下来,这个需要使用国内镜像下载,网上搜索即可。
-
最后成功运行,即可生成
our.onnx
文件
使用netron软件可以查看生成的onnx网络结构
our.onnx生成our.rknn
- 切换到
airockchip_yolov5/onnx_rknn
目录下cd ../onnx_rknn/
- 需要修改以下3个地方,我的platform是rk3588,保持不变,onnx存放位置在onnx_models文件夹,rknn_models存放生成的rknn模型,该文件夹可以不用创建,代码检查没有该文件夹则会自行创建
- 完整代码如下所示:
import cv2
import numpy as np
from rknn.api import RKNN
import os
if __name__ == '__main__':
platform = 'rk3588'
Width = 640
Height = 640
MODEL_PATH = './onnx_models/our.onnx'
NEED_BUILD_MODEL = True
# Create RKNN object
rknn = RKNN()
OUT_DIR = "rknn_models"
RKNN_MODEL_PATH = './rknn_models/our.rknn'
if NEED_BUILD_MODEL:
DATASET = './dataset.txt'
rknn.config(mean_values=[[0, 0, 0]], std_values=[
[255, 255, 255]], target_platform=platform)
# Load model
print('--> Loading model')
ret = rknn.load_onnx(MODEL_PATH)
if ret != 0:
print('load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset=DATASET)
if ret != 0:
print('build model failed.')
exit(ret)
print('done')
# Export rknn model
if not os.path.exists(OUT_DIR):
os.mkdir(OUT_DIR)
print('--> Export RKNN model: {}'.format(RKNN_MODEL_PATH))
ret = rknn.export_rknn(RKNN_MODEL_PATH)
if ret != 0:
print('Export rknn model failed.')
exit(ret)
print('done')
else:
ret = rknn.load_rknn(RKNN_MODEL_PATH)
rknn.release()
- 在终端输入
python3 onnx2rknn.py
,模型转换成功。
- 使用netron软件可以查看生成的rknn网络结构
在rk3588板子上的运行效果
requirement.txt
absl-py==0.15.0
asttokens==2.4.1
astunparse==1.6.3
backcall==0.2.0
cachetools==4.2.4
certifi==2024.8.30
charset-normalizer==2.0.12
clang==5.0
contourpy==1.1.1
cycler==0.12.1
decorator==5.1.1
executing==2.1.0
fast-histogram==0.11
flatbuffers==1.12
fonttools==4.55.0
gast==0.4.0
google-auth==1.35.0
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
grpcio==1.67.1
h5py==3.1.0
idna==3.10
importlib-metadata==8.5.0
importlib-resources==6.4.5
ipython==8.12.3
jedi==0.19.2
keras==2.6.0
Keras-Preprocessing==1.1.2
kiwisolver==1.4.7
Markdown==3.7
MarkupSafe==2.1.5
matplotlib==3.7.5
matplotlib-inline==0.1.7
numpy==1.20.3
oauthlib==3.2.2
onnx==1.10.0
onnxoptimizer==0.2.7
onnxruntime==1.10.0
opencv-python==4.5.5.64
opt-einsum==3.3.0
packaging==24.2
pandas==2.0.3
parso==0.8.4
pexpect==4.9.0
pickleshare==0.7.5
Pillow==7.0.0
prompt-toolkit==3.0.48
protobuf==3.12.2
psutil==5.9.0
ptyprocess==0.7.0
pure-eval==0.2.3
pyasn1==0.6.1
pyasn1-modules==0.4.1
pygments==2.18.0
pyparsing==3.1.4
python-dateutil==2.9.0.post0
pytz==2024.2
PyYAML==6.0.2
requests==2.27.1
requests-oauthlib==2.0.0
rknn-toolkit2==1.5.0+1fa95b5c
rsa==4.9
ruamel.yaml==0.17.4
ruamel.yaml.clib==0.2.8
scipy==1.5.4
seaborn==0.13.2
six==1.15.0
stack-data==0.6.3
tensorboard==2.6.0
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow==2.6.2
tensorflow-estimator==2.6.0
termcolor==1.1.0
torch==1.10.1
torchvision==0.11.2
tqdm==4.64.0
traitlets==5.14.3
typing-extensions==3.7.4.3
tzdata==2024.2
urllib3==1.26.20
wcwidth==0.2.13
werkzeug==3.0.6
wrapt==1.12.1
zipp==3.20.2