7.1 KiB
支持 RKNN
本教程基于 Ubuntu-18.04 和 Rockchip rk3588
NPU。对于不同的 NPU 设备,您需要使用不同的 rknn 包.
这是设备和安装包的关系表:
Device | Python Package | c/c++ SDK |
---|---|---|
RK1808/RK1806 | rknn-toolkit | rknpu |
RV1109/RV1126 | rknn-toolkit | rknpu |
RK3566/RK3568/RK3588 | rknn-toolkit2 | rknpu2 |
RV1103/RV1106 | rknn-toolkit2 | rknpu2 |
安装
建议为项目创建一个虚拟环境。
-
使用 git 获取 RKNN-Toolkit2 或者 RKNN-Toolkit。以 RKNN-Toolkit2 为例:
git clone git@github.com:rockchip-linux/rknn-toolkit2.git
-
通过 rknn-toolkit2 文档 或者 rknn-toolkit 文档安装 RKNN python 安装包。安装 rknn python 包时,最好在安装命令后添加
--no-deps
,以避免依赖包的冲突。以rknn-toolkit2为例:pip install packages/rknn_toolkit2-1.2.0_f7bb160f-cp36-cp36m-linux_x86_64.whl --no-deps
-
先安装onnx==1.8.0,跟着 instructions,源码安装 MMDeploy。 需要注意的是, MMDeploy 和 RKNN 依赖的安装包间有冲突的内容. 这里提供建议在 python 3.6 环境中使用的安装包版本:
protobuf==3.19.4 onnx==1.8.0 onnxruntime==1.8.0 torch==1.8.0 torchvision==0.9.0
-
使用 conda 安装 torch and torchvision,比如:
conda install pytorch==1.8.0 torchvision==0.9.0 cudatoolkit=11.1 -c pytorch -c conda-forge
如要使用 MMClassification, 需要用户自己安装使用。
使用
例子:
python tools/deploy.py \
configs/mmcls/classification_rknn_static.py \
/mmclassification_dir/configs/resnet/resnet50_8xb32_in1k.py \
https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_batch256_imagenet_20200708-cfb998bf.pth \
/mmclassification_dir/demo/demo.JPEG \
--work-dir ../resnet50 \
--device cpu
部署 config
部署 config,你可以根据需要修改 backend_config
字段. 一个 mmclassification 的 backend_config
例子如下:
backend_config = dict(
type='rknn',
common_config=dict(
mean_values=None,
std_values=None,
target_platform='rk3588',
optimization_level=3),
quantization_config=dict(do_quantization=False, dataset=None),
input_size_list=[[3, 224, 224]])
common_config
的内容服务于 rknn.config()
. quantization_config
的内容服务于 rknn.build()
。
安装 SDK
RKNPU2 编译 MMDeploy SDK
-
获取 rknpu2:
git clone git@github.com:rockchip-linux/rknpu2.git
-
在 linux 系统, 下载 gcc 交叉编译器.
rknpu2
的官方提供的下载链接无法使用了. 用户可以使用另一个 链接. 下载并解压完编译器, 打开终端, 设置RKNN_TOOL_CHAIN
和RKNPU2_DEVICE_DIR
为export RKNN_TOOL_CHAIN=/path/to/gcc/usr;export RKNPU2_DEVICE_DIR=/path/to/rknpu2/runtime/RK3588
。 -
上述准备工作完成后, 运行如下指令安装:
cd /path/to/mmdeploy
mkdir -p build && rm -rf build/CM* && cd build
export LD_LIBRARY_PATH=$RKNN_TOOL_CHAIN/lib64:$LD_LIBRARY_PATH
cmake \
-DCMAKE_TOOLCHAIN_FILE=/path/to/mmdeploy/cmake/toolchains/rknpu2-linux-gnu.cmake \
-DMMDEPLOY_BUILD_SDK=ON \
-DCMAKE_BUILD_TYPE=Debug \
-DOpenCV_DIR=${RKNPU2_DEVICE_DIR}/../../examples/3rdparty/opencv/opencv-linux-aarch64/share/OpenCV \
-DMMDEPLOY_BUILD_SDK_PYTHON_API=ON \
-DMMDEPLOY_TARGET_DEVICES="cpu" \
-DMMDEPLOY_TARGET_BACKENDS="rknn" \
-DMMDEPLOY_CODEBASES=all \
-DMMDEPLOY_BUILD_TEST=ON \
-DMMDEPLOY_BUILD_EXAMPLES=ON \
..
make && make install
运行 SDK 的 demo
首先,确保--dump-info
在转模型的时候调用了, 这样工作目录下包含 SDK 需要的配置文件 pipeline.json
。
使用 adb push
将模型路径,执行文件和.so 文件传到板子上。
cd /path/to/mmdeploy
adb push resnet50 /data/local/tmp/resnet50
adb push /mmclassification_dir/demo/demo.JPEG /data/local/tmp/resnet50/demo.JPEG
cd build
adb push lib /data/local/tmp/lib
adb push bin/image_classification /data/local/tmp/image_classification
设置环境变量,运行例子。
adb shell
cd /data/local/tmp
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/data/local/tmp/lib
./image_classification cpu ./resnet50 ./resnet50/demo.JPEG
..
label: 65, score: 0.95
问题点
-
量化失败.
经验来说, 如果
do_quantization
被设置为True
,RKNN 需要的输入没有被归一化过。请修改Normalize
在model_cfg
的设置,如将img_norm_cfg = dict( mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
改为
img_norm_cfg = dict( mean=[0, 0, 0], std=[1, 1, 1], to_rgb=True)
此外, deploy_cfg 的
mean_values
和std_values
应该被设置为model_cfg
中归一化的设置. 使mean_values=[[103.53, 116.28, 123.675]]
,std_values=[[57.375, 57.12, 58.395]]
。 -
MMDet 模型.
YOLOV3 & YOLOX: 将下面的模型拆分配置写入到 detection_rknn_static.py:
# yolov3, yolox partition_config = dict( type='rknn', # the partition policy name apply_marks=True, # should always be set to True partition_cfg=[ dict( save_file='model.onnx', # name to save the partitioned onnx start=['detector_forward:input'], # [mark_name:input, ...] end=['yolo_head:input']) # [mark_name:output, ...] ])
RetinaNet & SSD & FSAF with rknn-toolkit2, 将下面的模型拆分配置写入到 detection_rknn_static.py。使用 rknn-toolkit 的用户则不用。
# retinanet, ssd partition_config = dict( type='rknn', # the partition policy name apply_marks=True, partition_cfg=[ dict( save_file='model.onnx', start='detector_forward:input', end=['BaseDenseHead:output']) ])
-
SDK 只支持 int8 的 rknn 模型,这需要在转换模型时设置
do_quantization=True
。