前言 目前 RKNN-Toolkit 可以运行在 PC(Linux/Windows/MacOS x64)上,也可以运行在 RK3399Pro 本人推荐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’) 注: 目前 RK1806/RK1808/RV1109/RV1126 等设备支持 NTB 或 ADB 两种连接模式,RK3399Pro 开发板只支持 ADB 模式。使用多设备时,需要确保这些设备使用相同的连接模式,即 list_devices 查询出来的设备 ID 列表都是 ADB,或都是 NTB。 在 Linux 上第一次使用 NTB 设备时,非 root 用户需要获取该 USB 设备的读写权限,这 可以通过执行 SDK/platform-tools/update_rk_u***_rule/linux/update_rk1808_u***_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 = '
-----TOP 5-----
' for i in range(5): value = output_sorted index = np.where(output == value) for j in range(len(index)): if (i + j) >= 5: break if value > 0: topi = '{}: {}
'.format(index[j], value) else: topi = '-1: 0.0
' top5_str += topi print(top5_str) def show_perfs(perfs): perfs = 'perfs: {}
'.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 object rknn = RKNN() # rknn = RKNN(verbose=True, verbose_file=’./mobilenet_build.log’) # 将详细的日志信息输出到屏幕,并写到 mobilenet_build.log 文件中 # rknn = RKNN(verbose=True) # 只在屏幕打印详细的日志信息 # pre-process config print('--> 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 model print('--> 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 model print('--> 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 model print('--> 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 inputs img = cv2.imread('./space_shuttle_224.jpg') # 预测的图片 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Init runtime environment print('--> 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') # Inference print('--> 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,可以减小模型大小,及模型在硬件设备上的首次启动速度。但是打开这个开关后,构建出来的模型就只能在硬件平台上运行,无法通过模拟器进行推理或性能评估。如果硬件有更新,则对应的模型要重新构建。 注: 该选项不能在 RK3399Pro Linux 开发板 / Windows PC / Mac OS X PC 上使用。 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 使用浮点和量化模型推理并将每一层的结果做快照。之后再根据快照里的数据,比较量化模型和浮点模型每一层的差距,用于评估量化所产生的误差或错误。 注: 该接口只能在 build 或 hybrid_quantization_step1 之后调用,并且原始模型应 该为非量化的模型,否则会调用失败。
该接口使用的量化方式与 config 中指定的一致。 rknn.accuracy_analysis(inputs='./dataset.txt', target='rk3399pro') 导出加密模型API: export_encrypted_rknn_model 该接口的功能是将普通的 RKNN 模型按一定的算法进行加密。 注: 加密后的 RKNN 模型,使用方法同普通模型。 加密后的 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'] **************************************************
原作者:荪荪
|