当前位置: 首页 > news >正文

ai之pdf解析工具 PPStructure 还是PaddleOCR

目录

  • 重点是四 先用 PPStructure 版面分析,分成不同的块儿,再选用 PaddleOCR、或PPStructure
  • 基础路径
  • OCR模型配置
  • OCR模型配置
  • GPU配置
  • 硬件配置
  • 性能配置
      • 一、框架选型对比分析
        • 1. **PaddleOCR核心能力**
        • 2. **PP-Structure核心能力**
        • 3. **选型结论**
      • 二、错误根因分析与修复方案
        • 1. **错误现象**
        • 2. **深层原因**
        • 3. **修复方案
      • 三、性能优化建议
        • 1. **GPU资源利用**
        • 2. **内存管理**
        • 3. **模型裁剪**
      • 四、架构设计升级建议
        • 1. **流程重组**
        • 2. **模块解耦**
      • 五、关键参数调优指南

重点是四 先用 PPStructure 版面分析,分成不同的块儿,再选用 PaddleOCR、或PPStructure

https://chat.deepseek.com/a/chat/s/1dafb23d-d230-48a6-b3a1-72569eb1c7cd

我有解析PDF的程序如下:
1、配置
“”"
OCR处理工具类
功能:统一管理OCR引擎的初始化、处理、资源回收
“”"
import multiprocessing
import os
from pathlib import Path
from typing import Tuple, Optional, Dict, Any

import paddle
from paddleocr import PaddleOCR, PPStructure

from .GPUResource import GPUResourceController
from …utils.logutil import get_local_logger

logger = get_local_logger()

基础路径

BASE_DIR = Path(file).parent.parent
MODEL_DIR = BASE_DIR / “common/models”
logger.info(f" >>>>>> MODEL_DIR路径: {MODEL_DIR}")

OCR模型配置

START_PAGE = 6

OCR模型配置

OCR_CONFIG = {
# 显式指定所有模型路径
# det_model_dir=str(MODEL_DIR /“ch_PP-OCRv4_det_infer”),
“det_model_dir”: str(MODEL_DIR / “ch_PP-OCRv4_det_infer”),
“rec_model_dir”: str(MODEL_DIR / “ch_PP-OCRv4_rec_infer”),
“cls_model_dir”: str(MODEL_DIR / “ch_ppocr_mobile_v2.0_cls_infer”),
“table_model_dir”: str(MODEL_DIR / “en_ppstructure_mobile_v2.0_table_structure_infer”),
“layout_model_dir”: str(MODEL_DIR / “en_ppstructure_mobile_v2.0_layout_infer”),
“lang”: “ch”,
“ocr_version”: “PP-OCRv4”,
“table_version”: “PP-StructureV2”
}

GPU配置

GPU_CONFIG = {
“enable_gpu”: True,
“max_gpus”: 2,
“memory_fraction”: 0.5
}

硬件配置

GPU_MEMORY_LIMIT = 0.8 # 单进程最大显存占比
CPU_THREADS = 4 # CPU模式线程数

性能配置

PRECISION_MODE = “fp16” if paddle.is_compiled_with_cuda() else “fp32”
ENABLE_TENSORRT = True

