YOLO模型格式转换:pt -> onnx -> rknn

embedded/2024/12/28 13:44:28/

导出 RKNPU 适配模型说明

Source

​ 本仓库基于 https://github.com/ultralytics/ultralytics 仓库的 c9be1f3cce89778f79fb462797b8ca0300e3813d commit 进行修改,验证.
修改前的源码链接:
https://github.com/ultralytics/ultralytics/tree/c9be1f3cce89778f79fb462797b8ca0300e3813d

2.1 模型转换pt2onnx

如果想用最新版本的v8官方代码,可以尝试修改以下内容:

ultralytics/nn/moudles/head.py

Detect

    def forward(self, x):# ============================↓新增↓============================if self.export and self.format == 'rknn':y = []for i in range(self.nl):y.append(self.cv2[i](x[i]))cls = torch.sigmoid(self.cv3[i](x[i]))cls_sum = torch.clamp(cls.sum(1, keepdim=True), 0, 1)y.append(cls)y.append(cls_sum)return y# ============================↑新增↑============================        

Segment

    def forward(self, x):"""Return model outputs and mask coefficients if training, otherwise return outputs and mask coefficients."""p = self.proto(x[0])  # mask protosbs = p.shape[0]  # batch size# ============================↓新增↓============================if self.export and self.format == 'rknn':mc = [self.cv4[i](x[i]) for i in range(self.nl)]else:# ============================↑新增↑============================        mc = torch.cat([self.cv4[i](x[i]).view(bs, self.nm, -1) for i in range(self.nl)], 2)  # mask coefficientsx = self.detect(self, x)if self.training:return x, mc, p# ============================↓新增↓============================if self.export and self.format == 'rknn':bo = len(x)//3relocated = []for i in range(len(mc)):relocated.extend(x[i*bo:(i+1)*bo])relocated.extend([mc[i]])relocated.extend([p])return relocated# ============================↑新增↑============================               return (torch.cat([x, mc], 1), p) if self.export else (torch.cat([x[0], mc], 1), (x[1], mc, p))
ultralytics\engine\exporter.py

增加rknn相关
115行

        ['RKNN', 'rknn', '_rknnopt.torchscript', True, False],

187行

        jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle, ncnn, rknn = flags

327行

        if rknn:f[12], _ = self.export_rknn()

390行左右onnx_expert附近增加函数

    @try_exportdef export_rknn(self, prefix=colorstr('RKNN:')):"""YOLOv8 RKNN model export."""LOGGER.info(f'\n{prefix} starting export with torch {torch.__version__}...')# ts = torch.jit.trace(self.model, self.im, strict=False)# f = str(self.file).replace(self.file.suffix, f'_rknnopt.torchscript')# torch.jit.save(ts, str(f))f = str(self.file).replace(self.file.suffix, f'.onnx')opset_version = self.args.opset or get_latest_opset()torch.onnx.export(self.model,self.im[0:1,:,:,:],f,verbose=False,opset_version=12,do_constant_folding=True,  # WARNING: DNN inference with torch>=1.12 may require do_constant_folding=Falseinput_names=['images'])LOGGER.info(f'\n{prefix} feed {f} to RKNN-Toolkit or RKNN-Toolkit2 to generate RKNN model.\n' 'Refer https://github.com/airockchip/rknn_model_zoo/tree/main/models/CV/object_detection/yolo')return f, None
ultralytics/nn/autobackend.py

增加rknn相关
120行左右

        pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle, ncnn, triton, rknn = \self._model_type(w)

550行左右

        elif getattr(self, 'rknn', False):assert "for inference, please refer to https://github.com/airockchip/rknn_model_zoo/"
ultralytics/cfg/default.yaml # Export settings改为: ```format: rknn``` ultralytics/data/augment.py
        # Create new boxesreturn np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1)), dtype=bboxes.dtype).reshape(4, n).T改为:return np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T

模型差异

在基于不影响输出结果, 不需要重新训练模型的条件下, 有以下改动:

  • 修改输出结构, 移除后处理结构. (后处理结果对于量化不友好)

  • dfl 结构在 NPU 处理上性能不佳,移至模型外部的后处理阶段,此操作大部分情况下可提升推理性能。

  • 模型输出分支新增置信度的总和,用于后处理阶段加速阈值筛选。

以上移除的操作, 均需要在外部使用CPU进行相应的处理. (对应的后处理代码可以在 RKNN_Model_Zoo 中找到)

导出onnx模型

运行pt2onnx.py

2.2 转换模型onnx2rknn

