2. NPU使用

NPU是专门用于神经网络的处理单元。它旨在加速人工智能领域的神经网络算法,如机器视觉和自然语言处理。随着人工智能的应用范围正在扩大,目前 提供各种领域的功能,包括面部跟踪、手势和身体跟踪、图像分类、视频监控、自动语音识别(ASR)以及高级驾驶员辅助系统(ADAS)等。

lubancat-zero、LubanCat-1/LubanCat-2系列板卡,使用瑞芯微rk356X处理器, rk3568和rk3566都内置NPU模块,最高可达1TOPS,支持整数8、整数16卷积运算,支持深度学习框架:TensorFlow、TF-lite、Pytorch、Caffe、ONNX等等。

瑞芯微官方提供了rknpu2和rknn-Toolkit2工具,SDK为带有RKNPU的芯片平台提供编程接口。 Rockchip NPU平台使用RKNN模型,RKNN模型是可以使用rknn-Toolkit2软件开发工具包转换,部署到板卡使用rknn-Toolkit-Lite2。

本章将简单介绍在PC(Ubuntu系统)上使用RKNN-Toolkit2进行模型转换、模型推理、性能评估等,并在板卡上使用RKNN Toolkit Lite2部署。

重要

本章教程测试环境:鲁班猫RK系列板卡,镜像系统是Debian10(Python 3.7.3 , OpenCV 4.7.0.68),PC环境使用ubuntu20.04(python3.8.10)。 教程编写时的RKNN-Toolkit2是1.4.0版本,板卡npu驱动是0.7.2,rknnrt是1.4.0,adb工具1.0.40。

2.1. rknn-Toolkit2

RKNN-Toolkit2工具在PC平台上使用,提供python接口简化模型的部署和运行,用户 通过该工具可以便捷地完成以下功能:模型转换、量化功能、模型推理、性能和内存评估、量化精度分析、模型加密功能。

RKNN-Toolkit2目前版本适用系统是Ubuntu18.04/Ubuntu20.04/Ubuntu22.04,更多依赖和使用信息可以看下 《RKNN Toolkit2 快速上手指南》。

RKNN-Toolkit2工程文件可以直接从官方 github地址 拉取或者从 云盘资料下载 (提取码hslu),在 1-野火开源图书_教程文档->参考代码 。 (获取的RKNN-Toolkit2文件中包含RKNN Toolkit Lite2)

2.1.1. rknn-Toolkit2安装

环境安装(PC ubuntu20.04):

#安装python工具,ubuntu20.04默认是安装了python3.8.10
sudo apt update
sudo apt-get install python3-dev python3-pip python3.8-venv gcc

#安装相关库和软件包
sudo apt-get install libxslt1-dev zlib1g-dev libglib2.0 libsm6 \
libgl1-mesa-glx libprotobuf-dev gcc

安装RKNN-Toolkit2:

#创建目录,由于测试使用的ubuntu20.04已经安装的包可能和安装运行RKNN-Toolkit2所需的包版本不同,为避免其他问题,这里使用python venv隔离环境
mkdir project-Toolkit2 && cd project-Toolkit2
python3 -m venv .toolkit2_env
# 激活进入环境
source .toolkit2_env/bin/activate

#拉取源码,或者复制RKNN-Toolkit2到该目录
git clone https://github.com/rockchip-linux/rknn-toolkit2.git

#使用pip3安装包时可能很慢,设置下源
pip3 config set global.index-url https://mirror.baidu.com/pypi/simple

#安装依赖库,根据rknn-toolkit2\doc\requirements_cp38-1.4.0.txt
pip3 install numpy
pip3 install -r doc/requirements_cp38-1.4.0.txt

#安装rknn_toolkit2
pip3 install packages/rknn_toolkit2-1.4.0_22dcfef4-cp38-cp38-linux_x86_64.whl

检测是否安装成功:

(.toolkit2_env) llh@-:~/project-Toolkit2$ python
Python 3.8.10 (default, Jun 22 2022, 20:18:18)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from rknn.api import RKNN
>>>

2.1.2. 模型转换和模型推理

在RKNN-Toolkit2文件中example目录下有各种功能的例程,进入../examples/onnx/yolov5目录 该Demo展示了在PC上将onnx模型转换成RKNN模型,然后导出、推理、部署到NPU平台运行并取回结果的过程。

