菜单

C++ 推理

相关源文件

C++ 推理系统为在生产环境中部署 PaddleOCR 模型提供了高性能的部署能力。与 Python 实现相比,此实现性能更优,并支持 PP-OCRv5、PP-StructureV3 以及文档理解任务等全方位的 OCR 流程。

C++ 推理是 PaddleOCR 生态系统中一项关键的部署选项,介于开发接口和生产服务器部署之间。

1. 概述

1.1 系统架构

C++ 推理系统采用模块化架构,以 ocr()structure() 函数为两个主要入口点,位于 deploy/cpp_infer/src/main.cpp83-200 该系统通过专用的 C++ 类支持所有三个主要的 PaddleOCR 流程。

C++ 推理系统组件

来源: deploy/cpp_infer/src/main.cpp83-200 deploy/cpp_infer/include/paddleocr.h21-50 deploy/cpp_infer/include/paddlestructure.h21-44

1.2 支持的 OCR 流程

C++ 实现支持所有主要的 PaddleOCR 流程

管道C++ 类支持的操作
PP-OCRv5PPOCR文本检测、识别、分类
PP-StructureV3PaddleStructure布局分析、表格识别
文档理解PaddleStructure + PPOCR组合结构+OCR分析

1.3 性能优化

该系统提供多种优化策略

  • CPU:通过 FLAGS_cpu_threads 实现多线程,通过 FLAGS_enable_mkldnn 实现 MKLDNN 加速
  • GPU:通过 FLAGS_use_gpu 实现 CUDA 加速,通过 FLAGS_use_tensorrt 实现 TensorRT 优化
  • 精度:通过 FLAGS_precision 支持 FP32、FP16、INT8 精度模式

来源: deploy/cpp_infer/src/ocr_det.cpp47-78 deploy/cpp_infer/src/ocr_rec.cpp163-193

2. 环境设置

2.1 先决条件

要使用 C++ 推理功能,您需要以下组件

  • C++ 编译器(Linux 上为 GCC,Windows 上为 Visual Studio)
  • 用于构建项目的 CMake 3.0+
  • CUDA 和 cuDNN(可选,用于 GPU 加速)
  • TensorRT(可选,用于进一步的 GPU 加速)

2.2 构建 OpenCV

PaddleOCR 的 C++ 推理依赖 OpenCV 进行图像处理。您需要从源代码编译 OpenCV

来源: deploy/cpp_infer/readme.md30-76

2.3 获取 Paddle 推理库

您可以通过以下两种方式获取 Paddle 推理库

  1. 直接下载:从 Paddle 推理库官网 下载预编译版本

  2. 从源码编译:获取最新功能,您可以从源码编译库

编译好的库将位于 build/paddle_inference_install_dir/

来源: deploy/cpp_infer/readme.md90-153

3. 构建 PaddleOCR C++ 推理

3.1 准备模型

构建之前,您需要准备 OCR 模型。您可以

  • 从 PaddleOCR 下载预训练模型
  • 导出您自己训练的模型

模型应按以下结构组织

inference/
|-- det_db
|   |--inference.pdiparams
|   |--inference.pdmodel
|-- rec_rcnn
|   |--inference.pdiparams
|   |--inference.pdmodel
|-- cls
|   |--inference.pdiparams
|   |--inference.pdmodel
|-- table
|   |--inference.pdiparams
|   |--inference.pdmodel
|-- layout
|   |--inference.pdiparams
|   |--inference.pdmodel

来源: deploy/cpp_infer/readme.md169-190

3.2 编译步骤

要编译 PaddleOCR C++ 推理程序

  1. 修改 tools/build.sh 脚本,设置 OpenCV 和 Paddle 推理库的路径
  1. 运行构建脚本

这将在 build 目录中生成一个名为 ppocr 的可执行文件。

来源: deploy/cpp_infer/readme.md194-214

4. C++ 推理架构

C++ 推理系统由几个关键组件组成,它们协同工作以执行 OCR 任务。

