0


手把手教你百度飞桨PP-YOLOE部署到瑞芯微RK3588

前言

  1. PP-YOLOE是百度飞桨团队发布的目标检测模型,PP-YOLOE是基于PP-YOLOv2的卓越的单阶段Anchor-free模型,超越了多种流行的YOLO模型。PP-YOLOE有一系列的模型,即s/m/l/x,可以通过width multiplierdepth multiplier配置。PP-YOLOE避免了使用诸如Deformable Convolution或者Matrix NMS之类的特殊算子,以使其能轻松地部署在多种多样的硬件上.
  2. RK3588是瑞芯微发布的新一代高性能旗舰Soc芯片,采用ARM架构,采用先进的8nm制程工艺,集成了四核Cortex-A76和四核Cortex-A55(共8核),以及单独的NEON协处理器,支持8K视频编解码,内部集成独立的NPU处理器,可提供高达6TOPS算力,可以满足绝大多数终端设备的边缘计算需求,提供了许多功能强大的嵌入式硬件引擎,为高端应用提供了极致的性能,同时提供了丰富的功能接口,可满足不同行业的产品定制需求。
  3. **本文着重介绍如何将百度飞桨PP-YOLOE模型部署到瑞芯微RK3588,内容包括:环境搭建、模型转换、运行例程等。另外,整个部署过程的难点在于模型转换,模型转换的总体框架如下:**

paddle模型无法直接转为瑞芯微的rknn格式,所以要先将paddle模型转换为onnx,再将onnx转rknn。

一、环境搭建

  1. 系统:Ubuntu18.04.5x64
  2. 用户:root
  3. 在部署过程中,不同步骤下的操作要求的环境会有所差异,甚至会有一些软件包版本冲突的问题,所以这边使用conda来进行环境管理。

1、Anaconda3安装

1.1、下载

  1. 清华镜像官网下载地址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
  2. 此处下载Anaconda3-2022.10-Linux-x86_64.sh

1.2、安装

  1. 使用bash命令安装:
  1. # bash Anaconda3-2022.10-Linux-x86_64.sh
  1. 然后一路输入yes回车,默认在用户主目录下创建一个名为anaconda3的文件夹作为安装地址,此处用的是root账号,所以安装在/root/anaconda3目录下。
  2. Anaconda安装完成以后出现的个提示解读:
  3. 1For changes to take effect, close and re-open your current shell.,翻译过来就是:关闭当前命令行,并重新打开,刚刚安装和初始化Anaconda设置才可以生效,重新打开一个命令行后直接就进入了condabase环境。
  4. 2If you'd prefer that conda's base environment not be activated on startup, set the auto_activate_base parameter to false: ,翻译过来就是:如果您希望 conda 的基础环境在启动时不被激活,请将 auto_activate_base 参数设置为 false,命令如下:
  1. # conda config --set auto_activate_base false
  1. 当然这一条命令执行完毕后,想要再次进入condabase环境,只需要使用对应的conda指令即可,如下:
  1. # conda activate base
  1. 到此,Anaconda3安装完毕。

2、paddle模型导出环境

  1. PP-YOLOE是百度飞桨paddle的目标检测模型,paddle目标检测模型的导出依赖于PaddleDetection,所以要安装PaddleDetection工具包。之所以要单独搭建此环境,是因为PaddleDetection工具依赖的onnxnumpy等软件包版本与瑞星微RK3588rknn-toolkit2不兼容。
  2. PaddleDetection版本:2.5.0
  3. rknn-toolkit2版本:1.3.0

2.1、创建环境

  1. 选择python3.8.13包进行创建环境,命令如下:
  1. # conda create --name paddleExport python==3.8.13

2.2、进入环境

  1. 命令如下:
  1. # conda activate paddleExport
  1. 注:如无特别说明,本章节下文所有操作均在所创建的环境中进行。

