RKNN:yolov8模型转换与板端推理流程

devtools/2024/12/21 21:10:37/

近期,在研究瑞芯微的RKNN模型推理时,遇到一些坑,现记录下来,以备忘,亦供同道者参考。

目录

1. 模型转换

1.1. 宿主机环境配置

1.2. onnx模型准备

rknn-toc" style="margin-left:40px;">1.3. onnx转rknn

2. 模型推理

2.1. 推理环境配置

2.2. 推理验证

2.2.1. 输入格式报错

 2.2.2. 需要使用torch


本文主要内容包括两块,一是在宿主机进行onnx-->rknn的模型转换,二是在SOC上利用转换好的rknn模型进行推理。

1. 模型转换

这一步需要在x86宿主机上进行,并配置相关环境。

1.1. 宿主机环境配置

主要就是在python环境中安装RKNN-Toolkit2。

构造环境这一步,建议在docker里面进行,这样可以避免和宿主机环境产生冲突,或者因为宿主机环境和需要的环境不匹配而导致的模型转换出现问题。

PS:之前博主在宿主机的python环境中直接pip安装的rknn-toolkit2,然而用一样的代码进行模型转换,最后推理结果总是出现错乱或者直接所有结果置信度特别低(接近0),最后放弃挣扎,转用docker才没有问题。

这里使用的版本是1.6.0,下载地址:

https://codeload.github.com/rockchip-linux/rknn-toolkit2/zip/refs/tags/v1.6.0icon-default.png?t=N7T8https://codeload.github.com/rockchip-linux/rknn-toolkit2/zip/refs/tags/v1.6.0下载解压之后的目录如下所示:

.
├── CHANGELOG.md
├── doc
├── LICENSE
├── README.md
├── res
├── rknn-toolkit2
├── rknn_toolkit_lite2
└── rknpu2

进到“rknn-toolkit2/docker/docker_file/ubuntu_20_04_cp38”目录下,并利用提供的Dockerfile构建一个docker镜像:

docker build -t rknn_toolkit2_1.6.0 . -f Dockerfile_ubuntu_20_04_for_cp38

等待镜像构建完毕,就会在里面自动安装模型转换所需的所有软件环境。然后,就可以启动一个容器,进到docker系统中:

# 注意:我们上一步构造的镜像命名为rknn_toolkit2_1.6.0,需要改为你的镜像名字;
#      同时,这里作了一个主机和容器之间的路径映射,以便于文件共享,需要将“ /data/projects/other/rknn_test/share_dir”改为你自己的路径
docker run -v /data/projects/other/rknn_test/share_dir:/workspace/ -it rknn_toolkit2_1.6.0

至此,就构建好了所需的环境。

1.2. onnx模型准备

这一步是为了从我们训练的torch模型转为onnx中间格式的模型。这里不能直接使用ultralytics官方的库,需要作一定的改动,使其最后的detect部分改为rknn支持的方式:

 可以参考rknn修改后的ultralytics版本:

GitHub - airockchip/ultralytics_yolov8: NEW - YOLOv8 🚀 in PyTorch > ONNX > CoreML > TFLiteNEW - YOLOv8 🚀 in PyTorch > ONNX > CoreML > TFLite - airockchip/ultralytics_yolov8icon-default.png?t=N7T8https://github.com/airockchip/ultralytics_yolov8也可以自己在ultralytics的源码上修改,基本就是改ultralytics/nn/modules/head.py和ultralytics/engine/exporter.py两个文件,这里不细说了,有空了可以单独聊聊这块内容。

使用修改后的ultralytics进行模型转换:

yolo export model=yolov8n.pt format=rknn

即可得到一个支持转rknn的onnx模型。

rknn">1.3. onnx转rknn

这一步需要利用rknn_model_zoo里面的代码,当然自己写一个转换的脚本也很简单。这里以rknn_model_zoo为例说明。先把该代码拉下来,地址在:

GitHub - airockchip/rknn_model_zooContribute to airockchip/rknn_model_zoo development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/airockchip/rknn_model_zoo.git进入目录:rknn_model_zoo/examples/yolov8/python,然后使用模型转换脚本将onnx模型转为所需的rknn格式的模型: 

python convert.py yolov8n.onnx rk3588

OK,至此,我们在宿主机的工作就完毕了。接下来,需要到板子上进行操作。

2. 模型推理

2.1. 推理环境配置

首先配置一个python虚拟环境:

# 根据你使用python版本进行创建:
conda create -n py38 python=3.8

然后,在1.1中我们下载的文件里面有rknn-toolkit2-1.6.0/rknn_toolkit_lite2/packages这个文件夹,从里面找到对应的安装包,比如我这里Python用的3.8所以就选择rknn_toolkit_lite2-1.6.0-cp38-cp38-linux_aarch64.whl;

最后,将其拷贝到RK板子上,并在板子上打开命令行,进入Python虚拟环境,安装rknn_toolkit_lite2:

pip install rknn_toolkit_lite2-1.6.0-cp38-cp38-linux_aarch64.whl

2.2. 推理验证

将1.3中拉下来的demo代码考到板子上,进到rknn_model_zoo/examples/yolov8/python目录下,使用python脚本进行推理:

# 注意,../model/yolov8.rknn要改为你转换的rknn模型路径
python yolov8.py --model_path ../model/yolov8.rknn --img_show --img_save --target rk3588

这一步如果没问题的话,就会展示推理结果,不过可能会出现以下问题:

2.2.1. 输入格式报错

Traceback (most recent call last):File "yolov8.py", line 262, in <module>outputs = model.run([input_data])File "/home/linaro/pkgs/rknn_model_zoo/py_utils/rknn_executor.py", line 24, in runprint(inputs.shape)
AttributeError: 'list' object has no attribute 'shape'

对于这个错误,可以将这行代码:input_data = img

修改为:

input_data = np.expand_dims(img, axis=3)

将这行代码:outputs = model.run([input_data]) 

修改为:

outputs = model.run(input_data)

 2.2.2. 需要使用torch

在脚本实现的dfl函数中,使用了torch库,我们在板子上肯定不可能再去装一个torch的。因此,这里需要改为numpy实现,将以下代码替换原来的dfl函数即可:

def dfl(postion):n, c, h, w = postion.shapep_num = 4mc = c // p_numy = postion.reshape(n, p_num, mc, h, w)y = softmax(y, 2)acc_metrix = np.arange(mc).reshape(1, 1, mc, 1, 1)y = (y * acc_metrix).sum(2)return ydef softmax(data, dim):max = np.max(data, axis=dim, keepdims=True).repeat(data.shape[dim], axis=dim)exps = np.exp(data - max)return exps / np.sum(exps, axis=dim, keepdims=True)

最后,没有其他意外的话,就可以得到推理结果了:

 


http://www.ppmy.cn/devtools/30829.html

相关文章

基于SkyEye运行Android——应用最为广泛的移动设备操作系统

01.Android简介 Android&#xff08;安卓&#xff09;是一种基于Linux内核&#xff08;不包含GNU组件&#xff09;的开源操作系统&#xff0c;最初由安迪鲁宾开发&#xff0c;主要支持手机。2005年8月由Google收购注资&#xff1b;2007年11月&#xff0c;Google与84家硬件制造…

[论文阅读] 测试时间自适应TTA

最初接触 CVPR2024 TEA: Test-time Energy Adaptation [B站]&#xff08;1:35:00-1:53:00&#xff09;https://www.bilibili.com/video/BV1wx4y1v7Jb/?spm_id_from333.788&vd_source145b0308ef7fee4449f12e1adb7b9de2 实现&#xff1a; 读取预训练好的模型参数设计需要更…

R语言相关知识点

R语言中字符串 获取字符串长度&#xff1a;nchar() 字符串分割&#xff1a;strsplit() 字符串拼接&#xff1a;paste() 字符串截取&#xff1a;substr()其参数是子集所处的起始和终止位置。 字符串替代&#xff1a;gsub() chartr() sub() chartr是字母替换&#xff0c;不是字符…

flutter 生成单选组件

一、效果图 二、主要代码 import package:company_manage_flutter/xcClass/dicDataProp.dart; import package:flutter/material.dart; import package:get/get.dart;class CheckListWidget extends StatefulWidget {final List<Map<String, dynamic>> list;final…

搭建MongoDB分片集群

文章目录 一、什么是分片二、分片集群1、组件构成2、分片集群内各组件间交互 三、数据如何切分四、分片策略1、哈希分片2、范围分片 五、分片集群架构六、搭建分片集群1、涉及主机2、所有主机安装MongoDB3、分片节点副本集的创建3.1、第一套副本集shard13.1.1、准备存放数据和日…

C语言/数据结构——每日一题(链表的中间节点)

一.前言 今天我在LeetCode刷到了一道单链表题&#xff0c;想着和大家分享一下这道题&#xff1a;https://leetcode.cn/problems/middle-of-the-linked-list。废话不多说让我们开始今天的知识分享吧。 二.正文 1.1题目描述 1.2题目分析 这道题有一个非常简便的方法——快慢指…

JS实现瀑布流布局

瀑布流布局是一种常见的网页布局方式&#xff0c;可以实现页面内容的动态排列&#xff0c;使页面看起来更加美观。下面是一个简单的JS实现瀑布流布局的示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8&quo…

电商独立站最重要的功能设置:多语言转换和代运系统搭建

什么是独立站&#xff1f; 多语言模式切换 1 搭建电商独立站在我看来最简单的理解&#xff0c;就是独立的网站。 如果你在跨境圈子呆了一段时间&#xff0c;独立站是一个避不开且火热的一个词&#xff0c;并且也是所有的B2B、B2C商家都在运营和布局的市场。 独立站的优势有哪…