mmdeploy/docs/zh_cn/01-how-to-build/rockchip.md

7.1 KiB
Raw Blame History

支持 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

安装

建议为项目创建一个虚拟环境。

  1. 使用 git 获取 RKNN-Toolkit2 或者 RKNN-Toolkit。以 RKNN-Toolkit2 为例:

    git clone git@github.com:rockchip-linux/rknn-toolkit2.git
    
  2. 通过 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
    
  3. 先安装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
    
  4. 使用 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

  1. 获取 rknpu2:

    git clone git@github.com:rockchip-linux/rknpu2.git
    
  2. 在 linux 系统, 下载 gcc 交叉编译器. rknpu2 的官方提供的下载链接无法使用了. 用户可以使用另一个 链接. 下载并解压完编译器, 打开终端, 设置 RKNN_TOOL_CHAINRKNPU2_DEVICE_DIRexport RKNN_TOOL_CHAIN=/path/to/gcc/usr;export RKNPU2_DEVICE_DIR=/path/to/rknpu2/runtime/RK3588

  3. 上述准备工作完成后, 运行如下指令安装:

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 被设置为 TrueRKNN 需要的输入没有被归一化过。请修改 Normalizemodel_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_valuesstd_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