模型统一框架.md 17 KB

金融文档处理统一框架

参考 MinerU 实现的模型统一框架,针对金融场景设计。

支持场景

场景类型 特点 表格形式
银行交易流水 单栏列表形式,无合并单元格 有线表格 / 无线表格
财务报表 多栏列表形式,有合并单元格,表头复杂 有线表格 / 无线表格

模型选择

模型类型 推荐模型 说明
版式检测 Docling Layout / DocLayout-YOLO HuggingFace 或 MinerU 模型
文字识别 PaddleOCR (PyTorch) 效果好,支持角度校正
表格结构识别 MinerU VLM / PaddleOCR-VL VLM 返回 HTML 结构
公式识别 MinerU VLM 返回 LaTeX
方向识别 PP-LCNet 沿用 MinerU 实现
单元格坐标匹配 TableCellMatcher OCR 检测框与 VLM 结构匹配

处理流程

graph TB
    A[输入 PDF/图片] --> B{PDF 分类}
    
    B -->|扫描件/图片| C1[页面方向识别<br/>PP-LCNet]
    B -->|数字原生PDF| D
    C1 --> D[Layout 检测<br/>去重叠框]
    
    D --> E[整页 OCR<br/>获取所有 text spans]
    E --> F[Span-Block 匹配<br/>SpanMatcher]
    F --> G{元素分类}
    
    G --> H[文本类]
    G --> I[表格类]
    G --> J[图片类]
    G --> K[公式类]
    G --> L[丢弃类]
    
    subgraph 文本处理
        H --> H1{有匹配的spans?}
        H1 -->|是| H2[合并 spans 文本]
        H1 -->|否| H3{PDF类型?}
        H3 -->|数字PDF| H4[PDF 字符提取]
        H4 --> H5{成功?}
        H5 -->|否| H6[裁剪区域 OCR]
        H5 -->|是| H7[文本结果]
        H3 -->|扫描件| H6
        H6 --> H7
        H2 --> H7
    end
    
    subgraph 表格处理
        I --> I1[OCR 检测<br/>获取文本框坐标]
        I --> I2[VLM 结构识别<br/>返回 HTML]
        I1 --> I3[坐标匹配<br/>TableCellMatcher]
        I2 --> I3
        I3 --> I4[带坐标的表格]
    end
    
    subgraph 图片处理
        J --> J1[裁剪保存]
    end
    
    subgraph 公式处理
        K --> K1[VLM 识别<br/>返回 LaTeX]
    end
    
    subgraph 丢弃元素
        L --> L1{有匹配的spans?}
        L1 -->|是| L2[合并 spans 文本]
        L1 -->|否| L3[裁剪区域 OCR]
        L2 --> L4[保留备用]
        L3 --> L4
    end
    
    H7 --> M[合并所有结果]
    I4 --> M
    J1 --> M
    K1 --> M
    L4 --> M
    
    M --> N[按阅读顺序排序]
    N --> O[坐标转换回原图]
    O --> P[合并跨页表格]
    P --> Q[金额数字标准化]
    Q --> R[多格式输出]

关键改进:整页 OCR + Span 匹配

参考 MinerU 的处理方式,新流程采用 整页 OCR → Span-Block 匹配 策略:

  1. 整页 OCR:先对整个页面进行 OCR,获取所有 text spans(包含坐标和文本)
  2. Span 去重:移除高 IoU 重叠的 spans,保留置信度高的
  3. Span-Block 匹配:将 OCR spans 按重叠比例匹配到对应的 layout blocks
  4. 文本合并:将匹配到同一 block 的 spans 按阅读顺序合并

优势

  • ✅ 避免裁剪小图 OCR 失败的问题
  • ✅ OCR 可以利用更多上下文信息
  • ✅ 坐标更精确(整页坐标系)
  • ✅ 与 MinerU 处理方式一致

元素分类说明

元素类别 包含类型 处理方式
文本类 text, title, header, footer, ref_text, table_caption, image_caption 等 优先使用匹配的 spans,否则 PDF 提取或裁剪 OCR
表格类 table, table_body OCR 坐标 + VLM 结构
图片类 image, image_body, figure 裁剪保存
公式类 interline_equation, equation VLM 识别
丢弃类 abandon, discarded 优先使用匹配的 spans,否则裁剪 OCR

方向识别策略

