瑞芯微电子RV1126芯片环境搭建&SSD模型转换指南
引子
国产AI芯片这个集合,一直想补充的完整点。故翻了翻陈年的笔记,找到当年使用瑞芯微电子出的一款芯片RV1126的使用笔记,当时拿到的是一款基于RV1126的IP摄像头,在此整理记录下。OK,让我们开始吧。
一、文档
首先拿到官方的SDK包,解压后,SDK文档目录:rv1109_1126_sdk\RV1109_1126\docs\Socs\RV1126_RV1109\Rockchip_RV1126_RV1109_Linux_SDK_V1.1.1_20200711_CN.pdf
二、开发
1、win10连接虚拟机
文件夹直接输入:\\192.168.201.137\share
2、连接虚拟机ssh
3、安装虚拟机依赖库
sudo apt-get install g++-arm-linux-gnueabihf
sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install lib32gcc-7-dev g++-7 libstdc++-7-dev
sudo apt install openssh-server android-tools-adb vim net-tools git cmake tree minicom gawk bison flex ibssl-dev device-tree-compiler gcc-aarch64-linux-gnu mtools parted libudev-dev libusb-1.0-0-dev autoconf autotools-dev libsigsegv2 m4 intltool libdrm-dev curl sed make binutils build-essential gcc g++ bash patch gzip gawk bzip2 perl tar cpio python unzip rsync file bc wget libncurses5 u-boot-tools cvs mercurial rsync openssh-client subversion expect fakeroot liblz4-tool libtool keychain
4、不同板子选择不同mk编译
./build.sh lunch
选择 1. BoardConfig-38x38-spi-nand.mk
5、kernel编译
./build.sh kernel
6、uboot编译
./build.sh uboot
7、rootfs编译
a、rootfs编译命令(第一次执行)
./build.sh rootfs
b、当前SDK版本默认编译命令
source envsetup.sh rockchip_rv1126_rv1109
make
c、clean与重新编译
make xxx-dirclean xxx:模块名称
make xxx-rebuild
8、连接RV1126
a、插网线、上电源、连接USB线至连接至虚拟机
b、adb shell(已安装adb)
c、ifconfig 查看RV1126 ip 例如:192.168.201.38
d、浏览器打开,输入账号密码:admin,即可得到网络相机视频流
9、ssd、mobilenet demo运行 find . -name "rknn_ssd_demo"
a、cd /buildroot/output/rockchip_rv1126_rv1109/build/rknpu-1.2.1/rknn/rknn_api/examples/rknn_mobilenet_demo
b、修改build.sh文件中gcc工作目录
GCC_COMPILER=/home/ashyar/share/RV1126/RV1109_1126/prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
c、编译可执行文件
./build.sh
d、将可执行文件、模型、测试图片adb push到板子上
adb push XXX ./tmp/userdata
e、运行
先kill掉mediaserver
ps -elf | grep mediaserver
kill -9 xxx
./rknn_ssd_demo model/ssd_inception_v2_rv1109_rv1126.rknn model/road.bmp
三、模型转换
1、安装tensorflow1.14版本
pip install tensorflow==1.14
2、依赖库安装
pip install ruamel.yaml==0.15.81 flatbuffers==1.10 flask==1.0.2 lmdb==0.93 requests==2.22.0 onnx==1.4.1 numpy==1.16.3 dill==0.2.8.2 networkx==1.11 Pillow==5.3.0 ply==3.11 h5py==2.8.0 psutil==5.6.2 protobuf==3.6.1 scipy==1.3.0 onnx-tf==1.2.1
3、rknn 1.4安装
pip install rknn -i http://repo.rock-chips.com/pypi/simple --trusted-host repo.rock-chips.com
4、模型转换
cd rknn-toolkit-master/examples/rknn_convert
修改config文件
最后一行增加
target_platform: rv1126
运行:python rknn_convert.py ./models/tensorflow/mobilenet-ssd/ ./ True
验证:执行二(6)、三(4)步骤
四、PC端与边端互通设置
查看CPU占用率:busybox top
相机取图泛红bug沟通解决,IR_CUT为硬件相关设备,敲击相机,颜色正常后,拔掉IR_CUT线即可固定成像效果
注意:目标检测第一类为背景。列表中第一类置空或者为background的,否则会报错,VLC软件设置300ms
1、mqtt PC端
a、下载mosquitto 软件https://mosquitto.org/files/binary/win64/ 1.6.8版本,
b、安装目录下修改mosquiito.conf配置
208行 bind_address新增127.0.0.1
c、我的电脑-管理-服务 启动Mosquitto Broken服务
2、mqtt边端
a、编译
mkdir build
cd build
cmake .. -DPAHO_BUILD_STATIC=TRUE -DCMAKE_C_COMPILER=/home/ashyar/share/RV1126/RV1109_1126/prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
make
make install DESTDIR=./install/
头文件和lib中的so动态库文件libpaho-mqtt3a.so, libpaho-mqtt3a.so.1 即可以直接导入RV1126使用
ldd grpcclient 查看grpcclient缺少哪个动态库软链接
ln -s ../3rdparty/libs/grpc/libgpr.so libgpr.so.10
五、SSD-mobilenet迁移到RK3399Pro
1、硬件介绍
RK3399Pro人工智能芯片,采用了ARM双核Cortex-A72 + 四核Cortex-A53的大小核处理器架构(big.LITTLE大小核CPU架构),主频高达1.8GHz,集成Mali-T860 MP4 四核图形处理器。片上集成了AI神经网络处理器NPU,支持8Bit/16Bit运算,运算性能高达3.0TOPs。
(1)2.0 部件框图
RK3399Pro是具有CPU、GPU、NPU的SoC(RK3399pro = RK3399+NPU)
CPU:有两个A72,四个A53
GPU:ARM Mali T860 MP4 GPU
NPU:自研架构
同时还有一些其他部件,如DSP、ISP等。
(2)核心板功能参数
TB-96AI是一款开源的核心板,高度集成,只需开发简单的应用载板即可组成产品。针对RK3399pro芯片特性,在软硬件层面进行了多项优化。http://t.rock-chips.com/portal.php?mod=view&aid=30
(3)RG-IVC207开发板
我们手头的RK3399Pro开发板:RG-IVC207旧板子,内存是1.9GB,闪存是20GB,默认Fedora28系统。目前板子上用的rknn_toolkit版本是v1.2.0。1.3.0和1.3.0beta也已发布,可尝试使用。
2、SSD-mobilenet模型转换
以下步骤是在环境已经搭建好的情况下进行。
(1)拿到示例代码
RK3399Pro的SDK的example目录下有示例代码。需要提供prior_box.txt,labels.txt,测试集图片、dataset.txt和pb模型。
(2)生成box_priors.txt
回到SSD-mobilenet_tf的训练代码,在ssd_meta_arch.py中添加如下代码,在research目录下执行python setup.py install,运行model_main.py(即训练,训练时有生成),即可生成保存prior_boxes的文件box_priors.txt。在索书号场景下,有1917个prior_box。代码如下:
在 tensorflow\models\research\object_detection\meta_architectures\ssd_meta_arch.py
predictions_dict = {
'preprocessed_inputs': preprocessed_inputs,
'feature_maps': feature_maps,
'anchors': self._anchors.get()
} 代码后添加以下代码:
sess = tf.Session()
with sess.as_default():
anchors_np = self._anchors.get().eval()
anchors_np = anchors_np.transpose()
minx = anchors_np[0]
miny = anchors_np[1]
maxx = anchors_np[2]
maxy = anchors_np[3]
cx = (minx + maxx) / 2.
cy = (miny + maxy) / 2.
w = maxx - minx
h = maxy - miny
np.savetxt('box_priors.txt', (cx, cy, w, h), fmt='%0.8f')
即可保存 box_priors.txt 文件
(3)确定模型的输入输出节点
用Netron软件打开pb模型,查看网络节点(在预处理和后处理之间)。要注意,SSD模型的输入节点一般是第一个网络层Conv2D,注意不是Mul层,输出节点一般都是concat和concat_1。
(4)其他参数设置
a、修改NUM_CLASSES:我有3类,但NUM_CLASSES=4才可以
b、修改NUM_RESULTS:prior_box的数量,图书馆场景下有2592个。
c、修改INPUT_SIZE,宽高顺序和训练时的一样。
d、如果要量化,dataset.txt可以保存训练集的一部分和测试集的一部分图片名称,根据经验共200张就够,作为量化时的比对。将来测试集更新的话,不需要改动dataset.txt。
(5)运行
修改示例代码其他部分并运行。例如用我写的ssd_batch.py,可以批量推演图片并保存结果到txt中。
(6)Tips
a、我遇到过的错误提示:
AttributeError: 'NoneType' object has no attribute 'get_input_layers'
unkown layer tensorarraygatherV3
Please give image_tensor:0 the tensor shape:
AttributeError: 'NoneType' object has no attribute 'op'
ValueError: Dimensions must be equal, but are 3 and 24 for 'FeatureExtractor/InceptionV2/InceptionV2/Conv2d_1a_7x7/separable_conv2d' (op: 'Conv2D') with input shapes: [1,300,300,3], [1,1,24,64].
ValueError: NodeDef mentions attr 'Truncate' not in Op<name=cast; signature="x:SrcT" -=""> y:DstT; attr=SrcT:type; attr=DstT:type>; NodeDef: ToFloat = Cast[DstT=DT_FLOAT, SrcT=DT_UINT8, Truncate=false](image_tensor). (Check whether your GraphDef-interpreting binary is up to date with your GraphDef-generating binary.)
以上都是因为输入输出的节点设置错误。
b、Toybrick-开源社区,官方论坛,很有用
c、据说RK3399Pro对mobilenet的depthwise convolution的支持不好,导致ssd-mobilenet在RK3399Pro上会掉点,建议backbone换成inception-v2,精度和性能都更好。使用inception训练时可以修改depth multiplier参数,如从1改成0.5,减小卷积层的宽度,以提高性能(当然同时精度会有点损失)。