PaddleOCR v4模型转onnx踩坑记
1、训练得到的模型格式及推理格式
在训练的时候,我的paddlepaddle用的版本是3.2.0,用的是pp-ocrv4_mobile_rec的预训练模型,
训练命令是
python tools/train.py -c configs/rec/PP-OCRv4/PP-OCRv4_mobile_rec.yml
训练出来得模型是这种格式
./output/rec_ppocr_v4/best_model
├── model.pdopt
├── model.pdparams
转成推理模型的时候,是参照官方的命令
PaddleOCR/docs/version3.x/module_usage/text_recognition.md at main · PaddlePaddle/PaddleOCR · GitHub
python3 tools/export_model.py -c configs/rec/PP-OCRv5/PP-OCRv5_server_rec.yml -o \
Global.pretrained_model=output/xxx/xxx.pdparams \
Global.save_inference_dir="./PP-OCRv5_server_rec_infer/"
得出来的模型结构是
./PP-OCRv4_mobile_rec_infer/
├── inference.json
├── inference.pdiparams
├── inference.yml
这种推理模型,在paddlepaddle的环境下是可以正常推理的
2、所遇到的困境1(model.pdparams转inference.pdmodel和inference.pdiparams)
但是这种推理模型,是不能够使用paddle2onnx工具转成onnx模型的
要使用paddle2onnx工具转成onnx模型,得是下面这种推理结构
./PP-OCRv4_mobile_rec_old_infer/
├── inference.pdmodel
├── inference.pdiparams
├── inference.yaml
├── inference.pdiparams.info
要得到.pdmodel和.pdiparams的推理格式,得用paddlepaddle==2.4.2的版本,但是现在所有的镜像上好像都没有了paddlepaddle==2.4.2的版本

幸运的是,我搜到了另一个博客
https://blog.csdn.net/weixin_27219587/article/details/159817838

这个博主整理了一个对照表,我先在我原先的paddlepaddle==3.2.0的版本上测试,没有成功;我想新建个conda环境,尝试安装一下paddlepaddle==3.0.0b2的版本
#新建环境
conda create --name paddleonnx2 python==3.9.12
#安装paddlepaddle==3.0.0b2
pip install paddlepaddle==3.0.0b2 -i https://pypi.tuna.tsinghua.edu.cn/simple
#安装PaddleOCR包中的依赖项
pip install -r requirements.txt
具体的安装包如下:
Package Version
---------------------- -----------
albucore 0.0.24
albumentations 2.0.8
annotated-types 0.7.0
anyio 4.12.1
astor 0.8.1
certifi 2026.5.20
charset-normalizer 3.4.7
colorama 0.4.6
Cython 3.2.5
decorator 5.3.1
eval_type_backport 0.4.0
exceptiongroup 1.3.1
h11 0.16.0
httpcore 1.0.9
httpx 0.28.1
idna 3.18
ImageIO 2.37.2
lazy-loader 0.5
lmdb 2.2.1
networkx 3.2.1
numpy 2.0.2
opencv-contrib-python 4.13.0.92
opencv-python 4.13.0.92
opencv-python-headless 4.13.0.92
opt-einsum 3.3.0
packaging 26.2
paddlepaddle 3.0.0b2
pillow 11.3.0
pip 25.2
protobuf 6.33.6
pyclipper 1.3.0.post6
pydantic 2.13.4
pydantic_core 2.46.4
PyYAML 6.0.3
RapidFuzz 3.13.0
requests 2.32.5
scikit-image 0.24.0
scipy 1.13.1
setuptools 80.9.0
shapely 2.0.7
simsimd 6.5.16
stringzilla 4.6.1
tifffile 2024.8.30
tqdm 4.68.2
typing_extensions 4.15.0
typing-inspection 0.4.2
urllib3 2.6.3
wheel 0.45.1
使用上面博主这个命令
# 强制使用传统IR格式导出(兼容性最佳)
python tools/export_model.py \
-c configs/rec/PP-OCRv4/en_PP-OCRv4_mobile_rec.yml \
-o Global.export_with_pir=null \
Global.checkpoints="output/rec_ppocr_v4/best" \
Global.save_inference_dir="./output"
再尝试转换,成功了