所有要用到的压缩包都放在2.AI模型转换\ubuntu中了

  1. 下载模型转换工具
    网盘下载链接:https://pan.baidu.com/s/1_PquxW2rFuf77q6mT3gkDQ 提取码:6666
    文件:rknn-toolkit-1.7.3-docker.tar.gz
  2. 把压缩包移到电脑端ubuntu20.04的rknn-toolkit目录,无需解压
  3. 在该目录打开终端
    执行以下指令加载模型转换工具docker镜像:
    sudo docker load --input rknn-toolkit-1.7.3-docker.tar.gz
    
    执行以下指令进入镜像bash环境测试doker是否成功加载(可跳过):
    sudo docker run -t -i --privileged rknn-toolkit:1.7.3 /bin/bash
    
    输入python加载python相关库
    输入import rknn导入rknn相关库
    没报错,表示模型转换工具环境搭建完成。

上面3步仅第一次需要配置
4. 重新打开终端
启动doker容器,环境为rknn-toolkit:1.7.3,同时把本地model_convert文件夹映射到doker的test文件夹
这里一定要用绝对路径,Ctrl+L查看绝对路径

sudo docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb -v /home/developer/yolov8_model_convert:/test rknn-toolkit:1.7.3 /bin/bash

进入test文件夹
quant_dataset文件夹放在test文件夹
生成量化图片路径列表pic_path.txt,如果打开检查路径对,就不用跑这行代码,可以删掉一些,留10来行就行

python gen_list.py

把onnx文件放目录下转rknn,注意用v8官方代码转成onnx时opset=9

python rknn_convert.py

http://www.ppmy.cn/embedded/149453.html

相关文章

uniapp 微信小程序 数据空白展示组件

效果图 html <template><view class"nodata"><view class""><image class"nodataimg":src"$publicfun.locaAndHttp()?localUrl:$publicfun.httpUrlImg(httUrl)"mode"aspectFit"></image>&l…

深度学习与图像处理(国产深度学习框架——飞桨官方指定教材)

计算机视觉从小白到大师之路 《深度学习与图像处理&#xff08;PaddlePaddle版&#xff09;》这一本就够了 1.引言 随着人工智能技术的飞速发展&#xff0c;各行各业对深度学习、图像处理相关领域的人才需求日益迫切。本书旨在通过系统的理论讲解与丰富的实战案例&#xff0…

Node-解决sequelize配置时区

目录 什么是 UTC&#xff08;协调世界时&#xff09;&#xff1f; UTC 的重要性 UTC 和本地时间的关系 如何转换 UTC 和本地时间&#xff1f; 为什么要使用 UTC&#xff1f; 如何在编程中使用 UTC&#xff1f; Day.js 示例&#xff1a; 使用 Sequelize 进行数据库操作时&…

AI与药学:ChatGPT与临床培训——药学博士(Pharm-D)学生的看法、担忧和实践

一、文献信息 标题: ChatGPT and Clinical Training: Perception, Concerns, and Practice of Pharm-D Students 作者: Zawiah M, Al-Ashwal FY, Gharaibeh L, Abu Farha R, Alzoubi KH, Abu Hammour K, Qasim QA, Abrah F 期刊: Journal of Multidisciplinary Healthcare 二…

docker基础命令入门、镜像、运行容器、操作容器

一. Docker 基础入门相关命令 1.1 启动Docker 1.2 查看 Docker 运行状态 1.3 停止 Dokcer 1.4 重启Docker 1.5 配置开机启动 docker 1.6 查看 docker 所有命令 二. Docker 镜像相关命令 2.1 docker search 镜像名称——(查询某个镜像) 2.2 docker pull 镜像名称:version…

【人工智能离散数学基础】——深入详解图论:基础图结构及算法,应用于图神经网络等

深入详解图论&#xff1a;基础图结构及算法&#xff0c;应用于图神经网络等 图论&#xff08;Graph Theory&#xff09;是数学中研究图这种离散结构的分支&#xff0c;广泛应用于计算机科学、网络分析、人工智能等领域。随着图神经网络&#xff08;Graph Neural Networks, GNNs…

如何在谷歌浏览器中管理下载记录

谷歌浏览器作为广受欢迎的网络浏览器之一&#xff0c;不仅提供了高效的网页浏览功能&#xff0c;还具备了强大的文件下载管理功能。本文将详细介绍如何在谷歌浏览器中查看和管理下载记录&#xff0c;帮助您更高效地使用浏览器。 一、访问下载管理器 1.快速访问&#xff1a; 点…

深入探究C++pow函数的优势和劣势 原理

优势 功能强大 支持多种数据类型&#xff1a; C 的pow()函数在<cmath>头文件中定义&#xff0c;它能够灵活地处理不同的数据类型。对于整数类型&#xff0c;如int、long long等&#xff0c;它能准确地计算幂次方。以计算棋盘上的麦粒数为例&#xff0c;传说国际象棋棋盘…