RK3399Pro RKNN-Toolkit 的使用

2024-03-23 05:10
文章标签 使用 rknn toolkit rk3399pro

本文主要是介绍RK3399Pro RKNN-Toolkit 的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RKNN-Toolkit

  • 前言
  • 模型运行在与 PC 相连的 Rockchip NPU 平台上
    • 运行非 RKNN 模型时工具的使用流程
    • 运行RKNN 模型时工具的使用流程
  • 模型运行在 RK3399Pro Linux 开发板上
  • PyTorch 模型加载接口

前言

目前 RKNN-Toolkit 可以运行在 PC(Linux/Windows/MacOS x64)上,也可以运行在 RK3399Pro
开发板(Debian9 或 Debian10)。
本人推荐PC是linux系统,rk3399pro是debian10,原因之后补充。

模型运行在与 PC 相连的 Rockchip NPU 平台上

该场景下,RKNN-Toolkit 运行在 PC 上,通过 PC 的 USB 连接 NPU 设备。RKNN-Toolkit 将RKNN 模型传到 NPU 设备上运行,再从 NPU 设备上获取推理结果、性能信息等。

运行非 RKNN 模型时工具的使用流程

当模型为非 RKNN 模型(Caffe、TensorFlow、TensorFlow Lite、ONNX、Darknet、PyTorch、
MXNet 等模型)时,RKNN-Toolkit 工具的使用流程及注意事项如下:
在这里插入图片描述
注:
1、 以上步骤请按顺序执行。
2、 蓝色框标注的步骤导出的 RKNN 模型可以通过 load_rknn 接口导入并使用。
3、 红色框标注的模型推理、性能评估和内存评估的步骤先后顺序不固定,根据实际使用情况
决定。
4、 只有当目标平台是 Rockchip NPU 时,才可以调用 eval_memory 接口获取内存使用情况。

运行RKNN 模型时工具的使用流程

在这里插入图片描述
该场景下,首先需要完成以下两个步骤:
1、 确保开发板的 USB OTG 连接到 PC,并且正确识别到设备,即在 PC 上调用 以下命令可以查询到相关设备。

python3 -m rknn.bin.list_devices 

2、 调用 init_runtime 接口初始化运行环境时需要指定 target 参数和 device_id 参数。其中 target参数表明硬件类型,当前版本可选值为“rk1806”、“rk1808”、“rk3399pro”、“rv1109”或“rv1126”。当 PC 连接多个设备时,还需要指定 device_id 参数,即设备编号,设备编号可以通过 list_devices 接口或 python3 -m rknn.bin.list_devices 命令查询,示例如下:

all device(s) with adb mode:
[]
all device(s) with ntb mode:
[‘TB-RK1808S0’, ‘515e9b401c060c0b’]

初始化运行时环境代码示例如下:

# RK3399Pro
ret = init_runtime(target=’rk3399pro’, device_id=’VGEJY9PW7T’)

注:

  1. 目前 RK1806/RK1808/RV1109/RV1126 等设备支持 NTB 或 ADB 两种连接模式,RK3399Pro 开发板只支持 ADB 模式使用多设备时,需要确保这些设备使用相同的连接模式,即 list_devices 查询出来的设备 ID 列表都是 ADB,或都是 NTB。
  2. 在 Linux 上第一次使用 NTB 设备时,非 root 用户需要获取该 USB 设备的读写权限,这
    可以通过执行 SDK/platform-tools/update_rk_usb_rule/linux/update_rk1808_usb_rule.sh脚本完成,详细说明请参考同级目录下的 README.txt。

模型运行在 RK3399Pro Linux 开发板上

该场景下,RKNN-Toolkit 直接安装在 RK3399Pro Linux 系统中。构建或导入的 RKNN 模型直
接在 RK3399Pro 上运行,以获取模型实际的推理结果或性能信息。
对于 RK3399Pro Linux 开发板,RKNN-Toolkit 工具的使用流程取决于模型种类,如果模型类型是非 RKNN 模型,则使用流程同场景一中的第一个图;否则使用流程同第二个图。

PyTorch 模型加载接口

在这里插入图片描述
本人使用的是pytorch模型,以下是加载 pytorch模型的示例代码,如果在 PC 上执行这个例子,RKNN 模型将在模拟器上运行:

