rv1109/1126 rknn 模型部署过程

rv1109/1126是瑞芯微出的嵌入式AI芯片,带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上,需要经过模型转换和量化,下面记录一下整个过程。

量化环境

模型量化需要安装rk的工具包:
rockchip-linux/rknn-toolkit (github.com)
版本要根据开发板的固件支持程度来,如果二者不匹配,可能转出来的模型无法运行或者结果不对。

模型量化

rknn支持caffe,tensorflow,tflite,onnx,mxnet,pytorch等模型量化,下面以onnx为例,其他格式基本类似。即可以使用量化包带的可视化界面,也可以自行写代码,更推荐自己写代码,复用性和灵活性更强,对可视化界面一笔带过。

可视化量化工具

执行

python -m rknn.bin.visualization

image.png

选择对应格式,然后设置模型参数进行量化。
image.png

写代码量化

image.png

基础量化

最简单的量化方式如下,只需设置模型的均值、方差,载入原始模型,调用rknn.build接口,然后export_rknn即可。

from rknn.api import RKNNif __name__ == '__main__':rknn=RKNN()# pre-process configprint('--> config model')rknn.config(channel_mean_value='0 0 0 255',reorder_channel='0 1 2',target_platform=['rv1109'],#quantized_dtype="dynamic_fixed_point-i16")print('done')# Load mxnet modelonnx_model = 'yolov8n.onnx'print('--> Loading model')ret = rknn.load_onnx(onnx_model)if ret != 0:print('Load onnx_model model failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=True, dataset='../coco_resize.txt', pre_compile=False) # 若要在PC端仿真,pre_compile 为Falseif ret != 0:print('Build model failed!')exit(ret)print('done')print('--> Export RKNN model')ret = rknn.export_rknn('yolov8n_nohead.rknn')if ret != 0:print('Export RKNN model failed!')exit(ret)print('done')rknn.release()

模型量化需要提供量化图片的列表,格式为每行是一张图片的路径, 一般需要几百张,如:

images/0.jpg
images/1.jpg

模型推理验证

有两种方式验证模型的结果,一种是连接开发板,在开发板上运行,可以实际测试模型的推理速度,需要USB连接开发板,一种是在PC端仿真,速度较慢,适合在没有开发板的情况下,验证模型结果是否正确。两种方式使用的代码大部分一样,区别是在PC端仿真时,模型要以pre_compile=False模式进行量化,init_runtime参数为targe=None。

import os
import sys
from rknn.api import RKNN
import cv2
import numpy as npif __name__=="__main__":# Create RKNN objectrknn = RKNN()print('--> Loading RKNN model')ret = rknn.load_rknn('yolov8.rknn')if ret != 0:print('Load  failed!')exit(ret)print('load done')# Init Runtimerknn.init_runtime(target="rv1109")#第二个参数device_id为开发板的设备id,不用填, targe=None时,代表PC仿真image = cv2.imread("1.jpg")outputs = rknn.inference(inputs=[image]) rknn.release()

量化精度评估(逐层)

有些时候,量化损失可能过大,这时我们希望能够逐层比对量化后模型与原始模型,这时需要使用accuracy_analysis接口,这个接口第一个参数是图片列表文件,里面是测试图片的路径,第二个参数是比对结果保存路径:

from rknn.api import RKNNif __name__ == '__main__':rknn=RKNN()# pre-process configprint('--> config model')rknn.config(channel_mean_value='0 0 0 255',reorder_channel='0 1 2',target_platform=['rv1109'],#quantized_dtype="dynamic_fixed_point-i16")print('done')# Load mxnet modelonnx_model = 'yolov8n.onnx'print('--> Loading model')ret = rknn.load_onnx(onnx_model)if ret != 0:print('Load onnx_model model failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=True, dataset='../coco_resize.txt', pre_compile=False) # 若要在PC端仿真,pre_compile 为Falseif ret != 0:print('Build model failed!')exit(ret)print('done')rknn.accuracy_analysis("test_list.txt", output_dir='./snapshot5')			               print('--> Export RKNN model')ret = rknn.export_rknn('yolov8n_nohead.rknn')if ret != 0:print('Export RKNN model failed!')exit(ret)print('done')rknn.release()

