目录
3.1.2 init_runtime接口中的per_debug参数
前言
作者使用的平台是Ubuntu20.04虚拟系统,开发板是瑞芯微RK3588开发板,开发板上使用的系统是Ubuntu22.04系统。
一、任务
学习使用性能评估和内存评估接口。
二、概念介绍
2.1 基本概念介绍
性能评估:评估模型在硬件上运行的性能;
内存评估:评估模型在硬件上运行时内存的使用情况;
由于两个评估接口都涉及到模型实际的运行情况,所以只能在连板推理的情况下使用这两个评估接口。根据模型加载方式,又可分为两种,如下所示:
第一种:直接加载RKNN模型时性能评估与内存评估流程图如下所示:

第二种:非RKNN模型时(常用的深度学习模型转化为RKNN模型后)性能评估与内存评估流程图,如下图所示:

2.2 两种评估接口
2.2.1 性能评估接口
API | eval_perf |
描述 | 评估模型性能。 模型必须运行在与PC连接的RK3566/RK3568/RK3588/RV1103/RV1106上。如果初始化运行环境时设置perf_debug为False,则获得的是模型在硬件上运行的总时间;如果设置perf_debug为True,除了返回总时间外,还将返回每一层的耗时情况。 |
is_print:是否打印性能信息,默认值为True。 | |
返回值 | perf_result:性能信息(字符串)。 |
举例如下:
1 2 3 | …… rknn.eval_perf(inputs=[image],is_print=True) …… |
2.2.2 内存评估接口
API | eval_memory |
描述 | 获取模型在硬件平台运行时的内存使用情况。 模型必须运行在与PC连接的RK3566/RK3568/RK3588/RV1103/RV1106上。 |
参数 | is_print:是否以规范格式打印内存使用情况,默认值为True。 |
返回值 | memory_detail:内存使用情况,类型为字典。 内存使用情况按照下面的格式封装在字典中: { 'total_weight_allocation':4312608 'total_internal_allocation':1756160, 'total_model_allocation':6068768 } 'total_weight_allocation'字段表示模型中权重的内存占用。 'total_internal_allocation'字段表示模型中中间tensor内存占用。 'total_model_allocation'表示模型的内存占用,即权重和中间tensor的内存占用之和。 |
举例如下:
1 2 3 | …… memory_detail=rknn.eval_memory() …… |
三、实际演示
3.1 模型性能评估
3.1.1
我们为了方便,按照直接加载RKNN模型时性能评估与内存评估流程图进行测试。
首先打开Ubuntu虚拟系统,在该系统中打开pycharm,创建项目文件夹,在项目文件夹中创建eval.py文件,将准备好的rknn模型以及测试图片拷贝到项目文件夹中。如下图所示:
流程图前三步和最后一步的代码如下:【这在之前的博文已经学习过了】
from rknn.api import RKNN
if __name__ == '__main__':
# 创建RKNN对象
rknn = RKNN()
# 使用load_rknn接口导入rknn模型
rknn.load_rknn(path='./resnet.rknn')
# 使用init_runtime接口初始化运行时环境
rknn.init_runtime(
target='rk3588',
perf_debug=None, # perf_debug表示是否开启性能评估的debug模式
eval_mem=None, # eval_mem是否使能内存评估
)
# 释放RKNN对象
rknn.release()
性能评估代码如下:
整体代码如下:
from rknn.api import RKNN
if __name__ == '__main__':
# 创建RKNN对象
rknn = RKNN()
# 使用load_rknn接口导入rknn模型
rknn.load_rknn(path='./resnet.rknn')
# 使用init_runtime接口初始化运行时环境
rknn.init_runtime(
target='rk3588',
perf_debug=None, # perf_debug表示是否开启性能评估的debug模式
eval_mem=None, # eval_mem是否使能内存评估
)
# 使用eval_perf接口进行性能评估
rknn.eval_perf(
inputs=['space_shuttle_224.jpg'], # 表示要测试的图片
data_format=None,# 表示要推理的数据模式,默认为None
is_print=True, #is_print表示使能打印性能信息
)
# 释放RKNN对象
rknn.release()
Ubuntu虚拟系统连接开发板,这一步在前面的博文也已经学习过了。
确保开发板ADB连接到虚拟系统上,连接成功之后,会在虚拟系统任务栏处显示一个手机的图标。
在MobaXterm软件中通过串口与开发板互连,启动rknn_server服务。
然后,这下就可以运行程序了。
运行程序,得到如下图所示:可以看到,终端打印出使用开发板上的RKNPU推理测试图片所需要的总时间和FPS,总时间为4907us,FPS为203.79
3.1.2 init_runtime接口中的per_debug参数
在3.1小节中init_runtime接口中的per_debug参数取值为None,那么接下来,我们将这个参数的取值改为True【设置为True表示开启性能评估的debug模式】,即由:
改为:
其余代码不变,那么修改后会出现什么情况呢?
我们来运行程序,得到:
相较于上一次程序的运行,有了更多的打印信息,我们将打印信息列出来,如下所示:
===================================================================================================================
Performance
#### The performance result is just for debugging, ####
#### may worse than actual performance! ####
===================================================================================================================
Total Weight Memory Size: 11795520
Total Internal Memory Size: 1154048
Predict Internal Memory RW Amount: 7980032
Predict Weight Memory RW Amount: 11795472
ID OpType DataType Target InputShape OutputShape DDR Cycles NPU Cycles Total Cycles Time(us) MacUsage(%) WorkLoad(0/1/2)-ImproveTherical RW(KB) FullName
1 InputOperator UINT8 CPU \ (1,3,224,224) 0 0 0 5 \ 0.0%/0.0%/0.0% - Up:0.0% 147.00 InputOperator:x.3
2 ConvRelu UINT8 NPU (1,3,224,224),(64,3,7,7),(64) (1,64,112,112) 169773 115248 169773 1399 8.24 100.0%/0.0%/0.0% - Up:0.0% 980.50 Conv:input.21_Conv
3 MaxPool INT8 NPU (1,64,112,112) (1,64,56,56) 169686 0 169686 352 \ 100.0%/0.0%/0.0% - Up:0.0% 980.00 MaxPool:input.13_MaxPool
4 ConvRelu INT8 NPU (1,64,56,56),(64,64,3,3),(64) (1,64,56,56) 74195 112896 112896 223 50.63 100.0%/0.0%/0.0% - Up:0.0% 428.50 Conv:input.17_Conv
5 ConvAdd INT8 NPU (1,64,56,56),(64,64,3,3),(64),(1,64,56,56) (1,64,56,56) 108132 112896 112896 221 51.08 100.0%/0.0%/0.0% - Up:0.0% 624.50 Conv:input.23_Conv
6 Relu INT8 NPU (1,64,56,56) (1,64,56,56) 67875 0 67875 157 \ 100.0%/0.0%/0.0% - Up:0.0% 392.00 Relu:142_Relu
7 ConvRelu INT8 NPU (1,64,56,56),(64,64,3,3),(64) (1,64,56,56) 74195 112896 112896 221 51.08 100.0%/0.0%/0.0% - Up:0.0% 428.50 Conv:input.27_Conv
8 ConvAdd INT8 NPU (1,64,56,56),(64,64,3,3),(64),(1,64,56,56) (1,64,56,56) 108132 112896 112896 220 51.32 100.0%/0.0%/0.0% - Up:0.0% 624.50 Conv:input.31_Conv
9 Relu INT8 NPU (1,64,56,56) (1,64,56,56) 67875 0 67875 156 \ 100.0%/0.0%/0.0% - Up:0.0% 392.00 Relu:191_Relu
10 Conv INT8 NPU (1,64,56,56),(128,64,1,1),(128) (1,128,28,28) 52464 6272 52464 135 4.65 100.0%/0.0%/0.0% - Up:0.0% 303.00 Conv:input.41_Conv
11 ConvRelu INT8 NPU (1,64,56,56),(128,64,3,3),(128) (1,128,28,28) 63546 56448 63546 168 33.60 100.0%/0.0%/0.0% - Up:0.0% 367.00 Conv:input.35_Conv
12 ConvAdd INT8 NPU (1,128,28,28),(128,128,3,3),(128),(1,128,28,28) (1,128,28,28) 76013 112896 112896 221 51.08 100.0%/0.0%/0.0% - Up:0.0% 439.00 Conv:input.39_Conv
13 Relu INT8 NPU (1,128,28,28) (1,128,28,28) 33938 0 33938 122 \ 100.0%/0.0%/0.0% - Up:0.0% 196.00 Relu:267_Relu
14 ConvRelu INT8 NPU (1,128,28,28),(128,128,3,3),(128) (1,128,28,28) 59044 112896 112896 222 50.85 100.0%/0.0%/0.0% - Up:0.0% 341.00 Conv:input.45_Conv
15 ConvAdd INT8 NPU (1,128,28,28),(128,128,3,3),(128),(1,128,28,28) (1,128,28,28) 76013 112896 112896 223 50.63 100.0%/0.0%/0.0% - Up:0.0% 439.00 Conv:input.49_Conv
16 Relu INT8 NPU (1,128,28,28) (1,128,28,28) 33938 0 33938 118 \ 100.0%/0.0%/0.0% - Up:0.0% 196.00 Relu:316_Relu
17 Conv INT8 NPU (1,128,28,28),(256,128,1,1),(256) (1,256,14,14) 31340 6272 31340 108 5.81 100.0%/0.0%/0.0% - Up:0.0% 181.00 Conv:input.59_Conv
18 ConvRelu INT8 NPU (1,128,28,28),(256,128,3,3),(256) (1,256,14,14) 75666 56448 75666 183 30.85 100.0%/0.0%/0.0% - Up:0.0% 437.00 Conv:input.53_Conv
19 ConvAdd INT8 NPU (1,256,14,14),(256,256,3,3),(256),(1,256,14,14) (1,256,14,14) 125533 112896 125533 220 51.32 100.0%/0.0%/0.0% - Up:0.0% 725.00 Conv:input.57_Conv
20 Relu INT8 NPU (1,256,14,14) (1,256,14,14) 16969 0 16969 100 \ 100.0%/0.0%/0.0% - Up:0.0% 98.00 Relu:392_Relu
21 ConvRelu INT8 NPU (1,256,14,14),(256,256,3,3),(256) (1,256,14,14) 117049 112896 117049 223 50.63 100.0%/0.0%/0.0% - Up:0.0% 676.00 Conv:input.63_Conv
22 ConvAdd INT8 NPU (1,256,14,14),(256,256,3,3),(256),(1,256,14,14) (1,256,14,14) 125533 112896 125533 230 49.09 100.0%/0.0%/0.0% - Up:0.0% 725.00 Conv:input.67_Conv
23 Relu INT8 NPU (1,256,14,14) (1,256,14,14) 16969 0 16969 112 \ 100.0%/0.0%/0.0% - Up:0.0% 98.00 Relu:441_Relu
24 Conv INT8 NPU (1,256,14,14),(512,256,1,1),(512) (1,512,7,7) 35583 6272 35583 116 5.41 100.0%/0.0%/0.0% - Up:0.0% 205.50 Conv:input.10_Conv
25 ConvRelu INT8 NPU (1,256,14,14),(512,256,3,3),(512) (1,512,7,7) 212887 56448 212887 253 22.31 100.0%/0.0%/0.0% - Up:0.0% 1229.50 Conv:input.6_Conv
26 ConvAdd INT8 NPU (1,512,7,7),(512,512,3,3),(512),(1,512,7,7) (1,512,7,7) 412354 112896 412354 409 27.60 100.0%/0.0%/0.0% - Up:0.0% 2381.50 Conv:input.9_Conv
27 Relu INT8 NPU (1,512,7,7) (1,512,7,7) 8485 0 8485 92 \ 100.0%/0.0%/0.0% - Up:0.0% 49.00 Relu:517_Relu
28 ConvRelu INT8 NPU (1,512,7,7),(512,512,3,3),(512) (1,512,7,7) 408111 112896 408111 410 27.54 100.0%/0.0%/0.0% - Up:0.0% 2357.00 Conv:input.5_Conv
29 ConvAdd INT8 NPU (1,512,7,7),(512,512,3,3),(512),(1,512,7,7) (1,512,7,7) 412354 112896 412354 411 27.47 100.0%/0.0%/0.0% - Up:0.0% 2381.50 Conv:input.1_Conv
30 Relu INT8 NPU (1,512,7,7) (1,512,7,7) 8485 0 8485 108 \ 100.0%/0.0%/0.0% - Up:0.0% 49.00 Relu:566_Relu
31 Conv INT8 NPU (1,512,7,7),(1,512,7,7),(512) (1,512,1,1) 9264 24 9264 94 0.03 100.0%/0.0%/0.0% - Up:0.0% 53.50 Conv:x.1
32 Conv INT8 NPU (1,512,1,1),(1000,512,1,1),(1000) (1,1000,1,1) 88217 500 88217 153 0.33 100.0%/0.0%/0.0% - Up:0.0% 509.48 Conv:572_Gemm_2conv
33 Reshape INT8 CPU (1,1000,1,1),(2) (1,1000) 0 0 0 26 \ 0.0%/0.0%/0.0% - Up:0.0% 1.98 Reshape:572_Gemm_2conv_reshape2
34 OutputOperator INT8 CPU (1,1000),(1,1000) \ 0 0 0 7 \ 0.0%/0.0%/0.0% - Up:0.0% 1.95 OutputOperator:572
Total Operator Elapsed Time(us): 7418
===================================================================================================================
Total Weight Memory Size: 表示rknn模型参数所占据内存的总大小。
Total Internal Memory Size: 表示非权重值所占据内存的总大小。
Predict Internal Memory RW Amount: 模型推理时非权重值所需要的内存读写量。
Predict Weight Memory RW Amount: 模型推理时权重值所需要的内存读写量。
ID: 表示网络对应层操作的唯一编号。
OpType: 表示该层数据的操作类型。
DataType: 表示该层输入和输出的数据类型。由于本次使用的rknn模型都经过了量化操作,因此观察到所有层的DataType均为int8类型。
Target: 表示该层操作的设备单元。可以看到只有数据的输入、输出以及数据的reshape操作在CPU上执行,其余的层均在NPU上执行。
InputShape: 表示该层输入数据的形状。
OutputShape: 表示该层输出数据的形状。
DDR Cycles: 表示该层在内存DDR中计算所需要的周期数。
NPU Cycles: 表示该层在NPU中计算所需要的周期数。
Total Cycles: DDR Cycles 和 NPU Cycles 中较大的那一个。
Time(us): 表示该层计算的总时间。
MacUsage(%): 表示该层计算时所使用的乘加单元占用率,可以简单的理解为NPU的使用率。
WorkLoad(0/1/2)-ImproveTherical: 表示该层在未来优化中可能提升的潜力。
RW(KB): 表示该层计算时所需要的内存读写量。
FullName: 表示该层完整的名称。
Total Operator Elapsed Time(us): 本次推理操作总耗时。
至此,对于RKNN模型性能评估相关知识已经介绍完成。接下来我们要编写内存评估的相关程序了。
3.2 模型内存评估
首先将init_runtime接口中的eval_mem参数由None改为True,即由:
修改为: 然后注释掉与性能评估的代码:
随后编写内存评估的代码:
其余代码不变。
然后执行修改后的程序,得到:
由上图可知,打印出了NPU模型所占用的内存空间的详细信息,包括总权重所占内存大小【Total Weight Memory】,总内部张量所占内存大小【Total Internal Tensor Memory】以及总共所占内存大小【Total Memory】。Total Memory=Total Weight Memory+Total Internal Tensor Memory
INFO: When evaluating memory usage, we need consider the size of model, current model size is: 11.47 MiB 表示当前模型尺寸大小为11.47MiB。
至此,我们也完成了RKNN模型的内存评估。