来源: deploy/cpp_infer/include/paddleocr.h deploy/cpp_infer/src/paddleocr.cpp deploy/cpp_infer/include/paddlestructure.h deploy/cpp_infer/src/paddlestructure.cpp deploy/cpp_infer/include/ocr_det.h deploy/cpp_infer/src/ocr_det.cpp deploy/cpp_infer/include/ocr_rec.h deploy/cpp_infer/src/ocr_rec.cpp deploy/cpp_infer/include/ocr_cls.h deploy/cpp_infer/src/ocr_cls.cpp

4.1 核心类架构

PPOCR 类实现模式

来源: deploy/cpp_infer/include/paddleocr.h21-50 deploy/cpp_infer/src/paddleocr.cpp25-29 deploy/cpp_infer/include/ocr_det.h30-84 deploy/cpp_infer/include/ocr_rec.h30-99 deploy/cpp_infer/include/ocr_cls.h30-73

4.2 执行流程

PPOCR::ocr() 中的 OCR 流程执行

来源: deploy/cpp_infer/src/paddleocr.cpp91-117 deploy/cpp_infer/src/ocr_det.cpp92-175 deploy/cpp_infer/src/ocr_rec.cpp24-135 deploy/cpp_infer/src/ocr_cls.cpp23-106

5. 运行推理

5.1 命令行界面

deploy/cpp_infer/src/main.cpp178 中,可执行文件 ppocr 使用 google::ParseCommandLineFlags() 进行参数解析。主执行逻辑根据 FLAGS_type 参数路由到 ocr()structure() 函数。

执行入口

5.1.1 PP-OCRv5 文本识别

5.1.2 PP-StructureV3 文档分析

5.1.3 仅检测

来源: deploy/cpp_infer/src/main.cpp176-200 deploy/cpp_infer/src/main.cpp83-119 deploy/cpp_infer/src/main.cpp121-174

5.2 参数配置

参数系统定义在 deploy/cpp_infer/include/args.h,控制模型加载、硬件利用和处理行为。

5.2.1 硬件配置FLAGS

参数类型默认描述
FLAGS_use_gpuboolfalse通过 paddle_infer::Config::EnableUseGpu() 启用 GPU 加速
FLAGS_gpu_idint0用于 CUDA 操作的 GPU 设备索引
FLAGS_gpu_memint4000GPU 内存分配(MB)
FLAGS_cpu_threadsint10通过 SetCpuMathLibraryNumThreads() 配置 CPU 线程数
FLAGS_enable_mkldnnbooltrue通过 config.EnableMKLDNN() 启用 MKLDNN 加速
FLAGS_use_tensorrtboolfalse通过 config.EnableTensorRtEngine() 启用 TensorRT 优化
FLAGS_precision字符串"fp32"精度模式:"fp32"、"fp16" 或 "int8"

5.2.2 流程控制 FLAGS

参数类型默认代码中的使用
FLAGS_detbooltruePPOCR() 构造函数中控制 DBDetector 的实例化
FLAGS_recbooltruePPOCR() 构造函数中控制 CRNNRecognizer 的实例化
FLAGS_clsboolfalsePPOCR() 构造函数中控制 Classifier 的实例化
FLAGS_tableboolfalsePaddleStructure() 中控制 StructureTableRecognizer
FLAGS_layoutboolfalsePaddleStructure() 中控制 StructureLayoutRecognizer

5.2.3 模型路径 FLAGS

参数用途验证
FLAGS_det_model_dir传递给 DBDetector() 构造函数deploy/cpp_infer/src/main.cpp26-33 中的 check_params() 中进行检查
FLAGS_rec_model_dir传递给 CRNNRecognizer() 构造函数deploy/cpp_infer/src/main.cpp34-47 中的 check_params() 中进行检查
FLAGS_cls_model_dir传递给 Classifier() 构造函数deploy/cpp_infer/src/main.cpp48-55 中的 check_params() 中进行检查
FLAGS_table_model_dir传递给 StructureTableRecognizer()deploy/cpp_infer/src/main.cpp56-66 中的 check_params() 中进行检查