执行命令:

# 切换到examples/onnx/yolov5目录下
cd examples/onnx/yolov5
# 模型转换和模型推理
python test.py

运行导出成功后,会在当前目录下生成yolov5s.rknn文件,该文件在接下来的Toolkit Lite2小节将会使用到。

上面运行yolov5例程同时也会进行模型推理,会在当前目录下输出结果图片(out.jpg)。

2.1.3. 性能和内存评估

RKNN-Toolkit2除了可以模拟推理测试,也可以进行简单连板调试, 鲁班猫一些板卡usb接口不能直接usb adb调试,但可以使用网络adb连接进行调试。

连板调试板端需要启动adbd和rknn_server服务。PC端的adb server需要连接到adbd,这样就可以通过客户端与设备端进行沟通。 rknn_server是一个运行在板子上的后台代理服务,用于接收PC通过USB传输过来的协议,然后执行板端runtime对应的接口,并返回结果给PC端。

# 复制文件到板卡(可以通过scp sftp nfs等方式,文件在配套例程或者看下后面的参考链接,到RKNPU2的runtime\RK356X\Linux\rknn_server目录下获取)

# 添加可执行权限
cd  ../usr/bin
chmod +x rknn_server restart_rknn.sh start_rknn.sh

# 启动rknn_server
restart_rknn.sh

# 查看服务adbd的状态,处于active即可
sudo systemctl status adbd.service
sudo /usr/bin/adbd &

板子和PC连接在一个局域网下,测试使用本教程的配套程序:

# PC端安装adb
sudo apt install adb
# 开启adb server
adb start-server
# 连接板子,根据板子实际IP,默认5555端口
adb connect 192.168.103.115

# 查看连接的设备,确认初始化运行时的device_id
adb devices
cd examples/onnx/yolov5

# 运行程序,连板调试
python test.py

简单测试结果:

W __init__: rknn-toolkit2 version: 1.4.0-22dcfef4
--> Config model
done
--> Loading model
done
--> Building model
Analysing : 100%|███████████████████████████████████████████████| 142/142 [00:00<00:00, 2940.26it/s]
Quantizating : 100%|█████████████████████████████████████████████| 142/142 [00:00<00:00, 336.83it/s]
W build: The default input dtype of 'images' is changed from 'float32' to 'int8' in rknn model for performance!
                    Please take care of this change when deploy rknn model with Runtime API!
W build: The default output dtype of 'output' is changed from 'float32' to 'int8' in rknn model for performance!
                    Please take care of this change when deploy rknn model with Runtime API!
W build: The default output dtype of '327' is changed from 'float32' to 'int8' in rknn model for performance!
                    Please take care of this change when deploy rknn model with Runtime API!
W build: The default output dtype of '328' is changed from 'float32' to 'int8' in rknn model for performance!
                    Please take care of this change when deploy rknn model with Runtime API!
done
--> Export rknn model
done
--> Init runtime environment
W init_runtime: Flag perf_debug has been set, it will affect the performance of inference!
I NPUTransfer: Starting NPU Transfer Client, Transfer version 2.1.0 (b5861e7@2020-11-23T11:50:36)
D RKNNAPI: ==============================================
D RKNNAPI: RKNN VERSION:
D RKNNAPI:   API: 1.4.0 (bb6dac9 build: 2022-08-29 16:17:01)(null)
D RKNNAPI:   DRV: rknn_server: 1.3.0 (121b661 build: 2022-04-29 11:11:47)
D RKNNAPI:   DRV: rknnrt: 1.4.0 (a10f100eb@2022-09-09T09:07:14)
D RKNNAPI: ==============================================
done
===================================================================================================================
                            Performance
        #### The performance result is just for debugging, ####
        #### may worse than actual performance!            ####
