RK3576 Yolo 部署
1.开发背景
Ubuntu 下实现 yolo 计算比较常见,现实中我们需要在各种嵌入式板卡上实现 yolo 模型,在板卡上运行 yolo 也是常态。主要参考官方 github 和 野火教程。
2.开发需求
在 RK3576 上运行 yolov8 的官方例程
3.开发环境
Ubuntu20.04 + Conda + Yolov8 + RK3576
4.实现步骤
4.1 PyTorch 文件转 ONNX
4.1.1下载权重文件
下载官方权重文件 yolov8n.pt
wget https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt
4.1.2 下载转换工具
yolo8 转换工具 ultralytics 和 ultralytics_yolov8,ultralytics 安装相关环境,理论上ultralytics_yolov8 安装环境应该也是可以的。
git clone -b rk_opt_v1 https://github.com/airockchip/ultralytics_yolov8.git
4.1.3 创建环境并进入
conda create -n yolov8 python=3.9
conda activate yolov8
4.1.4 安装环境
cd ultralytics
pip install -e .
安装成功可以使用 yolo 指令
4.1.5 修改配置文件
修改配置文件 ,主要指定模型路径
vi ultralytics_yolov8/ultralytics/cfg/default.yaml
# Train settings -------------------------------------------------------------------------------------------------------
model: ./yolov8n.pt # (str, optional) path to model file, i.e. yolov8n.pt, yolov8n.yaml
data: coco128.yaml # (str, optional) path to data file, i.e. coco128.yaml
epochs: 100 # (int) number of epochs to train for
4.1.6 执行导出
cd ultralytics_yolov8/
export PYTHONPATH=./
python ./ultralytics/engine/exporter.py
生成文件 yolov8n_rknnopt.torchscript
4.2 ONNX 转 RKNN
4.2.1 下载 toolkit2.3.2
toolkit2.3.2 工具链很重要,工具链最好用最新的,否则可能存在不兼容的问题。
git clone https://github.com/airockchip/rknn-toolkit2
4.2.2 安装工具链
python 版本需要注意 conda 创建指定 python3.8,所以这里是 cp38
toolkit2.3.2 工具链支持 python3.6 ~ python3.12
sudo apt update
sudo apt-get install python3-dev python3-pip python3.8-venv gcc
sudo apt-get install libxslt1-dev zlib1g-dev libglib2.0 libsm6 libgl1-mesa-glx libprotobuf-dev# 配置 pip 源
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/# 安装依赖库,根据 rknn-toolkit2\doc\requirements_cp38-1.4.0.txt
pip3 install numpy
pip install -r ./rknn-toolkit2/packages/x86_64/requirements_cp39-2.3.2.txt
pip install ./rknn-toolkit2/packages/x86_64/rknn_toolkit2-2.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
4.2.3 下载测试包
git clone https://github.com/airockchip/rknn_model_zoo
4.2.4 增加转换脚本
主要是在 rknn_model_zoo/examples/yolov8/python/convert.py 上修改,convert.py 主要是转换 onnx 为 rknn, 主要修改 load_onnx -> load_pytorch。在 convert.py 同路径添加 pt2rknn.py
import os
import sys
import numpy as np
from rknn.api import RKNNDATASET_PATH = '../../datasets/COCO/coco_subset_20.txt'
# 默认开启量化
DEFAULT_QUANT = Truedef parse_arg():if len(sys.argv) < 3:print("Usage: python3 {} [torchscript_model_path] [platform] [dtype(optional)] [output_rknn_path(optional)]".format(sys.argv[0]));print(" platform choose from [rk3562,rk3566,rk3568,rk3576,rk3588]")print(" dtype choose from [i8, fp]")print("Example: python pt2rknn.py ./yolov8n.onnx rk3588")exit(1)model_path = sys.argv[1]platform = sys.argv[2]do_quant = DEFAULT_QUANTif len(sys.argv) > 3:model_type = sys.argv[3]if model_type not in ['i8', 'fp']:print("ERROR: Invalid model type: {}".format(model_type))exit(1)elif model_type == 'i8':do_quant = Trueelse:do_quant = Falseif len(sys.argv) > 4:output_path = sys.argv[4]else:output_path = "./model/yolov8_"+platform+".rknn"return model_path, platform, do_quant, output_pathif __name__ == '__main__':model_path, platform, do_quant, output_path = parse_arg()# Create RKNN objectrknn = RKNN(verbose=False)# Pre-process configprint('--> Config model')rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform=platform)print('done')# Load modelprint('--> Loading model')#ret = rknn.load_onnx(model=model_path)ret = rknn.load_pytorch(model=model_path, input_size_list=[[1, 3, 640, 640]])if ret != 0:print('Load model failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=do_quant, dataset=DATASET_PATH)if ret != 0:print('Build model failed!')exit(ret)print('done')# Export rknn modelprint('--> Export rknn model')ret = rknn.export_rknn(output_path)if ret != 0:print('Export rknn model failed!')exit(ret)print('done')# 精度分析,,输出目录./snapshot#print('--> Accuracy analysis')#ret = rknn.accuracy_analysis(inputs=['./subset/000000052891.jpg'])#if ret != 0:# print('Accuracy analysis failed!')# exit(ret)#print('done')# Releaserknn.release()
4.2.5 转换文件
# 拷贝 torchscript 文件到 rknn_model_zoo
cp ./yolo_v8/ultralytics_yolov8/yolov8n_rknnopt.torchscript rknn_model_zoo/examples/yolov8/model/yolov8n_rknnopt.pt# 执行转换 torch 转换 rknn 文件 yolov8_rk3576.rknn
cd ./rknn_model_zoo/examples/yolov8/
python ./python/pt2rknn.py ./model/yolov8n_rknnopt.pt rk3576
4.3 板端部署
4.3.1 编译示例
由于是测试代码,可以直接在 RK3576 上编译,正式项目还是使用交叉编译。
./build-linux.sh -t rk3576 -a aarch64 -d yolov8
# 编译后的结果
./install/rk3576_linux_aarch64/rknn_yolov8_demo/
├── lib
│ ├── librga.so
│ └── librknnrt.so
├── model
│ ├── bus.jpg
│ ├── coco_80_labels_list.txt
│ ├── yolov8_rk3576.rknn
│ └── yolov8.rknn
├── rknn_yolov8_demo
└── rknn_yolov8_demo_zero_copy
如果是在 PC 上交叉编译的,拷贝程序到板卡上。
4.3.2 运行程序
./rknn_yolov8_demo ./model/yolov8_rk3576.rknn ./model/bus.jpg