处理阶段 方向识别 建议
页面级 PP-LCNet 可配置,扫描件开启,数字PDF关闭
表格区域 - 可选,VLM 有一定容忍度,OCR 自带角度校正
文本区域 - 不需要,OCR 自带校正

Layout 后处理

大面积文本块转表格

当Layout检测将大面积的表格区域误识别为文本框时,可以通过后处理自动转换:

判断规则

  • 面积占比:占页面面积超过阈值(默认25%)
  • 尺寸比例:宽度和高度都超过一定比例(避免细长条)
  • 表格冲突:如果页面已有表格,不进行转换(避免误判)

配置示例

layout:
  convert_large_text_to_table: true  # 是否启用
  min_text_area_ratio: 0.25          # 最小面积占比(25%)
  min_text_width_ratio: 0.4          # 最小宽度占比(40%)
  min_text_height_ratio: 0.3         # 最小高度占比(30%)

详细说明请参考:Layout后处理-文本转表格.md


OCR 使用策略

PDF 类型 文字块处理 表格处理
扫描件/图片 整页 OCR → Span 匹配 OCR 检测(坐标) + VLM(结构)
数字原生 PDF 整页 OCR → Span 匹配 / PDF 字符提取 OCR 检测(坐标) + VLM(结构)

关键点

  • 整页 OCR 优先:先对整页进行 OCR,再将结果匹配到 layout blocks
  • 数字原生 PDF 在 spans 匹配失败时,会尝试 PDF 字符提取
  • 表格处理无论 PDF 类型都需要 OCR 检测,用于获取单元格内文本的精确坐标
  • VLM 只返回表格结构(HTML),不返回单元格坐标,需要与 OCR 检测结果匹配
  • 当前实现仅使用 VLM(MinerU VLM 或 PaddleOCR-VL)进行表格结构识别

OCR 参数配置

默认参数(已优化,参考PPStructureV3)

  • det_threshold: 0.6(检测框置信度阈值,提高可减少噪声框)
  • unclip_ratio: 1.5(检测框扩展比例,降低可提高框精确度)
  • enable_merge_det_boxes: False(是否合并检测框,表格场景建议False)

配置示例

ocr:
  det_threshold: 0.6              # 检测阈值(0.3-0.7,越高越严格)
  unclip_ratio: 1.5               # 扩展比例(1.3-1.8,越低越精确)
  enable_merge_det_boxes: false   # 合并框(表格场景建议false)
  language: ch                     # 语言(ch/ch_lite/en等)

参数调优建议

  • 表格密集场景det_threshold=0.6, enable_merge_det_boxes=false
  • 文本稀疏场景det_threshold=0.4, enable_merge_det_boxes=true
  • 扫描件质量差det_threshold=0.3, unclip_ratio=1.8

详细分析请参考:OCR识别差异分析与改进方案.md


目录结构

universal_doc_parser/
├── config/                              # 配置文件
│   ├── bank_statement_yusys_v2.yaml    # 银行流水配置(Docling + PaddleOCR-VL)
│   ├── bank_statement_mineru_v2.yaml   # 银行流水配置(MinerU layout + MinerU VLM)
│   ├── bank_statement_mineru_vl.yaml   # 银行流水配置(MinerU VLM)
│   └── bank_statement_paddle_vl.yaml   # 银行流水配置(PaddleOCR-VL)
│
├── core/                                # 核心处理模块
│   ├── pipeline_manager_v2.py          # 主流水线管理器 ⭐
│   ├── element_processors.py           # 元素处理器(文本、表格、图片等)
│   ├── coordinate_utils.py             # 坐标转换工具
│   ├── layout_utils.py                 # 布局处理工具(排序、去重、SpanMatcher)⭐
│   ├── pdf_utils.py                    # PDF 处理工具
│   ├── config_manager.py               # 配置管理
│   └── model_factory.py                # 模型工厂
│
├── models/                              # 模型适配器
│   └── adapters/
│       ├── base.py                     # 适配器基类
│       ├── mineru_adapter.py           # MinerU 适配器
│       ├── paddle_vl_adapter.py        # PaddleOCR-VL 适配器
│       ├── paddle_layout_detector.py   # PaddleX RT-DETR 布局检测器
│       └── docling_layout_adapter.py   # Docling 布局检测器 ⭐
│
├── utils/                               # 输出工具模块
│   ├── output_formatter_v2.py          # 统一输出格式化器 ⭐
│   ├── json_formatters.py              # JSON 格式化(middle.json, page.json)
│   ├── markdown_generator.py           # Markdown 生成器
│   ├── html_generator.py               # HTML 生成器
│   ├── visualization_utils.py          # 可视化工具(layout/OCR 图片)
│   └── normalize_financial_numbers.py  # 金额数字标准化
│
├── main_v2.py                           # 命令行入口 ⭐
└── 模型统一框架.md                       # 本文档