===================================================================================================================
Total Weight Memory Size: 7312768
Total Internal Memory Size: 7782400
Predict Internal Memory RW Amount: 134547200
Predict Weight Memory RW Amount: 7312768
ID   OpType           DataType Target InputShape                                   OutputShape            DDR Cycles     NPU Cycles     Total Cycles   Time(us)       MacUsage(%)    RW(KB)         FullName
0    InputOperator    UINT8    CPU    \                                            (1,3,640,640)          0              0              0              19             \              1200.00        InputOperator:images
1    Conv             UINT8    NPU    (1,3,640,640),(32,3,6,6),(32)                (1,32,320,320)         1493409        691200         1493409        11956          9.64           4409.25        Conv:Conv_0
2    exSwish          INT8     NPU    (1,32,320,320)                               (1,32,320,320)         2167674        0              2167674        5408           \              6400.00        exSwish:Sigmoid_1_2swish
3    Conv             INT8     NPU    (1,32,320,320),(64,32,3,3),(64)              (1,64,160,160)         1632022        921600         1632022        4153           36.99          4818.50        Conv:Conv_3
4    exSwish          INT8     NPU    (1,64,160,160)                               (1,64,160,160)         1083837        0              1083837        2849           \              3200.00        exSwish:Sigmoid_4_2swish
5    Conv             INT8     NPU    (1,64,160,160),(32,64,1,1),(32)              (1,32,160,160)         813640         102400         813640         1455           11.73          2402.25        Conv:Conv_6
6    exSwish          INT8     NPU    (1,32,160,160)                               (1,32,160,160)         541919         0              541919         1456           \              1600.00        exSwish:Sigmoid_7_2swish
........(中间省略)
142  Conv             INT8     NPU    (1,128,80,80),(255,128,1,1),(255)            (1,255,80,80)          824352         408000         824352         1040           65.38          2433.88        Conv:Conv_198
143  OutputOperator   INT8     CPU    (1,255,80,80),(1,80,80,256)                  \                      0              0              0              1011           \              3200.00        OutputOperator:output
144  OutputOperator   INT8     CPU    (1,255,40,40),(1,40,40,256)                  \                      0              0              0              216            \              800.00         OutputOperator:327
145  OutputOperator   INT8     CPU    (1,255,20,20),(1,20,20,256)                  \                      0              0              0              178            \              220.00         OutputOperator:328
Total Operator Elapsed Time(us): 117367

===================================================================================================================

上面测试可以看到开启了量化,并且调用了eval_perf对模型性能进行评估,获取测试模型的整体耗时及每一层的耗时情况,以上就是简单连接调试。

更多rknn-toolkit2的功能测试例程,参考下https://github.com/rockchip-linux/rknn-toolkit2/tree/master/examples/functions。

2.2. RKNN Toolkit Lite2

RKNN Toolkit Lite2为Rockchip NPU平台提供Python编程接口,用于在板端部署RKNN模型。

2.2.1. 板卡上安装RKNN Toolkit Lite2

Toolkit-lite2适用于开发板系统端部署推理模型,更多依赖和使用信息可以看下 RKNN用户手册

获取RKNN Toolkit Lite2,可以直接从官方github获取,或者在配套例程中,将文件传输到板卡中,直接git到板卡也行。 获取到的Toolkit Lite2目录结构如下:

broken

环境安装(以LubanCat 2,Debian10为例):

sudo apt update

#安装其他python工具
sudo apt-get install python3-dev python3-pip gcc

#安装相关依赖和软件包
pip3 install wheel
sudo apt-get install -y python3-opencv
sudo apt-get install -y python3-numpy
sudo apt -y install python3-setuptools

Toolkit Lite2工具安装:

# 进入到rknn_toolkit_lite2/packages目录下,选择Debian10 ARM64 with python3.7.3的whl文件安装:
pip3 install rknn_toolkit_lite2-1.4.0-cp37-cp37m-linux_aarch64.whl

安装成功:

broken

2.2.2. 板端部署推理

librknnrt.so是一个板端的runtime库,运行需要该库,板卡默认镜像/usr/lib目录下有librknnrt.so库, 但是需要更新下,选择对应版本的librknnrt.so。

librknnrt.so具体在rknpu2工程中runtime/目录下,根据不同板卡,系统选择目录,例如LubanCat-0/1/2板卡选择runtime/RK356X/Linux/librknn_api/aarch64/目录中的librknnrt.so, 然后复制该库到板卡系统/usr/lib/目录下。

rknpu2工程文件可以从https://github.com/rockchip-linux/rknpu2获取,或者从 云盘资料下载 (提取码hslu):