import numpy as np
import cv2
from rknn.api import RKNN
import torchvision.models as models
import torch# 通过跟踪转换为 Torch 脚本   
# 要将 PyTorch 模型通过跟踪转换为 Torch 脚本,必须将模型的实例以及示例输入传递给torch.jit.trace函数
def export_pytorch_model():net = models.resnet18(pretrained=True)  # 换成你的模型net.eval()trace_model = torch.jit.trace(net, torch.Tensor(1,3,224,224))trace_model.save('./resnet18.pt')# show一下输出
def show_outputs(output):output_sorted = sorted(output, reverse=True)top5_str = '\n-----TOP 5-----\n'for i in range(5):value = output_sorted[i]index = np.where(output == value)for j in range(len(index)):if (i + j) >= 5:breakif value > 0:topi = '{}: {}\n'.format(index[j], value)else:topi = '-1: 0.0\n'top5_str += topiprint(top5_str)def show_perfs(perfs):perfs = 'perfs: {}\n'.format(perfs)print(perfs)def softmax(x):return np.exp(x)/sum(np.exp(x))def pytorch2rknn_predict():export_pytorch_model()model = './resnet18.pt'input_size_list = [[3, 224, 224]]# Create RKNN objectrknn = RKNN()# rknn = RKNN(verbose=True, verbose_file=’./mobilenet_build.log’) # 将详细的日志信息输出到屏幕,并写到 mobilenet_build.log 文件中# rknn = RKNN(verbose=True)  # 只在屏幕打印详细的日志信息# pre-process configprint('--> Config model')rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 58.395, 58.395]], reorder_channel='0 1 2')'''rknn.config(mean_values=[[103.94, 116.78, 123.68]],std_values=[[58.82, 58.82, 58.82]],reorder_channel=’0 1 2’,need_horizontal_merge=True,target_platform=[‘rk1808’, ‘rk3399pro’])'''print('done')# Load Pytorch modelprint('--> Loading model')ret = rknn.load_pytorch(model=model, input_size_list=input_size_list)if ret != 0:print('Load Pytorch model failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=True, dataset='./dataset.txt')  # dataset.txt 是一个包含测试图片路径的文本文件if ret != 0:print('Build model failed!')exit(ret)print('done')# 量化精度分析print('--> Accuracy analysis')rknn.accuracy_analysis(inputs='./dataset.txt', target='rk3399pro')print('done')# Export RKNN modelprint('--> Export RKNN model')ret = rknn.export_rknn('./resnet_18.rknn')  # 导出储存为 RKNN 模型文件,用于模型部署if ret != 0:print('Export resnet_18.rknn failed!')exit(ret)print('done')# ret = rknn.load_rknn('./resnet_18.rknn')  # 改为自己的rknn模型# Set inputsimg = cv2.imread('./space_shuttle_224.jpg') # 预测的图片img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# Init runtime environmentprint('--> Init runtime environment')ret = rknn.init_runtime()  # ret = rknn.init_runtime(target='rk3399pro', device_id='VGEJY9PW7T')if ret != 0:print('Init runtime environment failed')exit(ret)print('done')# Inferenceprint('--> Running model')outputs = rknn.inference(inputs=[img])show_outputs(softmax(np.array(outputs[0][0])))  # 打印结果print('done')# perf  评估模型性能print(‘→ Begin evaluate model performance’)perf_results = rknn.eval_perf(inputs=[img])print(‘done’)rknn.release()def main():# export_pytorch_model()pytorch2rknn_predict()# rknn_predict()if __name__ == '__main__':main()

构建 RKNN 模型APIbuild

# 构建 RKNN 模型,并且做量化
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')

dataset:量化校正数据的数据集。目前支持文本文件格式,用户可以把用于校正的图片(jpg 或 png 格式)或 npy 文件路径放到一个.txt 文件中。文本文件里每一行一条路径信息。
pre_compile:预编译开关,如果设置成 True,可以减小模型大小,及模型在硬件设备上的首次启动速度。但是打开这个开关后,构建出来的模型就只能在硬件平台上运行,无法通过模拟器进行推理或性能评估。如果硬件有更新,则对应的模型要重新构建。
注:

  1. 该选项不能在 RK3399Pro Linux 开发板 / Windows PC / Mac OS X PC 上使用
  2. RKNN-Toolkit-V1.0.0 及以上版本生成的预编译模型不能在 NPU 驱动版本小于0.9.6 的设备上运行;RKNN-Toolkit-V1.0.0 以前版本生成的预编译模型不能在NPU 驱 动 版 本 大 于 等 于 0.9.6 的 设 备 上 运 行 。 驱 动 版 本 号 可 以 通 过get_sdk_version 接口查询。

加载 RKNN 模型load_rknn

# 从当前路径加载 mobilenet_v1.rknn 模型
ret = rknn.load_rknn(path='./mobilenet_v1.rknn')

参数load_model_in_npu: 是否直接加载 npu 中的 rknn 模型。其中 path 为 rknn 模型在 npu中的路径。只有当 RKNN-Toolkit 运RK3399Pro Linux 开发板或连有 NPU 设备的 PC 上时才可以设为 True。默认值为 False。