来源: deploy/cpp_infer/src/main.cpp25-81 deploy/cpp_infer/src/paddleocr.cpp31-54 deploy/cpp_infer/src/paddlestructure.cpp29-44

6. C++ 推理实现细节

让我们看看主要组件的实现细节

6.1 DBDetector 实现

DBDetector 类通过以下关键组件实现文本检测(使用 DB 算法)

模型配置与加载

DBDetector::Run() 中的处理流程

  1. 预处理ResizeImgType0::Run()Normalize::Run() 操作
  2. 推理predictor_->Run()(带输入张量重塑)
  3. 后处理DBPostProcessor::BoxesFromBitmap()FilterTagDetRes()

检测处理流程

来源: deploy/cpp_infer/src/ocr_det.cpp23-90 deploy/cpp_infer/src/ocr_det.cpp92-175

6.2 CRNNRecognizer 实现

CRNNRecognizer 类通过批量处理和 CTC 解码来处理文本识别

CRNNRecognizer::Run() 中的批量处理

  • 使用 Utility::argsort(width_list) 按宽度比例对图像进行排序
  • rec_batch_num_ 的批量大小进行处理
  • 应用 CrnnResizeImg::Run() 进行动态宽度调整

CTC 解码逻辑

来源: deploy/cpp_infer/src/ocr_rec.cpp24-135 deploy/cpp_infer/src/ocr_rec.cpp105-128

6.3 PaddleStructure 文档分析

PaddleStructure 类继承自 PPOCR,用于文档结构分析

PaddleStructure::structure() 中的结构分析流程

  1. 布局检测StructureLayoutRecognizer::Run() 识别区域
  2. 表格识别StructureTableRecognizer::Run() 处理表格区域
  3. OCR 集成:将 PPOCR::ocr() 应用于文本区域

表格 HTML 重构

来源: deploy/cpp_infer/src/paddlestructure.cpp48-79 deploy/cpp_infer/src/paddlestructure.cpp137-195

7. 性能优化

C++ 推理实现提供了多种优化选项以提高性能

7.1 CPU 优化

  • 多线程:通过 cpu_math_library_num_threads 控制线程数
  • MKLDNN:通过 enable_mkldnn=true 启用 MKLDNN 加速

7.2 GPU 加速

使用 GPU 加速

  • 设置 use_gpu=true
  • gpu_id 设置为所需的 GPU 索引
  • 使用 gpu_mem 控制内存使用

7.3 TensorRT 集成

为了在 NVIDIA GPU 上获得最佳性能,提供了 TensorRT 集成

  • 设置 use_tensorrt=true
  • 使用 precision 参数选择精度(fp32、fp16 或 int8)

来源: deploy/cpp_infer/src/ocr_det.cpp23-68 deploy/cpp_infer/src/ocr_rec.cpp137-166 deploy/cpp_infer/src/ocr_cls.cpp108-151

8. 常见问题与解决方案

8.1 TensorRT 问题

如果遇到错误:“您正在使用已编译 TensorRT 的 Paddle,但未找到 TensorRT 动态库”

  1. 将所有 TensorRT .dll 文件复制到执行目录
  2. 或将 LD_LIBRARY_PATH 设置为包含 TensorRT 库路径

8.2 构建问题

对于遇到构建错误的 Windows 用户

  • 请确保使用正确版本的 Visual Studio(建议使用 2019 或更高版本)
  • 下载 dirent.h 并将其放入 Visual Studio 的 include 文件夹
  • 将构建配置设置为 Release 模式

来源: deploy/cpp_infer/readme.md452-456 deploy/cpp_infer/docs/windows_vs2019_build.md140-141

9. 结论

PaddleOCR 的 C++ 推理实现为在生产环境中部署 OCR 模型提供了一个高性能的解决方案。通过遵循本文档中的设置、编译和使用说明,您可以有效地利用 C++ 推理功能来满足您的 OCR 应用需求。

模块化设计允许部署的灵活性,从简单的文本识别到复杂文档结构分析。各种优化选项使您能够根据硬件能力和需求来微调性能。