2.3、paddle安装

  1. 在安装PaddleDetection工具之前先安装paddle包,使用清华大学开源软件镜像站安装paddle包,地址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
  2. 安装之前可以先查看下各个版本依赖库:
  1. # conda search --full-name paddlepaddle --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ --info
  1. 这里选择2.3.2cpu版本进行安装:
  1. # conda install paddlepaddle=2.3.2 --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
  1. 验证安装:
  2. 输入python回车,进入python解释器,输入import paddle ,再输入 paddle.utils.run_check()如果出现PaddlePaddle is installed successfully!,说明已成功安装。
  1. (paddleExport) root@micro:~# python
  2. Python 3.8.13 (default, Oct 21 2022, 23:50:54)
  3. [GCC 11.2.0] :: Anaconda, Inc. on linux
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> import paddle
  6. >>> paddle.utils.run_check()
  7. Running verify PaddlePaddle program ...
  8. PaddlePaddle works well on 1 CPU.
  9. W1102 17:33:39.837543 4740 fuse_all_reduce_op_pass.cc:76] Find all_reduce operators: 2. To make the speed faster, some all_reduce ops are fused during training, after fusion, the number of all_reduce ops is 2.
  10. PaddlePaddle works well on 2 CPUs.
  11. PaddlePaddle is installed successfully! Let's start deep learning with PaddlePaddle now.
  12. >>>

2.4、PaddleDetection安装

  1. 安装文档参考:https://toscode.gitee.com/paddlepaddle/PaddleDetection/blob/release/2.5/docs/tutorials/INSTALL_cn.md
  2. 创建工作目录并切换到工作目录后下载源码:
  1. # mkdir -p /home/tools/baidu/paddle
  2. # cd /home/tools/baidu/paddle
  3. # git clone https://github.com/PaddlePaddle/PaddleDetection
  1. 安装PaddleDetection依赖库:
  1. # cd /home/tools/baidu/paddle/PaddleDetection
  2. # pip install -r requirements.txt
  1. 编译安装PaddleDetection
  1. # python setup.py install
  1. 验证安装:
  1. # python ppdet/modeling/tests/test_architectures.py
  2. .......
  3. ----------------------------------------------------------------------
  4. Ran 7 tests in 5.532s
  5. OK
  1. 看见以上输出提示,说明安装成功。

2.5、解决相关依赖问题

  1. 到此,paddle模型导出环境基本搭建完成,但是还要解决一下包依赖的问题。
  2. 安装pip依赖查看工具:
  1. # pip install pipdeptree
  1. 查看依赖关系:
  1. # pipdeptree -p paddlepaddle
  2. Warning!!! Possibly conflicting dependencies found:
  3. * paddlepaddle==2.3.2
  4. - paddle-bfloat [required: ==0.1.7, installed: ?]
  5. ------------------------------------------------------------------------
  6. paddlepaddle==2.3.2
  7. - astor [required: Any, installed: 0.8.1]
  8. - decorator [required: Any, installed: 5.1.1]
  9. - numpy [required: >=1.13, installed: 1.23.3]
  10. - opt-einsum [required: ==3.3.0, installed: 3.3.0]
  11. - numpy [required: >=1.7, installed: 1.23.3]
  12. - paddle-bfloat [required: ==0.1.7, installed: ?]
  13. - Pillow [required: Any, installed: 9.2.0]
  14. - protobuf [required: >=3.1.0,<=3.20.0, installed: 3.19.1]
  15. - requests [required: >=2.20.0, installed: 2.28.1]
  16. - certifi [required: >=2017.4.17, installed: 2022.9.24]
  17. - charset-normalizer [required: >=2,<3, installed: 2.0.4]
  18. - idna [required: >=2.5,<4, installed: 3.4]
  19. - urllib3 [required: >=1.21.1,<1.27, installed: 1.26.12]
  20. - six [required: Any, installed: 1.16.0]
  1. 从上面打印信息得知一些依赖包问题,进行修复:
  1. # pip install paddle-bfloat==0.1.7