使用方法

命令行

# 处理单个 PDF 文件
python main_v2.py -i document.pdf -c config/bank_statement_yusys_v2.yaml

# 处理图片目录
python main_v2.py -i ./images/ -c config/bank_statement_yusys_v2.yaml

# 开启 debug 模式(输出可视化图片)
python main_v2.py -i doc.pdf -c config/bank_statement_yusys_v2.yaml --debug

# 指定输出目录
python main_v2.py -i doc.pdf -c config/bank_statement_yusys_v2.yaml -o ./my_output/

Python API

from core.pipeline_manager_v2 import EnhancedDocPipeline
from utils import OutputFormatterV2

# 初始化流水线
with EnhancedDocPipeline("config/bank_statement_yusys_v2.yaml") as pipeline:
    # 处理文档
    results = pipeline.process_document("document.pdf")
    
    # 保存结果
    formatter = OutputFormatterV2("./output")
    output_paths = formatter.save_results(results, {
        'save_json': True,
        'save_markdown': True,
        'save_html': True,
        'save_layout_image': True,  # debug
        'save_ocr_image': True,     # debug
        'normalize_numbers': True,   # 金额标准化
    })

输出文件说明

输出文件 说明
{doc}_middle.json MinerU 标准格式 JSON
{doc}_page_001.json 每页独立 JSON(包含单元格坐标)
{doc}.md 完整文档 Markdown
{doc}_page_001.md 每页独立 Markdown(带坐标注释)
tables/*.html 表格 HTML 文件(带 data-bbox 坐标)
images/ 提取的图片元素
{doc}_page_001_layout.png Layout 可视化图片(debug 模式)
{doc}_page_001_ocr.png OCR 可视化图片(debug 模式)
*_original.* 标准化前的原始文件(如有修改)

配置说明

配置文件采用 YAML 格式,主要配置项:

# 场景名称
scene_name: "bank_statement"

# 输入配置
input:
  supported_formats: [".pdf", ".png", ".jpg", ".jpeg"]
  dpi: 200  # PDF 转图片的 DPI

# 预处理(方向识别)
preprocessor:
  module: "mineru"
  orientation_classifier:
    enabled: true  # 扫描件自动开启

# 版式检测
layout_detection:
  module: "docling"  # 可选: "mineru", "paddle", "docling"
  model_name: "docling-layout-old"
  model_dir: "ds4sd/docling-layout-old"  # HuggingFace 模型仓库
  device: "cpu"
  conf: 0.3

# VL 识别(表格、公式)
vl_recognition:
  module: "paddle"  # 可选: "mineru", "paddle"
  backend: "http-client"
  server_url: "http://xxx:8110"
  table_recognition:
    return_cells_coordinate: true

# OCR 识别
ocr_recognition:
  module: "mineru"
  language: "ch"

# 输出配置
output:
  create_subdir: false        # 是否创建子目录
  save_json: true
  save_markdown: true
  save_html: true
  save_layout_image: false    # debug 模式开启
  save_ocr_image: false       # debug 模式开启
  normalize_numbers: true     # 金额数字标准化

支持的布局检测器

1. Docling Layout (推荐)

基于 HuggingFace transformers 的 RT-DETR 模型。

layout_detection:
  module: "docling"
  model_name: "docling-layout-old"
  model_dir: "ds4sd/docling-layout-old"

支持的模型:

  • ds4sd/docling-layout-old
  • ds4sd/docling-layout-heron
  • ds4sd/docling-layout-egret-medium
  • ds4sd/docling-layout-egret-large

2. PaddleX RT-DETR (ONNX)

基于 ONNX Runtime 的 PaddleX 布局检测器。

layout_detection:
  module: "paddle"
  model_name: "RT-DETR-H_layout_17cls"
  model_dir: "/path/to/RT-DETR-H_layout_17cls.onnx"

3. MinerU DocLayout-YOLO

MinerU 内置的布局检测模型。

layout_detection:
  module: "mineru"
  model_name: "layout"

类别映射

所有布局检测器的输出都会统一映射到 MinerU/EnhancedDocPipeline 类别体系:

类别分类 包含类别
文本类 (TEXT) text, title, header, footer, page_number, ref_text, page_footnote, aside_text, ocr_text
表格类 (TABLE) table, table_body, table_caption, table_footnote
图片类 (IMAGE) image, image_body, figure, image_caption, image_footnote
公式类 (EQUATION) interline_equation, inline_equation, equation
代码类 (CODE) code, code_body, code_caption, algorithm
丢弃类 (DISCARD) abandon, discarded

核心组件

1. EnhancedDocPipeline (pipeline_manager_v2.py)

主流水线管理器,实现完整处理流程:

  • PDF 分类(扫描件/数字原生)
  • 页面方向识别
  • Layout 检测与去重
  • 整页 OCR + Span-Block 匹配
  • 元素分类处理
  • 阅读顺序排序
  • 坐标转换

2. SpanMatcher (layout_utils.py)

OCR Span 与 Layout Block 匹配器,参考 MinerU 实现:

  • match_spans_to_blocks() - 将 spans 匹配到对应的 blocks
  • merge_spans_to_text() - 将多个 spans 合并为文本
  • remove_duplicate_spans() - 去除重复 spans
  • poly_to_bbox() - 多边形坐标转 bbox

3. ElementProcessors (element_processors.py)

元素处理器,处理不同类型的元素:

  • process_text_element() - 文本处理(支持 pre_matched_spans)
  • process_table_element() - 表格处理(VLM + OCR 坐标匹配)
  • process_image_element() - 图片处理
  • process_equation_element() - 公式处理
  • process_code_element() - 代码处理
  • process_discard_element() - 丢弃元素处理(支持 pre_matched_spans)

3. OutputFormatterV2 (output_formatter_v2.py)

统一输出格式化器:

  • MinerU 标准 middle.json 格式
  • 每页独立 JSON(含单元格坐标)
  • Markdown 输出(完整版 + 按页)
  • 表格 HTML(带 data-bbox 属性)
  • 可视化图片(Layout/OCR)
  • 金额数字标准化

4. TableCellMatcher (来自 merger)

表格单元格坐标匹配器:

  • 使用动态规划进行行内单元格匹配
  • 将 OCR 检测框与 VLM 表格结构匹配
  • 输出带坐标的增强 HTML

依赖说明

MinerU 组件

  • mineru.utils.pdf_image_tools - PDF 图像处理
  • mineru.utils.pdf_text_tool - PDF 文本提取
  • mineru.utils.boxbase - 边界框计算
  • mineru.model.ocr - OCR 模型
  • mineru.model.ori_cls - 方向分类模型

Merger 组件(来自 ocr_verify)

  • merger.table_cell_matcher.TableCellMatcher - 单元格坐标匹配
  • merger.text_matcher.TextMatcher - 文本匹配

其他依赖

  • transformers - Docling 模型加载
  • huggingface_hub - 模型下载
  • onnxruntime - ONNX 模型推理
  • Pillow - 图像处理
  • NumPy - 数值计算
  • BeautifulSoup4 - HTML 解析
  • PyYAML - 配置文件解析
  • loguru - 日志

安装 merger 模块

# 1. 进入 ocr_verify 目录
cd /Users/zhch158/workspace/repository.git/ocr_verify

# 2. 安装 merger 模块(可编辑模式)
pip uninstall -y merger && pip install -e .

# 3. 验证安装
python3 -c "from merger.table_cell_matcher import TableCellMatcher; print('✅ 安装成功')"

完成后,在任何 Python 文件中都可以直接导入:

from merger.table_cell_matcher import TableCellMatcher
from merger.text_matcher import TextMatcher
from merger.bbox_extractor import BBoxExtractor

项目结构

/Users/zhch158/workspace/repository.git/
├── ocr_verify/                          # 源项目
│   ├── setup.py                         # 安装配置
│   └── merger/                          # 表格匹配模块
│       ├── table_cell_matcher.py        # 表格单元格匹配
│       ├── text_matcher.py              # 文本匹配
│       └── bbox_extractor.py            # 边界框提取
│
└── MinerU/                              # 目标项目
    └── zhch/
        └── universal_doc_parser/        # 金融文档处理框架
            ├── core/                    # 核心处理模块
            ├── models/adapters/         # 模型适配器
            ├── utils/                   # 输出工具
            └── config/                  # 配置文件