比对文件如下:

Conv__model.0_conv_Conv_214_out0_nhwc_1_320_320_16.tensor    	eculidean_norm=0.030792	cosine_norm=0.999525	eculidean=202.926056	cosine=0.999526
Sigmoid__model.0_act_Sigmoid_213_Mul__model.0_act_Mul_212_out0_nhwc_1_320_320_16.tensor 	eculidean_norm=0.049676	cosine_norm=0.998766	eculidean=178.751434	cosine=0.998767
Conv__model.1_conv_Conv_210_out0_nhwc_1_160_160_32.tensor    	eculidean_norm=0.103382	cosine_norm=0.994656	eculidean=521.709229	cosine=0.994656
Sigmoid__model.1_act_Sigmoid_211_Mul__model.1_act_Mul_209_out0_nhwc_1_160_160_32.tensor 	eculidean_norm=0.113702	cosine_norm=0.993536	eculidean=436.044495	cosine=0.993536
Conv__model.2_cv1_conv_Conv_208_out0_nhwc_1_160_160_32.tensor 	eculidean_norm=0.120058	cosine_norm=0.992793	eculidean=351.808380	cosine=0.992794
Sigmoid__model.2_cv1_act_Sigmoid_207_Mul__model.2_cv1_act_Mul_205_out0_nhwc_1_160_160_32.tensor 	eculidean_norm=0.169184	cosine_norm=0.985688	eculidean=262.819550	cosine=0.985688

混合量化

有些时候,使用默认量化方法模型精度损失较大,我们通过逐层分析,也知道了那些层的损失较大,这时就需要控制一些层不量化,或以更高精度模式量化,这种方式就是混合量化。
与基础量化相比,混合量化分为两步:
第一步是通过rknn.hybrid_quantization_step1(替换基础量化中的rknn.build)获得模型的量化配置文件:

rknn.hybrid_quantization_step1(dataset='../coco_resize.txt')

该接口会生成3个文件:

xx.data
xx.json
xx.quantization.cfg

其中,.cfg文件时量化配置文件,用于控制每一层的量化:

%YAML 1.2
---
# add layer name and corresponding quantized_dtype to customized_quantize_layers, e.g conv2_3: float32
customized_quantize_layers: {}
quantize_parameters:'@attach_Concat_/model.22/Concat_5/out0_0:out0':dtype: asymmetric_affinemethod: layermax_value:-   647.7965087890625min_value:-   0.0zero_point:-   0scale:-   2.5403785705566406qtype: u8'@Concat_/model.22/Concat_5_1:out0':dtype: asymmetric_affinemethod: layermax_value:-   647.7965087890625min_value:-   0.0zero_point:-   0scale:-   2.5403785705566406qtype: u8

对于不量化或者以其他精度模式量化的层,以字典形式写在customized_quantize_layers中,rv1109支持asymmetric_quantized-u8,dynamic_fixed_point-i8和dynamic_fixed_point-i16,默认情况下,以asymmetric_quantized-u8方式量化,在需要更高精度时,可用dynamic_fixed_point-i16,但速度会更慢。对于损失较大的层,我们可以尝试设置dynamic_fixed_point-i16量化(若float32则不量化):

customized_quantize_layers: {"Split_/model.22/Split_21": "dynamic_fixed_point-i16","Reshape_/model.22/dfl/Reshape_20": "float32"
}

设置完成量化配置后,使用rknn.hybrid_quantization_step2进行量化:

from rknn.api import RKNNif __name__ == '__main__':rknn=RKNN()# pre-process configprint('--> config model')rknn.config(channel_mean_value='0 0 0 255',reorder_channel='0 1 2',target_platform=['rv1109'],#quantized_dtype="dynamic_fixed_point-i16")print('done')# Load mxnet modelonnx_model = 'yolov8n.onnx'print('--> Loading model')ret = rknn.load_onnx(onnx_model)if ret != 0:print('Load onnx_model model failed!')exit(ret)print('done')# Build modelprint('--> Building model')rknn.hybrid_quantization_step2(dataset='../coco_resize.txt',   model_input='torch_jit.json',data_input="torch_jit.data",model_quantization_cfg="torch_jit.quantization.cfg",pre_compile=False)if ret != 0:print('Build model failed!')exit(ret)print('done')rknn.accuracy_analysis("test_list.txt", output_dir='./snapshot5')			               print('--> Export RKNN model')ret = rknn.export_rknn('yolov8n_nohead.rknn')if ret != 0:print('Export RKNN model failed!')exit(ret)print('done')rknn.release()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/21509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Mybatis】Mybatis架构简介

文章目录 1.整体架构图2. 基础支撑层2.1 类型转换模块2.2 日志模块2.3 反射工具模块2.4 Binding 模块2.5 数据源模块2.6缓存模块2.7 解析器模块2.8 事务管理模块 3. 核心处理层3.1 配置解析3.2 SQL 解析与 scripting 模块3.3 SQL 执行3.4 插件 4. 接口层 1.整体架构图 MyBatis…

爬虫008_流程控制语句_if_if else_elif_for---python工作笔记026

然后我们再来看一下这里的,判断,可以看到 再看一个判断,这里的布尔类型 第二行有4个空格,python的格式 注意这里,输入的age是字符串,需要转一下才行 int可以写到int(intput("阿斯顿法师打发地方")) 这样也可以

成功解决:ValueError Cannot assign non-leaf Tensor to parameter ‘weight‘

成功解决:ValueError Cannot assign non-leaf Tensor to parameter ‘weight‘ 欢迎大家来到安静到无声的《模式识别与人工智能(程序与算法)》,如果对所写内容感兴趣请看模式识别与人工智能(程序与算法)系列讲解 - 总目录,同时这也可以作为大家学习的参考。欢迎订阅,优…

【LeetCode 算法】Reorder List 重排链表

文章目录 Reorder List 重排链表问题描述:分析代码PointerReverseMerge Tag Reorder List 重排链表 问题描述: 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#…

集中/本地转发、AC、AP

1.ADSL ADSL MODEM(ADSL 强制解调器)俗称ADSL猫 ADSL是一种异步传输模式(ATM)。ADSL是指使用电话线上网,需要专用的猫(Modem),在上网的时候高频和低频分离,所以上网电话两不耽误,速…

LBP特征笔记

LBP,局部二值模式(Local Binary Pattern),是一种描述图像局部纹理特征的方式,具有旋转不变性和灰度不变性。首先由T. Ojala, M.Pietikinen, 和 D. Harwood 在1994年提出。 LBP特征描述 基础LBP算子 基础的LBP算子定义…

Mysql推荐使用规范

一:基础规范 1、使用InnoDB存储引擎 支持事务、行级锁、并发性能更好、CPU及内存缓存页优化使得资源利用率更高 2、推荐使用utf8mb4字符集 无需转码,无乱码风险, 支持emoji表情以及部分不常见汉字 3、表、字段必须加注释 方便他人理解字段意思。 4、不在数据…

分布式ID性能评测:CosId VS 美团 Leaf

环境 MacBook Pro (M1)JDK 17JMH 1.36运行在本机 Docker 内的 mariadb:10.6.4 运行 CosId SegmentChainId 模式,基准测试代码: Benchmarkpublic long generate() {return segmentChainId.generate();}Leaf 基准测试代码: Benchmarkpublic l…

使用正则表达式 移除 HTML 标签后得到字符串

