转换paddleocr到瑞芯微rk3588
1 使用fastdeploy+python SDK方式移植padleocr到rk3588
padocr的模型是基于paddlepaddle框架的,因此需要先将paddlepaddle的模型转为onnx后再将onnx转为rknn模型。获得rknn模型后,可以直接借助百度的FastDeploy框架使用文字识别模型。整体思路如下:
- 步骤1:服务端环境搭建(rknn-toolkit2 1.5.0),用于转换RKNN模型。由于rknn-toolkit2-1.5.2转换paddle-ocr的模型之后,会出现推理错乱的情况,因此将onnx转rknn时,需要使用rknn-toolkit2-1.5.0版本,但可以使用rknn-toolkit2-1.5.2进行推理。
- 步骤2:边缘端环境搭建:安装rknpu2/编译FastDeploy/编译FastDeploy Python SDK
- 步骤3:使用FastDeploy Python SDK进行模型推理。
1.1 安装模型转换环境
1.1.1 服务器环境安装
下载rknn-toolkit2-1.5.0,然后根据需要安装其他依赖即可。
wget https://github.com/rockchip-linux/rknn-toolkit2/blob/v1.5.0/packages/rknn_toolkit2-1.5.0%2B1fa95b5c-cp38-cp38-linux_x86_64.whl
# numpy的版本过高是会出现 module 'numpy' has no attribute 'bool'
pip3 install numpy==1.23.1 -i https://mirror.baidu.com/pypi/simple
# 安装rknn-toolkit2-1.5.0
pip3 install --no-dependencies rknn_toolkit2-1.5.0+1fa95b5c-cp38-cp38-linux_x86_64.whl
1.1.2 板端环境rknpu2安装
参考:https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/example/pp_ocrv3.html#id3
1.1.3 板端编译FastDeploy安装
板端编译FastDeploy C++ SDK
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy
mkdir build && cd build
cmake .. \
-DENABLE_ORT_BACKEND=OFF \
-DENABLE_RKNPU2_BACKEND=ON \
-DENABLE_VISION=ON \
-DRKNN2_TARGET_SOC=RK3588 \
-DCMAKE_INSTALL_PREFIX=${PWD}/fastdeploy-0.0.0
# build if soc is RK3588
make -j8
make install
** 配置环境变量**
# 永久配置
source PathToFastDeploySDK/fastdeploy_init.sh
sudo cp PathToFastDeploySDK/fastdeploy_libs.conf /etc/ld.so.conf.d/
sudo ldconfig
** 编译FastDeploy Python SDK**
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy
# 如果您使用的是develop分支输入以下命令
git checkout develop
cd python
export ENABLE_ORT_BACKEND=ON
export ENABLE_RKNPU2_BACKEND=ON
export ENABLE_VISION=ON
export RKNN2_TARGET_SOC=RK3588
# 如果你的核心板的运行内存大于等于8G,我们建议您执行以下命令进行编译。
python3 setup.py build
python3 setup.py bdist_wheel
cd dist
pip3 install fastdeploy_python-0.0.0-cp39-cp39-linux_aarch64.whl
1.2 模型转换
1.2.1 下载paddleocr v4模型
官网地址:https://github.com/PaddlePaddle/PaddleOCR
wget https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_det_infer.tar
wget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
wget https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_rec_infer.tar
1.2.2 paddle转onnx转rknn
文字检测模型转换
# paddle模型转onnx
paddle2onnx --model_dir ./model/ch_PP-OCRv4_det_infer \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--save_file ./model/ch_PP-OCRv4_det_infer/model.onnx \
--opset_version 12 \
--enable_onnx_checker True \
--enable_dev_version True
# 固定输出尺寸
python -m paddle2onnx.optimize \
--input_model ./model/ch_PP-OCRv4_det_infer/model.onnx \
--output_model ./model/ch_PP-OCRv4_det_infer/model_fix.onnx \
--input_shape_dict "{'x':[1,3,960,960]}"
# 模型一些类型缺少“shape”,可以使用onnxruntime的工具重新推理下onnx的shape,参考:https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/example/pp_ocrv3.html#pp-ocrv3
python3 /opt/virtualenvs/feiran/lib/python3.8/site-packages/onnxruntime/tools/symbolic_shape_infer.py \
--input ./models/ocr/ch_PP-OCRv4_det_infer/model_fix.onnx \
--output ./models/ocr/ch_PP-OCRv4_det_infer/model_fix_new.onnx
# 编写脚本将onnx转为rknn,参考:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tools/rknpu2/export.py
文字方向判别模型
# paddle模型转onnx
paddle2onnx --model_dir ./model/ch_ppocr_mobile_v2.0_cls_infer \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--save_file ./model/ch_ppocr_mobile_v2.0_cls_infer/model.onnx \
--opset_version 12 \
--enable_onnx_checker True \
--enable_dev_version True
# 固定输出尺寸
python -m paddle2onnx.optimize \
--input_model ./model/ch_ppocr_mobile_v2.0_cls_infer/model.onnx \
--output_model ./model/ch_ppocr_mobile_v2.0_cls_infer/model_fix.onnx \
--input_shape_dict "{'x':[1,3,48,192]}"
# 模型一些类型缺少“shape”,可以使用onnxruntime的工具重新推理下onnx的shape,参考:https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/example/pp_ocrv3.html#pp-ocrv3
python3 /opt/virtualenvs/feiran/lib/python3.8/site-packages/onnxruntime/tools/symbolic_shape_infer.py \
--input ./models/ocr/ch_ppocr_mobile_v2.0_cls_infer/model_fix.onnx \
--output ./models/ocr/ch_ppocr_mobile_v2.0_cls_infer/model_fix_new.onnx
# 编写脚本将onnx转为rknn,参考:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tools/rknpu2/export.py
文字识别模型转换
# paddle模型转onnx
paddle2onnx --model_dir ./model/ch_PP-OCRv4_rec_infer \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--save_file ./model/ch_PP-OCRv4_rec_infer/model.onnx \
--opset_version 12 \
--enable_onnx_checker True \
--enable_dev_version True
# 固定输出尺寸
python -m paddle2onnx.optimize \
--input_model ./model/ch_PP-OCRv4_rec_infer/model.onnx \
--output_model ./model/ch_PP-OCRv4_rec_infer/model_fix.onnx \
--input_shape_dict "{'x':[1,3,48,320]}"
# 模型一些类型缺少“shape”,可以使用onnxruntime的工具重新推理下onnx的shape,参考:https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/example/pp_ocrv3.html#pp-ocrv3
python3 /opt/virtualenvs/feiran/lib/python3.8/site-packages/onnxruntime/tools/symbolic_shape_infer.py \
--input ./models/ocr/ch_PP-OCRv4_rec_infer/model_fix.onnx \
--output ./models/ocr/ch_PP-OCRv4_rec_infer/model_fix_new.onnx
# 编写脚本将onnx转为rknn,参考:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tools/rknpu2/export.py
1.3 模型推理
import os
import cv2
import fastdeploy as fd
from pathlib import Path
if __name__ == "__main__":
rec_option = fd.RuntimeOption()
rec_option.use_rknpu2()
rec_format = fd.ModelFormat.RKNN
det_option = fd.RuntimeOption()
det_option.use_rknpu2()
det_format = fd.ModelFormat.RKNN
det_model = fd.vision.ocr.DBDetector(
"../model/ocr/ch_PP-OCRv4_det_infer/model_fix.rknn",
"",
runtime_option=det_option,
model_format=det_format)
det_model.preprocessor.static_shape_infer = True
det_model.preprocessor.disable_normalize()
det_model.preprocessor.disable_permute()
rec_model = fd.vision.ocr.Recognizer(
"../model/ocr/ch_PP-OCRv4_rec_infer/model_fix.rknn",
"",
"../model/ocr/dicts/ppocr_keys_v1.txt",
runtime_option=rec_option,
model_format=rec_format)
rec_model.preprocessor.static_shape_infer = True
rec_model.preprocessor.disable_normalize()
rec_model.preprocessor.disable_permute()
ppocr_v3 = fd.vision.ocr.PPOCRv4(
det_model=det_model, cls_model=None, rec_model=rec_model)
ppocr_v3.cls_batch_size = 1
ppocr_v3.rec_batch_size = 1
for file in Path("../data/src_ocr_images/license_plate").rglob("*.png"):
im = cv2.imread(file.as_posix())
result = ppocr_v3.predict(im)
vis_im = fd.vision.vis_ppocr(im, result)
cv2.imwrite(os.path.join("../data/dst_ocr_images/license_plate", os.path.basename(file)), vis_im)
# result = rec_model.predict(im)
print(file.as_posix(), result)
1.4 问题
问题1:文字识别模型推理后解析的结果与图片中的文字不一样?
解决方法:参考https://github.com/PaddlePaddle/FastDeploy/issues/2218
“1.5.2的toolkit2转换rknn模型有问题,最后支持的版本是1.5.1b19,你可以用1.5.1b19的工具转换模型。但是这个问题还是看下吧,因为板子已经支持半自动的动态输入了,目前的静态resize输入识别率很低,估计变形太严重都丢了”。使用1.5.1b19版本的rknn导出模型。
找不到对应版本的模型,使用1.5.0可以正常推理,下载地址https://github.com/rockchip-linux/rknn-toolkit2/blob/v1.5.0/packages/rknn_toolkit2-1.5.0%2B1fa95b5c-cp38-cp38-linux_x86_64.whl。
问题2:rknn-toolkit2降低到1.5.0版本后,出现下面错误
E load_onnx: onnx.onnx_cpp2py_export.checker.ValidationError: Field 'shape' of 'type' is required but missing.
模型一些类型缺少“shape”,可以使用onnxruntime的工具重新推理下onnx的shape:
python symbolic_shape_infer.py --input ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer_old.onnx
--output ch_ppocr_mobile_v2.0_cls_infer/ch_ppocr_mobile_v2.0_cls_infer.onnx
symbolic_shape_infer.py位于onnxruntime的安装目录中/opt/virtualenvs/feiran/lib/python3.8/site-packages/onnxruntime/tools/symbolic_shape_infer.py
问题3:转换cls和rec模型时报错
E build: AttributeError: module 'numpy' has no attribute 'bool'.
降低numpy的版本:pip3 install numpy==1.23.1 -i https://mirror.baidu.com/pypi/simple
参考
- 百度FastDeploy提供的Demo:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tools/rknpu2/export.py
- 模型转换步骤:https://github.com/PaddlePaddle/FastDeploy/tree/develop/examples/vision/ocr/PP-OCR/rockchip/python
- 编译步骤:https://github.com/PaddlePaddle/FastDeploy/blob/develop/docs/cn/build_and_install/rknpu2.md
- 嵌入式AI应用开发实战指南—基于LubanCat-RK系列板卡:https://doc.embedfire.com/linux/rk356x/Ai/zh/latest/lubancat_ai/example/pp_ocrv3.html