3、paddle转onnx转rknn环境

  1. paddleonnxonnxrknn两个环境可以分开搭建,也可以搭建在一起。这里选择搭建在一起,方便onnx版本对齐,避免转换过程中onnx版本不兼容造成的失败。

3.1、创建环境

  1. 选择python3.8.13包进行创建环境
  1. # conda create --name paddle2rknn libprotobuf python==3.8.13

3.2、进入环境

  1. 命令如下:
  1. # conda activate paddle2rknn
  1. 注:如无特别说明,本章节下文所有操作均在所创建的环境中进行。

3.3、RKNN-Toolkit2工具安装

  1. RKNN-Toolkit2是为用户提供在 PCRockchip NPU 平台上进行模型转换、推理和性能评估的开发套件,RKNN-Toolkit2适用于RK3566RK3568RK3588/RK3588SRV1103RV1106等型号的芯片。RKNN-Toolkit2的开源地址https://github.com/rockchip-linux/rknn-toolkit2,从中我们可以获取它的百度网盘下载地址。
  2. 百度网盘地址:https://eyun.baidu.com/s/3eTDMk6Y#sharelink/path=%2F
  3. 密码:rknn
  4. 这边拿到的RK3588开发板上rknpuAPI及驱动版本是1.3.0,所以这里选择RK_NPU_SDK_1.3.0release版本进行下载。下载解压后这里RKNN-Toolkit2的根目录为/home/tools/rockchip/RK_NPU_SDK_1.3.0/rknn-toolkit2-1.3.0。目前提供两种方式安装RKNN-Toolkit2:一是通过Python包安装与管理工具pip进行安装;二是运行带完整RKNN-Toolkit2工具包的docker镜像。本文采用第一种方式。
  5. 切换到RKNN-Toolkit2根目录:
  1. # cd /home/tools/rockchip/RK_NPU_SDK_1.3.0/rknn-toolkit2-1.3.0
  1. 安装依赖,因为我们环境的python版本是3.8.13,所以这里执行:
  1. # pip3 install -r doc/requirements_cp38-1.3.0.txt
  1. 安装RKNN-Toolkit2
  1. # pip3 install packages/rknn_toolkit2-1.3.0_11912b58-cp38-cp38-linux_x86_64.whl

3.3、paddle2onnx工具安装

  1. paddle2onnx支持将PaddlePaddle模型格式转化到ONNX模型格式。paddle2onnx也依赖于paddle包,在新的环境中需要重新安装paddle包,paddle包的安装请参考前面章节。
  2. 查看paddle2onnx可安装版本:
  1. # pip3 index versions paddle2onnx
  2. WARNING: pip index is currently an experimental command. It may be removed/changed in a future release without prior warning.
  3. paddle2onnx (1.0.1)
  4. Available versions: 1.0.1, 1.0.0, 0.9.8, 0.9.7, 0.9.6, 0.9.5, 0.9.4, 0.9.2, 0.9.1, 0.9.0, 0.8.2, 0.8.1, 0.8, 0.7, 0.6, 0.5.1, 0.5, 0.4, 0.3.2, 0.3.1
  1. 默认安装的就是最新版本,这里指定0.9.8版本,否则会因为onnx版本版本太高,与RKNN-Toolkit2不兼容:
  1. # pip install paddle2onnx==0.9.8

3.4、解决相关依赖问题

  1. 到此,paddleonnxrknn环境基本搭建完成,但是还要解决一下包依赖的问题。
  2. 安装pip依赖查看工具:
  1. # pip install pipdeptree
  1. 查看依赖关系:
  1. # pipdeptree -p paddle2onnx
  2. Warning!!! Possibly conflicting dependencies found:
  3. * paddlepaddle==2.3.2
  4. - paddle-bfloat [required: ==0.1.7, installed: ?]
  5. * rknn-toolkit2==1.3.0-11912b58
  6. - numpy [required: ==1.17.3, installed: 1.23.3]
  7. - protobuf [required: ==3.12.0, installed: 3.19.1]
  8. - requests [required: ==2.21.0, installed: 2.28.1]
  9. ------------------------------------------------------------------------
  10. paddle2onnx==0.9.8
  1. 从上面打印信息得知一些依赖包版本不对,进行修复:
  1. # pip install paddle-bfloat==0.1.7
  2. # pip install numpy==1.17.3
  3. # pip install protobuf==3.12.0
  4. # pip install requests==2.21.0