模型推理API:inference
在进行模型推理前,必须先构建或加载一个 RKNN 模型。
对当前模型进行推理,返回推理结果。
如果 RKNN-Toolkit 运行在 PC 上,且初始化运行环境时设置 target 为 Rockchip NPU设备,得到的是模型在硬件平台上的推理结果。
如果 RKNN-Toolkit 运行在 PC 上,且初始化运行环境时没有设置 target,得到的是模型在模拟器上的推理结果。模拟器可以模拟 RK1808,也可以模拟 RV1126,具体模拟哪款芯片,取决于 RKNN 模型的 target_platform 参数值.
如果 RKNN-Toolkit 运行在 RK3399Pro Linux 开发板上,得到的是模型在实际硬件上的推理结果。
data_format:数据模式,可以填以下值: “nchw”, “nhwc”。默认值为’nhwc’。这两个的不同之处在于 channel 放置的位置。

评估模型性能API: eval_perf

# 对模型性能进行评估
……
rknn.eval_perf(inputs=[image], is_print=True)
……

评估模型性能。
模型运行在 PC 上,初始化运行环境时不指定 target,得到的是模型在模拟器上运行的性能数据,包含逐层的运行时间及模型完整运行一次需要的时间。模拟器可以模拟RK1808,也可以模拟 RV1126,具体模拟哪款芯片,取决于 RKNN 模型的 target_platform参数值。
模型运行在与 PC 连接的 Rockchip NPU 上,且初始化运行环境时设置 perf_debug 为 False,则获得的是模型在硬件上运行的总时间;如果设置 perf_debug 为 True,除了返回总时间外,还将返回每一层的耗时情况。
模型运行在 RK3399Pro Linux 开发板上时,如果初始化运行环境时设置 perf_debug 为 False,获得的也是模型在硬件上运行的总时间;如果设置 perf_debug 为 True,返回总时间及每一层的耗时情况

量化精度分析API:accuracy_analysis
使用浮点和量化模型推理并将每一层的结果做快照。之后再根据快照里的数据,比较量化模型和浮点模型每一层的差距,用于评估量化所产生的误差或错误。
注:

  1. 该接口只能在 buildhybrid_quantization_step1 之后调用,并且原始模型应
    该为非量化的模型,否则会调用失败。
    45
  2. 该接口使用的量化方式与 config 中指定的一致。
rknn.accuracy_analysis(inputs='./dataset.txt', target='rk3399pro')

导出加密模型API: export_encrypted_rknn_model
该接口的功能是将普通的 RKNN 模型按一定的算法进行加密。
注:

  1. 加密后的 RKNN 模型,使用方法同普通模型。
  2. 加密后的 RKNN 模型,如果使用 Python 接口部署,要注意 target 不能是模拟器;如果使用 C API 进行部署,则只要把 RKNN 模型更换即可,其他代码不用做修改。

input_model: 待加密的 RKNN 模型路径。数据类型为字符串。必填参数。
output_model: 模型加密后的保存路径。数据类型为字符串。选填参数,如果不填该参数,则使用{original_model_name}.crypt.rknn 作为加密后的模型的名字。
crypt_level: 加密等级。等级越高,安全性越高,解密越耗时;反之,安全性越低,解密越快。数据类型为整型,默认值为 1,目前安全等级有 3 个等级,1,2 和 3。

from rknn.api import RKNN
if __name__ == '__main__':rknn = RKNN()ret = rknn.export_encrypted_rknn_model('test.rknn')if ret != 0:print('Encrypt RKNN model failed.')exit(ret)rknn.release()

获取设备列表API:list_devices
列出已连接的 RK3399PRO/RK1808/RV1109/RV1126 或 TB-RK1808 AI 计算棒。
注:目前设备连接模式有两种:ADB 和 NTB。其中 RK3399PRO 目前只支持 ADB 模式,TB-RK1808 AI 计算棒只支持 NTB 模式,RK1808/RV1109 支持 ADB/NTB 模式。多设备连接时请确保他们的模式都是一样的。
返回 adb_devices 列表和 ntb_devices 列表,如果设备为空,则返回空列表。例如我们的环境里插了两个 TB-RK1808 AI 计算棒,得到的结果如下:

adb_devices = []
ntb_devices = ['TB-RK1808S0', '515e9b401c060c0b']
from rknn.api import RKNN
if __name__ == '__main__':rknn = RKNN()rknn.list_devices()rknn.release()

返回的设备列表信息如下(这里有两个 RK1808 开发板,它们的连接模式都是 adb):

*************************
all device(s) with adb mode:
['515e9b401c060c0b', 'XGOR2N4EZR']
*************************

查询模型可运行平台API: list_support_target_platform
查询给定 RKNN 模型可运行的芯片平台。
rknn_model:RKNN 模型路径。如果不指定模型路径,则按类别打印 RKNN-Toolkit当前支持的芯片平台。
support_target_platform: Returns runnable chip platforms, or None if the model path is empty.

rknn.list_support_target_platform(rknn_model=’mobilenet_v1.rknn’)

结果展示:

**************************************************
Target platforms filled in RKNN model: []
Target platforms supported by this RKNN model: ['RK1806', 'RK1808', 'RK3399PRO']
**************************************************

这篇关于RK3399Pro RKNN-Toolkit 的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/837227

相关文章

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建