需求分析 后台返回的数据是 这样式的 需要讲html 标签替换 high_light_text: "<span stylecolor:red>OPPO</span> <span stylecolor:red>OPPO</span> 白色 01"使用正则表达式 function stripHTMLTags(htmlString) {return htmlString.rep…

stm32 舵机 cubemx

文章目录 前言一、cubemx配置二、代码1.serve.c2.serve.h3.主函数 总结 前言 stm32对舵机进行控制&#xff0c;很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此&#…

音视频--DTMF信号发送及检测

参考资料 https://zh.wikipedia.org/wiki/%E5%8F%8C%E9%9F%B3%E5%A4%9A%E9%A2%91https://www.cnblogs.com/lijingcheng/p/4454932.html 1. DTMF是什么 1.1 DTMF定义 双音多频信号&#xff08;英语&#xff1a;Dual-Tone Multi-Frequency&#xff0c;简称&#xff1a;DTMF&a…

怎么查到企业的供应商和客户?

企业的供应商和客户是什么&#xff1f; 其实不需要过多介绍&#xff0c;我们对供应商和客户都有自己的理解&#xff0c;供应商就是负责企业产品的供应&#xff0c;企业从供应商那里买材料进行加工得到的产品&#xff0c;卖给客户。 官方来说供应商是向企业和竞争对手提供各种…

Linux进程,线程,内核线程的区别

进程、线程和内核线程是计算机中不同层次的执行单元&#xff0c;它们之间有以下区别&#xff1a; 进程&#xff08;Process&#xff09;&#xff1a;进程是计算机中正在运行的程序的实例。每个进程都有自己的地址空间、代码、数据、打开的文件等资源。进程是操作系统进行资源分…

关于React框架(库)的若干个问题

​一、是什么&#xff1f; ​ react是用于构建用户界面的JavaScript库&#xff0c;是一个将数据渲染为HTML视图的开源JavaScript库。 二、为什么用&#xff1f;有什么好处&#xff08;特点&#xff09;&#xff1f; 1. 为什么用&#xff1f;用的前提&#xff1f; ❶原生js操…

mac 下用brew快速安装CommandLineTools

有时候用git 就会提示安装CommandLineTools &#xff0c;xcode太大又不想安装&#xff0c;怎么办呢我们可以试下下面的方式 什么是Brew&#xff1a; Brew是Mac OS X下的一个包管理器&#xff0c;可以方便地安装、升级和卸载很多常用的软件包 在mac下如何安装呢&#xff1a; …

爆肝整理,Postman接口测试-参数关联实战(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试什么时候…

AlexNet卷积神经网络-笔记

AlexNet卷积神经网络-笔记 AlexNet卷积神经网络2012年提出 测试结果为&#xff1a; 通过运行结果可以发现&#xff0c; 在眼疾筛查数据集iChallenge-PM上使用AlexNet&#xff0c;loss能有效下降&#xff0c; 经过5个epoch的训练&#xff0c;在验证集上的准确率可以达到94%左右…

leetcode 738. 单调递增的数字

2023.8.4 这题用暴力法会超时&#xff0c;我就没试了&#xff0c;采用了个挺巧的方法&#xff0c;为了方便需要先将整数n转换为字符串的形式&#xff0c;然后从后向前遍历&#xff0c;当两个数字非递增时&#xff0c;将前一个数字--&#xff0c;后一个数字的位置记录在index中&…

以技术驱动反欺诈,Riskified 为企业出海保驾护航

如今&#xff0c;全球对于线上消费的需求日益增长&#xff0c;各类新型支付方式也层出不穷。在国内&#xff0c;线上支付有着较为完善的法律及监管条例&#xff0c;格局基本已定型。但对于出海商家而言&#xff0c;由于不同国家和地区的支付规则和监管机制不同&#xff0c;跨境…

云运维工具

企业通常寻找具有成本效益的方法来优化创收&#xff0c;维护物理基础架构以托管服务器和应用程序以提供服务交付需要巨大的空间和前期资金&#xff0c;最重要的是&#xff0c;物理基础设施会产生额外的运营支出以进行定期维护&#xff0c;这对收入造成了沉重的损失。 云使企业…