二、模型转换

  1. paddle目前有四大类模型:目标检测、分类、OCR以及分割,这里选择的ppyoloe是目标检测的一种。

1、模型导出

  1. 参考文档:
  2. https://gitee.com/paddlepaddle/PaddleDetection/tree/develop
  3. https://gitee.com/paddlepaddle/PaddleDetection/blob/develop/deploy/EXPORT_MODEL.md
  4. 切换到前面搭建的模型导出环境并进入PaddleDetection工作目录:
  1. # conda activate paddleExport
  2. # cd /home/tools/baidu/paddle/PaddleDetection
  1. 模型导出可以在线下载模型进行导出:
  1. # python tools/export_model.py \
  2. -c configs/ppyoloe/ppyoloe_crn_s_300e_coco.yml \
  3. --output_dir=/home/tools/baidu/paddle/model/ppyoloe \
  4. -o weights=https://paddledet.bj.bcebos.com/models/ppyoloe_crn_s_300e_coco.pdparams \
  5. use_gpu=False exclude_nms=True
  1. 也可以将原始模型文件下载到本地进行导出:
  1. # python tools/export_model.py \
  2. -c configs/ppyoloe/ppyoloe_crn_s_300e_coco.yml \
  3. --output_dir=/home/tools/baidu/paddle/model/ppyoloe \
  4. -o weights=/home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco.pdparams \
  5. use_gpu=False exclude_nms=True

参数说明:

-c 指定配置文件

--output_dir 模型保存路径

-o 输出相关配置,其中:

  1. weights:训练得到的模型,扩展名为pdparams
  2. use_gpu:是否使用gpu
  3. exclude_nms:裁剪掉模型中后处理的nms部分

当前环境没有gpu,所以设置use_gpu=False;

rknn目前不支持NonZero算子,所以要裁剪掉模型中后处理的nms部分,设置 exclude_nms=True

预测模型会导出到/home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco目录下,分别为infer_cfg.yml, model.pdiparams, model.pdiparams.info, model.pdmodel。

2、paddle转onnx

  1. 参考:https://toscode.gitee.com/paddlepaddle/Paddle2ONNX
  2. 切换到paddleonnxrknn环境:
  1. # conda activate paddle2rknn
  1. paddleonnx命令:
  1. # paddle2onnx --model_dir /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/ \
  2. --model_filename model.pdmodel \
  3. --params_filename model.pdiparams \
  4. --opset_version 12 \
  5. --save_file /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx \
  6. --enable_onnx_checker True

参数说明:

--model_dir:配置包含 Paddle 模型的目录路径

--model_filename:配置位于

  1. --model_dir

下存储网络结构的文件名

--params_filename:配置位于

  1. --model_dir

下存储模型参数的文件名称

--opset_version:配置转换为 ONNX 的 OpSet 版本,目前支持 7~16 等多个版本,默认为 9,这里选择12,为了与rknn-toolkit2兼容。

--save_file:指定转换后的模型保存目录路径

--enable_onnx_checker:配置是否检查导出为 ONNX 模型的正确性, 建议打开此开关, 默认为 False

  1. 转换完的onnx文件位于:/home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx,但是这个模型没法拿去转换成rknn,原因是rknn需要固定输入shape,所以我们在转换的时候还需要使用input_shape_dict来设置固定输入shape。那如何确定输入shape的参数呢?从以下网址:https://toscode.gitee.com/paddlepaddle/PaddleDetection/blob/release/2.5/deploy/EXPORT_MODEL.md