-----
备注:
(上面是成功的状态,后来我再次复现的时候,出现了
(pooldinfer2) C:\Users\Modelcode\PaddleOCR>python tools/export_model.py -c configs/rec/PP-OCRv4/PP-OCRv4_mobile_rec.yml -o Global.export_with_pir=null Global.checkpoints="output/rec_ppocr_v40505/best_model/model.pdparams" Global.save_inference_dir="./output/rec_ppocrv40616test_oldinference"
信息: 用提供的模式无法找到文件。
C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\utils\cpp_extension\extension_utils.py:686: UserWarning: No ccache found. Please be aware that recompiling all source files may be required. You can download and install ccache from: https://github.com/ccache/ccache/blob/master/doc/INSTALL.md
warnings.warn(warning_message)
Skipping import of the encryption module.
[2026/06/16 16:44:21] ppocr INFO: resume from output/rec_ppocr_v40505/best_model/model
[2026/06/16 16:44:21] ppocr INFO: Export inference config file to ./output/rec_ppocrv40616test_oldinference\inference.yml
Skipping import of the encryption module
Traceback (most recent call last):
File "C:\Users\Modelcode\PaddleOCR\tools\export_model.py", line 37, in <module>
main()
File "C:\Users\Modelcode\PaddleOCR\tools\export_model.py", line 33, in main
export(config)
File "C:\Users\Modelcode\PaddleOCR\ppocr\utils\export_model.py", line 560, in export
export_single_model(
File "C:\Users\Modelcode\PaddleOCR\ppocr\utils\export_model.py", line 396, in export_single_model
paddle.jit.save(model, save_path)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\decorator\__init__.py", line 247, in fun
return caller(func, *(extras + args), **kw)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\base\wrapped_decorator.py", line 40, in __impl__
return wrapped_func(*args, **kwargs)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\jit\api.py", line 895, in wrapper
func(layer, path, input_spec, **configs)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\decorator\__init__.py", line 247, in fun
return caller(func, *(extras + args), **kw)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\base\wrapped_decorator.py", line 40, in __impl__
return wrapped_func(*args, **kwargs)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\base\dygraph\base.py", line 101, in __impl__
return func(*args, **kwargs)
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\jit\api.py", line 1209, in save
static_func.concrete_program_specify_input_spec(
File "C:\Users\miniforge3\envs\pooldinfer2\lib\site-packages\paddle\jit\dy2static\program_translator.py", line 1059, in concrete_program_specify_input_spec
raise ValueError(
ValueError: No valid transformed program for function: forward(x,data), input_spec: None.
Please specific `input_spec` in `@paddle.jit.to_static` or feed input tensor to call the decorated function at once.
后来检查到是我修改了./ppocr/utils/export_model.py 中的代码
#if paddle_version >= version.parse(
# "3.0.0b2"
# ) or paddle_version == version.parse("0.0.0"):
# model.forward.rollback()
# with paddle.pir_utils.OldIrGuard():
# model = dynamic_to_static(model, arch_config, logger, input_shape)
# paddle.jit.save(model, save_path)
#if config["Global"].get("export_with_pir", True):
# assert (
# paddle_version >= version.parse("3.0.0b2")
# or paddle_version == version.parse("0.0.0")
# ) and os.environ.get("FLAGS_enable_pir_api", None) not in ["0", "False"]
# paddle.jit.save(model, save_path)
#else:
# if paddle_version >= version.parse(
# "3.0.0b2"
# ) or paddle_version == version.parse("0.0.0"):
# model.forward.rollback()
# with paddle.pir_utils.OldIrGuard():
# model = dynamic_to_static(model, arch_config, logger, input_shape)
# paddle.jit.save(model, save_path)
# else:
# paddle.jit.save(model, save_path)
可能是以为第一次没转换成功, 后来尝试各种方案的时候,我把上面的代码给注释掉了,导致再次复现的时候出现了上面的问题)
-----------
但是测试的时候,乱码

上面这个可能是我测试的命令不对。
正确的命令是
paddleocr text_recognition -i ./data/test/platesf --model_name PP-OCRv4_mobile_rec
我切换到paddlepaddle-gpu==3.2.0的环境,用上面这个旧的推理格式,测试成功了

用新的推理格式

也推理成功了

3、所遇到的困境2(inference.pdmodel和inference.pdiparams转onnx)
在上面这个环境中,我安装paddle2onnx工具,版本是2.1.0,进行onnx模型的转换,转换命令是
paddle2onnx --model_dir ./output/rec_ppocr_v4_oldinference --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file ./inference/rec_ppocr_v4_onnx/rec.onnx --opset_version 11 --enable_onnx_checker True
最后转换错误,报错
ImportError: DLL load failed while importing paddle2onnx_cpp2py_export: 找不指定的程序
这个时候,我又搜到了另外一个博主的博客
https://blog.csdn.net/weixin_46028455/article/details/159731735
于是我想着既然有inference.pdmodel和inference.pdiparams,跟paddlepaddle环境没关系了,再新建一个环境好了。
#新建环境
conda create --name paddleonnx3 python==3.8
#安装特定 nightly 版 paddlepaddle(CPU)
pip install paddlepaddle==3.0.0.dev20250426 -i https://www.paddlepaddle.org.cn/packages/nightly/cpu/ --pre
#安装 paddle2onnx
pip install paddle2onnx
再安装上缺少的相关依赖,具体的安装包如下:
Package Version
----------------- -----------------
anyio 4.5.2
astor 0.8.1
certifi 2026.4.22
coloredlogs 15.0.1
decorator 5.2.1
exceptiongroup 1.3.1
flatbuffers 25.12.19
h11 0.16.0
httpcore 1.0.9
httpx 0.28.1
humanfriendly 10.0
idna 3.13
ml-dtypes 0.2.0
mpmath 1.3.0
networkx 3.1
numpy 1.24.4
onnx 1.17.0
onnx_graphsurgeon 0.6.1
onnxoptimizer 0.3.13
onnxruntime 1.19.2
opt-einsum 3.3.0
packaging 26.2
paddle2onnx 2.1.0
paddlepaddle 3.0.0.dev20250426
pillow 10.4.0
pip 24.3.1
polygraphy 0.50.3
protobuf 5.29.4
pyreadline3 3.5.6
setuptools 75.3.0
sniffio 1.3.1
sympy 1.13.3
typing_extensions 4.13.2
wheel 0.45.1
转换成功了

但是最后onnx有问题,推理也是乱码
上面这个测试也不对,可能onnx模型在paddle环境下测试,本身就不太合理。
我在github上,找到了一个博主,写的测试Paddle中onnx模型的程序
https://github.com/hpc203/PaddleOCR-v3-onnxrun-cpp-py/tree/main

把我的模型和字典切换过去,改造一下相关代码,也测试成功了

心路历程:做什么事情,先不要急于否定,先做好记录。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)