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

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

心路历程:做什么事情,先不要急于否定,先做好记录。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