我们可以得知,paddle目标检测模型有1~3个输入,那又如何确定具体要填什么样的值?我们可以使用以下python代码,先把之前转的onnx模型的输入输出打印出来:

  1. import onnx
  2. import numpy as np
  3. import logging
  4. logging.basicConfig(level=logging.INFO)
  5. def onnx_datatype_to_npType(data_type):
  6. if data_type == 1:
  7. return np.float32
  8. else:
  9. raise TypeError("don't support data type")
  10. def parser_initializer(initializer):
  11. name = initializer.name
  12. logging.info(f"initializer name: {name}")
  13. dims = initializer.dims
  14. shape = [x for x in dims]
  15. logging.info(f"initializer with shape:{shape}")
  16. dtype = initializer.data_type
  17. logging.info(f"initializer with type: {onnx_datatype_to_npType(dtype)} ")
  18. # print tenth buffer
  19. weights = np.frombuffer(initializer.raw_data, dtype=onnx_datatype_to_npType(dtype))
  20. logging.info(f"initializer first 10 wights:{weights[:10]}")
  21. def parser_tensor(tensor, use='normal'):
  22. name = tensor.name
  23. logging.info(f"{use} tensor name: {name}")
  24. data_type = tensor.type.tensor_type.elem_type
  25. logging.info(f"{use} tensor data type: {data_type}")
  26. dims = tensor.type.tensor_type.shape.dim
  27. shape = []
  28. for i, dim in enumerate(dims):
  29. shape.append(dim.dim_value)
  30. logging.info(f"{use} tensor with shape:{shape} ")
  31. def parser_node(node):
  32. def attri_value(attri):
  33. if attri.type == 1:
  34. return attri.i
  35. elif attri.type == 7:
  36. return list(attri.ints)
  37. name = node.name
  38. logging.info(f"node name:{name}")
  39. opType = node.op_type
  40. logging.info(f"node op type:{opType}")
  41. inputs = list(node.input)
  42. logging.info(f"node with {len(inputs)} inputs:{inputs}")
  43. outputs = list(node.output)
  44. logging.info(f"node with {len(outputs)} outputs:{outputs}")
  45. attributes = node.attribute
  46. for attri in attributes:
  47. name = attri.name
  48. value = attri_value(attri)
  49. logging.info(f"{name} with value:{value}")
  50. def parser_info(onnx_model):
  51. ir_version = onnx_model.ir_version
  52. producer_name = onnx_model.producer_name
  53. producer_version = onnx_model.producer_version
  54. for info in [ir_version, producer_name, producer_version]:
  55. logging.info("onnx model with info:{}".format(info))
  56. def parser_inputs(onnx_graph):
  57. inputs = onnx_graph.input
  58. for input in inputs:
  59. parser_tensor(input, 'input')
  60. def parser_outputs(onnx_graph):
  61. outputs = onnx_graph.output
  62. for output in outputs:
  63. parser_tensor(output, 'output')
  64. def parser_graph_initializers(onnx_graph):
  65. initializers = onnx_graph.initializer
  66. for initializer in initializers:
  67. parser_initializer(initializer)
  68. def parser_graph_nodes(onnx_graph):
  69. nodes = onnx_graph.node
  70. for node in nodes:
  71. parser_node(node)
  72. t = 1
  73. def onnx_parser():
  74. model_path = '/home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx'
  75. model = onnx.load(model_path)
  76. # 0.
  77. parser_info(model)
  78. graph = model.graph
  79. # 1.
  80. parser_inputs(graph)
  81. # 2.
  82. parser_outputs(graph)
  83. # 3.
  84. #parser_graph_initializers(graph)
  85. # 4.
  86. #parser_graph_nodes(graph)
  87. if __name__ == '__main__':
  88. onnx_parser()