broken

运行RKNN Toolkit Lite2的Demo,进入获取到的Toolkit Lite2目录,在../examples/inference_with_lite目录下执行命令:

broken

修改下Toolkit Lite2工具中的examples/onnx/yolov5例程,简单改下test.py,使用RKNN Toolkit Lite2部署, 导入前面RKNN-Toolkit2转换出的yolov5s.rknn(修改后的源文件参考配套例程):

cat@lubancat:~/yolov5$ python test.py
--> Load RKNN model
done
--> Init runtime environment
I RKNN: [10:29:36.521] RKNN Runtime Information: librknnrt version: 1.4.0 (a10f100eb@2022-09-09T09:07:14)
I RKNN: [10:29:36.521] RKNN Driver Information: version: 0.7.2
I RKNN: [10:29:36.524] RKNN Model Information: version: 1, toolkit version: 1.4.0-22dcfef4(compiler version: 1.4.0 (3b4520e4f@2022-09-05T20:52:35)), target: RKNPU lite, target platform: rk3568, framework name: ONNX, framework layout: NCHW
done
--> Running model
done
class: person, score: 0.8352155685424805
box coordinate left,top,right,down: [211.9896697998047, 246.17460775375366, 283.70787048339844, 515.0830216407776]
class: person, score: 0.8330121040344238
box coordinate left,top,right,down: [473.26745200157166, 231.93780636787415, 562.1268351078033, 519.7597033977509]
class: person, score: 0.7970154881477356
box coordinate left,top,right,down: [114.68497347831726, 233.11390662193298, 207.21904873847961, 546.7821505069733]
class: person, score: 0.4651743769645691
box coordinate left,top,right,down: [79.09242534637451, 334.77847719192505, 121.60038471221924, 518.6368670463562]
class: bus , score: 0.7837686538696289
box coordinate left,top,right,down: [86.41703361272812, 134.41848754882812, 558.1083570122719, 460.4184875488281]

(post process result:1896): dbind-WARNING **: 10:31:30.000: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
cat@lubancat:~/yolov5$ ls
bus.jpg  dataset.txt  onnx_yolov5_0.npy  onnx_yolov5_1.npy  onnx_yolov5_2.npy  out.jpg  test.py  yolov5s.onnx  yolov5s.rknn

运行正常可以显示(或者查看输出图片out.jpg):

broken

提示

默认配套例程../yolov5/test.py是没有使用cv2.imshow()显示图片。

2.3. 相关频率设置(rk356X)

鲁班猫板卡CPU默认是 interactive 状态,它会根据CPU使用率和目标负载来动态地调整CPU频率。 为获得更高运行速度或者性能评估,我们需要手动固定频率,参考下这:

1、CPU频率设置:

# 查看CPU当前频率
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

# 查看CPU当前调频策略
cat  /sys/devices/system/cpu/cpufreq/policy0/scaling_governor

# 查看可以设置的频率
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies

# 设置允许root权限的用户通过sysfs的“scaling_setspeed字段将cpu频率设置成用户想要的频率
echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor

# 设置需要固定的频率
echo 1800000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed

2、DDR频率设置:

# 查看DDR当前频率
cat /sys/class/devfreq/dmc/cur_freq

# 查看DDR当前调频策略
cat  /sys/class/devfreq/dmc/governor

# 查看DDR可以设置的频率
 cat /sys/class/devfreq/dmc/available_frequencies

# 设置允许root权限的用户通过sysfs的“scaling_setspeed字段将cpu频率设置成用户想要的频率
echo userspace >  /sys/class/devfreq/dmc/governor

# 设置需要固定的频率,这里是1056000000
echo 1056000000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed

3、NPU频率设置:

# 查看NPU查看可用的频率
cat /sys/class/devfreq/fde40000.npu/available_frequencies

echo userspace > /sys/class/devfreq/fde40000.npu/governor
# 设置频率
echo 900000000 > /sys/kernel/debug/clk/clk_scmi_npu/clk_rate

# 查看当前npu频率
cat /sys/class/devfreq/fde40000.npu/cur_freq

# 或者使用下面命令查看
cat /sys/kernel/debug/clk/clk_summary | grep npu