use_gpu_flag = paddle.device.is_compiled_with_cuda()
print(f"torch.cuda.is_available(){use_gpu_flag}")
print(f"torch.version
{paddle.device.get_cudnn_version()}")

class OCREngineInitError(Exception):
“”“OCR引擎初始化异常”“”
pass

“”"
OCR配置工具类
“”"
class OCRConfig:

def __init__(self, process_idx: int = 0):"""初始化OCR工具:param process_idx: 进程ID(用于多进程GPU分配)"""self.process_idx = process_idxself.gpu_id = -1self.ocr_engine = Noneself.table_engine = Noneself._init_gpu()self._init_ocr_engine()self._init_table_engine()def __enter__(self):self._set_hardware_environment()self._init_engines()return selfdef __exit__(self, exc_type, *_):self._cleanup_resources()self._report_gpu_status(exc_type is None)def _set_hardware_environment(self):os.environ["CUDA_VISIBLE_DEVICES"] = str(self.gpu_id) if self.gpu_id != -1 else ""device = "gpu:0" if self.gpu_id != -1 else "cpu"paddle.set_device(device)if self.gpu_id != -1:paddle.set_flags({'FLAGS_fraction_of_gpu_memory_to_use': GPU_MEMORY_LIMIT,'FLAGS_allocator_strategy': 'auto_growth'})def _init_gpu(self) -> None:"""初始化GPU环境"""if not GPU_CONFIG["enable_gpu"] or not paddle.is_compiled_with_cuda():logger.info(f" paddle.is_compiled_with_cuda: {paddle.device.is_compiled_with_cuda()}, 即将运行在CPU模式")paddle.set_device("cpu")returnnum_gpus = paddle.device.cuda.device_count()if num_gpus == 0:logger.warn(f" num_gpus: {num_gpus}, 没有检测到可用的GUP, 即将运行在CPU模式")return -1  # 标记为CPU模式self.gpu_id = self.process_idx % num_gpusos.environ["CUDA_VISIBLE_DEVICES"] = str(self.gpu_id)paddle.set_device(f"gpu:{self.gpu_id}")logger.info(f"初始化GPU:{self.gpu_id} | 进程:{self.process_idx}")# 设置显存分配比例paddle.set_flags({'FLAGS_fraction_of_gpu_memory_to_use': GPU_CONFIG["memory_fraction"]})def _init_ocr_engine(self) -> None:"""初始化OCR引擎"""try:self.ocr_engine = PaddleOCR(use_angle_cls=True,lang=OCR_CONFIG["lang"],page_num=START_PAGE,use_gpu=self.gpu_id != -1,gpu_id=self.gpu_id,table_model_dir="../common/models/en_ppstructure_mobile_v2.0_table_structure_infer",  # 显式指定表格模型# 显式指定所有模型路径# det_model_dir=str(MODEL_DIR /"ch_PP-OCRv4_det_infer"),det_model_dir=OCR_CONFIG["det_model_dir"],rec_model_dir=OCR_CONFIG["rec_model_dir"],cls_model_dir=OCR_CONFIG["cls_model_dir"],# ocr_version=OCR_CONFIG["ocr_version"],table_version="PP-StructureV2",  # 使用表格识别模型show_log=False,# 性能优化参数enable_mkldnn=True,  # Intel CPU 加速use_tensorrt=False,   # NVIDIA GPU 加速precision="fp16"     # 混合精度推理)print(f" OCR引擎初始化成功 [PID:{os.getpid()}] Assigned to GPU {self.gpu_id} (Process index: {self.process_idx})")except Exception as e:logger.error(f"OCR引擎初始化失败: {str(e)}")raise OCREngineInitError("OCR初始化失败") from edef _init_table_engine(self) -> None:"""初始化表格引擎: 使用RapidTable """# table_input = RapidTableInput(#     model_type="unitable",#     use_cuda=self.gpu_id != -1,#     device=f"cuda:{self.gpu_id}" if self.gpu_id != -1 else "cpu"# )# self.table_engine = RapidTable(table_input)"""初始化表格引擎: 使用PPStructure """try:self.table_engine = PPStructure(table_model_dir=OCR_CONFIG["table_model_dir"],layout_model_dir=OCR_CONFIG["layout_model_dir"],table_version=OCR_CONFIG["table_version"],ocr=False,use_gpu=GPU_CONFIG["enable_gpu"],gpu_id=self.gpu_id,show_log=False)logger.info("表格引擎初始化成功")except Exception as e:logger.error(f"表格引擎初始化失败: {str(e)}")raise OCREngineInitError("表格引擎初始化失败") from edef _cleanup_resources(self):"""资源清理"""if self.gpu_id != -1:paddle.device.cuda.empty_cache()logger.info(f"已释放GPU:{self.gpu_id}资源")
def _report_gpu_status(self, success: bool):if self.gpu_id != -1:GPUResourceController().release_gpu(self.gpu_id, success)

class OCRManager:
“”"
OCR引擎管理器(多进程安全)
“”"
_engines = {}

@classmethod
def get_engine(cls, process_idx: int) -> OCRConfig:"""获取进程专用引擎"""if not process_idx:process_idx = os.getpid()if process_idx not in cls._engines:try:cls._engines[process_idx] = OCRConfig(process_idx)except OCREngineInitError as e:raise RuntimeError(f"无法为进程{process_idx}创建引擎") from ereturn cls._engines[process_idx]
"""
GPU资源管理器(进程安全版本)
核心功能:
- 自动检测可用GPU
- 实现进程级GPU分配
- 避免跨进程污染
"""
_gpu_ring = []
_lock = multiprocessing.Lock()def __init__(self):self._init_gpu_pool()def _init_gpu_pool(self):"""安全初始化GPU资源池"""with self._lock:if not self._gpu_ring:if paddle.is_compiled_with_cuda():num_gpus = paddle.device.cuda.device_count()self._gpu_ring = list(range(num_gpus)) if num_gpus > 0 else []logger.info(f"GPU资源池初始化完成: {self._gpu_ring}")def acquire_gpu(self, process_id: int) -> int:"""进程安全获取GPU ID"""with self._lock:if not self._gpu_ring:return -1return self._gpu_ring[process_id % len(self._gpu_ring)]

2、处理程序:
def _process_ocr_and_table(self, img_path, page_idx:int):
# 假设这是你的 OCR 和表格识别逻辑
try:
“”“使用进程级引擎处理”“”
ocr_config = OCRManager.get_engine(os.getpid())
ocr_engine = ocr_config.ocr_engine
table_engine = ocr_config.table_engine

        # OCR识别ocr_output = ocr_engine.ocr(img_path)if not ocr_output:raise ValueError(" ocr_output OCR未识别到内容")logger.info(f" 第{page_idx}页OCR识别结果,类型:{type(ocr_output)}, \n 内容示例:{ocr_output}")# 解析OCR结果:每个元素的结构为 [box_coords, (text, score)]boxes = [line[0] for line in ocr_output]  # 提取所有框坐标txts = [line[1][0] for line in ocr_output]  # 提取所有文本

相关文章:

  • 微信小程序之Promise-Promise初始用
  • 华为模拟器练习简单的拓扑图(3台路由器和2台pc)
  • 线性Wi-Fi FEM被卷死,非线性FEM是未来?
  • 【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(3)
  • Linux 搭建FTP服务器(vsftpd)
  • Spring Boot与Eventuate Tram整合:构建可靠的事件驱动型分布式事务
  • spring中的BeanFactoryAware接口详解
  • SpringBoot Day_03
  • 【Spark集成HBase】Spark读写HBase表
  • 一次Java Full GC 的排查
  • JAVA EE(进阶)_CSS
  • Jenkins与Maven的集成配置
  • framework 编译技巧
  • 使用 OpenCV 构建稳定的多面镜片墙效果(镜面反射 + Delaunay 分块)
  • c/c++的opencv膨胀
  • 解决SQL Server SQL语句性能问题(9)——创建和更新统计对象
  • 蓝桥杯 11. 保卫国王大道
  • 【Java高阶面经:数据库篇】18、分布式事务:如何在分库分表中实现高性能与一致性?
  • Cadence学习笔记之---PCB的布线与铺铜
  • OceanBase数据库全面指南(查询进阶篇DQL)
  • 莱芜话题 莱芜在线/青岛seo青岛黑八网络最强
  • 做情趣用品网站需要哪些资质/企业专业搜索引擎优化
  • 凡科网做网站如何推广/搜索引擎优化seo的英文全称是
  • 深圳市哪些公司做网站好/淘宝推广工具
  • 做头像一个字的网站/南宁seo网络推广
  • 怎样对一个网站做seo/怎么做网站优化排名