代码保存为printOnnx.py,然后执行:

  1. # python printOnnx.py
  2. INFO:root:onnx model with info:7
  3. INFO:root:onnx model with info:PaddlePaddle
  4. INFO:root:onnx model with info:
  5. INFO:root:input tensor name: image
  6. INFO:root:input tensor data type: 1
  7. INFO:root:input tensor with shape:[-1, 3, 640, 640]
  8. INFO:root:input tensor name: scale_factor
  9. INFO:root:input tensor data type: 1
  10. INFO:root:input tensor with shape:[-1, 2]
  11. INFO:root:output tensor name: tmp_17
  12. INFO:root:output tensor data type: 1
  13. INFO:root:output tensor with shape:[-1, 8400, 4]
  14. INFO:root:output tensor name: concat_14.tmp_0
  15. INFO:root:output tensor data type: 1
  16. INFO:root:output tensor with shape:[-1, 80, 8400]

从打印信息我们可以看到ppyoloe有两个输入shape,其中batch为-1表示不确定的,其它如图像大小等参数可以从中得知。使用以下新命令转出固定输入shape的onnx模型:

  1. # paddle2onnx --model_dir /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/ \
  2. --model_filename model.pdmodel \
  3. --params_filename model.pdiparams \
  4. --opset_version 12 \
  5. --save_file /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx \
  6. --input_shape_dict="{'image':[1,3,640,640], 'scale_factor':[1,2]}" \
  7. --enable_onnx_checker True

如果是高版本的paddle2onnx(貌似 > 0.9.8),则需使用以下命令:

  1. # paddle2onnx --model_dir /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/ \
  2. --model_filename model.pdmodel \
  3. --params_filename model.pdiparams \
  4. --opset_version 12 \
  5. --save_file /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx \
  6. --enable_onnx_checker True
  7. # python -m paddle2onnx.optimize \
  8. --input_model /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx \
  9. --output_model /home/tools/baidu/paddle/model/ppyoloe/ppyoloe_crn_s_300e_coco/model.onnx \
  10. --input_shape_dict "{'image':[1,3,640,640], 'scale_factor':[1,2]}"

转换完后,可以看到输入输出shape都固定下来了:

  1. # python printOnnx.py
  2. INFO:root:onnx model with info:7
  3. INFO:root:onnx model with info:PaddlePaddle
  4. INFO:root:onnx model with info:
  5. INFO:root:input tensor name: image
  6. INFO:root:input tensor data type: 1
  7. INFO:root:input tensor with shape:[1, 3, 640, 640]
  8. INFO:root:input tensor name: scale_factor
  9. INFO:root:input tensor data type: 1
  10. INFO:root:input tensor with shape:[1, 2]
  11. INFO:root:output tensor name: tmp_17
  12. INFO:root:output tensor data type: 1
  13. INFO:root:output tensor with shape:[1, 8400, 4]
  14. INFO:root:output tensor name: concat_14.tmp_0
  15. INFO:root:output tensor data type: 1
  16. INFO:root:output tensor with shape:[1, 80, 8400]

3、onnx转rknn

  1. 在前面下载RKNN-Toolkit2里有rknpu2_1.3.0.tar.gz文件,解压后参考RK_NPU_SDK_1.3.0/rknpu2_1.3.0/examples/rknn_yolov5_demo/convert_rknn_demo/yolov5/onnx2rknn.py编写ppyoloeonnxrknn的代码:
  1. # coding=gbk
  2. import cv2
  3. import numpy as np
  4. from rknn.api import RKNN
  5. import os
  6. ONNX_MODEL = 'ppyoloe_crn_s_300e_coco/model.onnx'
  7. RKNN_MODEL = 'ppyoloe_crn_s_300e_coco/model.rknn'
  8. if __name__ == '__main__':
  9. NEED_BUILD_MODEL = True
  10. # NEED_BUILD_MODEL = False
  11. #生成scale_factor.npy
  12. arr = np.array([1.0, 1.0])
  13. np.save("scale_factor.npy", arr)
  14. # Create RKNN object
  15. rknn = RKNN(verbose=True)
  16. if NEED_BUILD_MODEL:
  17. DATASET = './dataset.txt'
  18. #mean_values和std_values查看相应的infer_cfg.yml文件
  19. #注意:infer_cfg.yml下is_scale:值为true,所以values值要除以scale[1.0/255],即:将values*255得到的值填入下面代码
  20. #rknn默认读图方式是RGB,如果这里训练时是使用BGR,则量化时需要RGB转BGR
  21. #rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 57.12, 57.375]], target_platform="rk3588")
  22. rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 57.12, 57.375]], target_platform="rk3588", quant_img_RGB2BGR=True)
  23. # Load model
  24. print('--> Loading model')
  25. #ret = rknn.load_onnx(model=ONNX_MODEL)
  26. ret = rknn.load_onnx(model=ONNX_MODEL, input_size_list=[[1,3,640,640],[1,2]])
  27. if ret != 0:
  28. print('load model failed!')
  29. exit(ret)
  30. print('done')
  31. # Build model
  32. print('--> Building model')
  33. ret = rknn.build(do_quantization=True, dataset=DATASET) #量化
  34. #ret = rknn.build(do_quantization=False, dataset=DATASET) #不量化
  35. if ret != 0:
  36. print('build model failed.')
  37. exit(ret)
  38. print('done')
  39. # Export rknn model
  40. print('--> Export RKNN model: {}'.format(RKNN_MODEL))
  41. ret = rknn.export_rknn(RKNN_MODEL)
  42. if ret != 0:
  43. print('Export rknn model failed.')
  44. exit(ret)
  45. print('done')
  46. else:
  47. ret = rknn.load_rknn(RKNN_MODEL)
  48. rknn.release()

这里针对量化的时候,有几个地方需要注意:

(1)、rknn默认读图方式是RGB,如果这里训练时是使用BGR,则量化时需要RGB转BGR,在rknn.config时需要配置quant_img_RGB2BGR=True,ppyoloe是使用什么样的格式去训练的,这里还没有去验证。

(2)、从前面paddle转onnx时,我们得知ppyoloe有两个输入shape,所以在准备量化校正数据集时,我们也需要提供两个输入shape数据,即dataset.txt每行有两个文件,用空格隔开:

  1. # cat dataset.txt
  2. bus.jpg scale_factor.npy
  3. 1.jpg scale_factor.npy

第一个文件为图片文件

第二个文件为输入名称是scale_factor的shape信息,npy格式,表示输入图像大小比真实图像大小,这边都设置为1.0,在以上代码直接生成该文件。

  1. 运行以上代码,实现onnxrknn
  1. # python3 onnx2rknn.py
  1. 可能会碰到的错误:
  1. E build: Catch exception when building RKNN model!
  2. E build: Traceback (most recent call last):
  3. E build: File "rknn/api/rknn_base.py", line 1680, in rknn.api.rknn_base.RKNNBase.build
  4. E build: File "rknn/api/rknn_base.py", line 363, in rknn.api.rknn_base.RKNNBase._generate_rknn
  5. E build: File "rknn/api/rknn_base.py", line 270, in rknn.api.rknn_base.RKNNBase._build_rknn
  6. E build: ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /root/anaconda3/envs/paddle2rknn/lib/python3.8/site-packages/rknn/api/lib/linux-x86_64/cp38/librknnc_v2.so)
  7. build model failed.

原因是需要2.29版本的GLIBC,解决方法参考:https://www.cnblogs.com/chenyirong/p/16342370.html

然后重新转换,不出意外的话,在代码设置的路径下就会生成我们想要的rknn模型文件,把它部署到开发板上就可以愉快的玩耍了~

三、运行例程

  1. 目前手上没有开发板,等有了再补上!

本文转载自: https://blog.csdn.net/buyishengun/article/details/127653529
版权归原作者 布衣神棍 所有, 如有侵权,请联系我们删除。

“手把手教你百度飞桨PP-YOLOE部署到瑞芯微RK3588”的评论:

还没有评论