瀏覽代碼

feat: enhance financial document processing framework with improved model selection, layout detection options, and detailed processing flow, including support for various document types and output formats

zhch158_admin 6 天之前
父節點
當前提交
6653c2cb9f
共有 1 個文件被更改,包括 307 次插入162 次删除
  1. 307 162
      zhch/universal_doc_parser/模型统一框架.md

+ 307 - 162
zhch/universal_doc_parser/模型统一框架.md

@@ -1,175 +1,238 @@
-参考minerU实现的模型统一框架,
-对于我们设计的金融场景,
-一种是银行交易流水,特点是单栏列表形式,没有合并单元格,分无线表格和有线表格两种形式;
-另一种是财务报表形式,特点是多栏列表形式,有合并单元格,且表头复杂。且分有线,无线表格两种形式。
-minerU pipeline使用paddle的ocr模型,对于文字识别效果较好,但表格结构识别效果一般
-对于表格识别minerU vlm和PaddleOCR-VL的效果都很好
-对于我们的应用场景,版式识别使用MinerU的doclayout_yolo_docstructbench_imgsz1280_2501.pt模型效果较好
-同时要求为了方便交叉核对,需要返回每个单元格的坐标信息。
+# 金融文档处理统一框架
 
-对于银行交易流水, 构想的处理流程如下:
+参考 MinerU 实现的模型统一框架,针对金融场景设计。
 
-1. 方向旋转, PP-LCNet_x1_0_doc_ori.onnx沿用现有minerU实现
-2. layout检测, doclayout_yolo_docstructbench_imgsz1280_2501.pt
-3. 文本调用PaddleOCR进行检测和识别,pytorch模型
-4. 其他如:表格,数学公式等调用minerU vlm或PaddleOCR-VL进行检测和识别
-5. 调用minerU后处理模块进行表格结构恢复和HTML生成,同时返回单元格坐标信息
+## 支持场景
 
-这里用到的模型都可以通过配置文件进行配置和替换,方便后续进行模型升级和替换,调用模型的代码都应可以采用adpter的方式尽量复用minerU的实现。
+| 场景类型 | 特点 | 表格形式 |
+|---------|------|---------|
+| **银行交易流水** | 单栏列表形式,无合并单元格 | 有线表格 / 无线表格 |
+| **财务报表** | 多栏列表形式,有合并单元格,表头复杂 | 有线表格 / 无线表格 |
+
+## 模型选择
+
+| 模型类型 | 推荐模型 | 说明 |
+|---------|---------|------|
+| **版式检测** | Docling Layout / DocLayout-YOLO | HuggingFace 或 MinerU 模型 |
+| **文字识别** | PaddleOCR (PyTorch) | 效果好,支持角度校正 |
+| **表格结构识别** | MinerU VLM / PaddleOCR-VL | VLM 返回 HTML 结构 |
+| **公式识别** | MinerU VLM | 返回 LaTeX |
+| **方向识别** | PP-LCNet | 沿用 MinerU 实现 |
+| **单元格坐标匹配** | TableCellMatcher | OCR 检测框与 VLM 结构匹配 |
+
+---
+
+## 处理流程
 
 ```mermaid
 graph TB
     A[输入 PDF/图片] --> B{PDF 分类}
     
     B -->|扫描件/图片| C1[页面方向识别<br/>PP-LCNet]
-    B -->|数字原生PDF| C2[Layout 检测]
-    C1 --> D1[Layout 检测]
+    B -->|数字原生PDF| D
+    C1 --> D[Layout 检测<br/>去重叠框]
+    
+    D --> E{元素分类}
     
-    subgraph OCR模式
-        D1 --> E1[文本区域]
-        D1 --> F1[表格区域]
-        E1 --> G1[OCR 检测+识别<br/>自带角度校正]
-        F1 --> H1[表格方向检测]
-        H1 --> I1[OCR 检测<br/>获取文本框坐标]
-        H1 --> J1{使用VLM?}
-        J1 -->|是| K1[VLM 结构识别]
-        J1 -->|否| L1[表格模型识别<br/>SLANet/UNet]
-        I1 --> M1[匹配坐标与结构]
-        K1 --> M1
-        L1 --> M1
+    E --> F[文本类]
+    E --> G[表格类]
+    E --> H[图片类]
+    E --> I[公式类]
+    E --> J[丢弃类]
+    
+    subgraph 文本处理
+        F --> F1{PDF类型?}
+        F1 -->|扫描件| F2[OCR 检测+识别]
+        F1 -->|数字PDF| F3[PDF 字符提取]
+        F3 --> F4{成功?}
+        F4 -->|否| F2
+        F4 -->|是| F5[文本结果]
+        F2 --> F5
+    end
+    
+    subgraph 表格处理
+        G --> G1[OCR 检测<br/>获取文本框坐标]
+        G --> G2[VLM 结构识别<br/>返回 HTML]
+        G1 --> G3[坐标匹配<br/>TableCellMatcher]
+        G2 --> G3
+        G3 --> G4[带坐标的表格]
     end
     
-    subgraph 文本提取模式
-        C2 --> E2[文本区域]
-        C2 --> F2[表格区域]
-        E2 --> G2[PDF 字符提取<br/>pdftext]
-        G2 --> G2a{提取成功?}
-        G2a -->|否| G2b[OCR 补充识别]
-        F2 --> H2[表格方向检测]
-        H2 --> I2[OCR 检测<br/>获取文本框坐标]
-        H2 --> J2{使用VLM?}
-        J2 -->|是| K2[VLM 结构识别]
-        J2 -->|否| L2[表格模型识别<br/>SLANet/UNet]
-        I2 --> M2[匹配坐标与结构]
-        K2 --> M2
-        L2 --> M2
+    subgraph 图片处理
+        H --> H1[裁剪保存]
     end
     
-    G1 --> N[合并所有结果]
-    M1 --> N
-    G2a -->|是| N
-    G2b --> N
-    M2 --> N
+    subgraph 公式处理
+        I --> I1[VLM 识别<br/>返回 LaTeX]
+    end
+    
+    subgraph 丢弃元素
+        J --> J1[OCR 提取文本<br/>保留备用]
+    end
     
-    N --> O[合并跨页表格]
+    F5 --> K[合并所有结果]
+    G4 --> K
+    H1 --> K
+    I1 --> K
+    J1 --> K
+    
+    K --> L[按阅读顺序排序]
+    L --> M[坐标转换回原图]
+    M --> N[合并跨页表格]
+    N --> O[金额数字标准化]
+    O --> P[多格式输出]
 ```
 
+### 元素分类说明
+
+| 元素类别 | 包含类型 | 处理方式 |
+|---------|---------|---------|
+| **文本类** | text, title, header, footer, ref_text, table_caption, image_caption 等 | OCR 或 PDF 提取 |
+| **表格类** | table, table_body | OCR 坐标 + VLM 结构 |
+| **图片类** | image, image_body, figure | 裁剪保存 |
+| **公式类** | interline_equation, equation | VLM 识别 |
+| **丢弃类** | abandon, discarded | OCR 提取备用 |
+
 ---
 
 ## 方向识别策略
 
-| 处理阶段                 | 方向识别          | 建议                                 |
-| ------------------------ | ----------------- | ------------------------------------ |
-| **页面级**               | PP-LCNet          | 可配置,扫描件开启,数字PDF关闭      |
-| **表格区域 + VLM**       | ImgOrientationCls | 可选,VLM 有一定容忍度               |
-| **表格区域 + OCR坐标**   | ImgOrientationCls | **必须**,OCR 坐标依赖正确方向       |
-| **文本区域**             | -                 | 不需要,OCR 自带校正                 |
+| 处理阶段 | 方向识别 | 建议 |
+|---------|---------|------|
+| **页面级** | PP-LCNet | 可配置,扫描件开启,数字PDF关闭 |
+| **表格区域** | - | 可选,VLM 有一定容忍度,OCR 自带角度校正 |
+| **文本区域** | - | 不需要,OCR 自带校正 |
 
 ---
 
 ## OCR 使用策略
 
-| PDF 类型         | 文字块处理                     | 表格处理                           |
-| ---------------- | ------------------------------ | ---------------------------------- |
-| **扫描件/图片**  | OCR 检测 + 识别                | OCR 检测(坐标) + VLM/表格模型(结构) |
-| **数字原生 PDF** | PDF 字符提取(失败时 OCR 补充)| OCR 检测(坐标) + VLM/表格模型(结构) |
+| PDF 类型 | 文字块处理 | 表格处理 |
+|---------|-----------|---------|
+| **扫描件/图片** | OCR 检测 + 识别 | OCR 检测(坐标) + VLM(结构) |
+| **数字原生 PDF** | PDF 字符提取(失败时 OCR 补充) | OCR 检测(坐标) + VLM(结构) |
 
 **关键点**:
 - 数字原生 PDF 的文字块可直接提取,坐标更精确
 - **表格处理无论 PDF 类型都需要 OCR 检测**,用于获取单元格内文本的精确坐标
 - VLM 只返回表格结构(HTML),不返回单元格坐标,需要与 OCR 检测结果匹配
+- 当前实现仅使用 VLM(MinerU VLM 或 PaddleOCR-VL)进行表格结构识别
 
 ---
 
-## 实现说明
-
-### 目录结构
+## 目录结构
 
 ```
 universal_doc_parser/
-├── config/
-│   ├── bank_statement_v2.yaml      # 银行流水配置
-│   ├── financial_report_v2.yaml    # 财务报表配置
-│   ├── bank_statement_mineru_vl.yaml
-│   └── bank_statement_paddle_vl.yaml
-├── core/
-│   ├── config_manager.py           # 配置管理
-│   ├── model_factory.py            # 模型工厂
-│   ├── pipeline_manager.py         # 原版流水线
-│   └── pipeline_manager_v2.py      # 增强版流水线 ⭐
-├── models/
+├── 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                 # 布局处理工具(排序、去重)
+│   ├── 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
-├── utils/
-│   ├── output_formatter.py         # 原版输出格式化
-│   └── output_formatter_v2.py      # 增强版输出格式化 ⭐
-├── main_enhanced.py                # 原版入口
-├── main_v2.py                      # 增强版入口 ⭐
-└── 模型统一框架.md
+│       ├── 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                       # 本文档
 ```
 
-### 使用方法
+---
+
+## 使用方法
+
+### 命令行
 
 ```bash
-# 处理单个PDF文件
-python main_v2.py -i document.pdf -c config/bank_statement_v2.yaml
+# 处理单个 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_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_v2.yaml --debug
+# 开启 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_v2.yaml -o ./my_output/
+python main_v2.py -i doc.pdf -c config/bank_statement_yusys_v2.yaml -o ./my_output/
 ```
 
-### 输出说明
+### Python API
 
-| 输出文件 | 说明 |
-|---------|------|
-| `{doc}_middle.json` | MinerU 标准格式 JSON |
-| `{doc}_enhanced.json` | 增强版 JSON(包含单元格坐标) |
-| `{doc}.md` | Markdown 文件(带坐标注释) |
-| `tables/*.html` | 表格 HTML 文件(带坐标信息) |
-| `{doc}_page_*_layout.png` | Layout 可视化图片(debug模式) |
-| `{doc}_page_*_ocr.png` | OCR 可视化图片(debug模式) |
+```python
+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,   # 金额标准化
+    })
+```
 
-1. **EnhancedDocPipeline** (`pipeline_manager_v2.py`)
-   - 实现完整的处理流程
-   - 支持 PDF 分类(扫描件/数字原生)
-   - 集成 merger 的 TableCellMatcher 进行坐标匹配
+---
+
+## 输出文件说明
 
-2. **OutputFormatterV2** (`output_formatter_v2.py`)
-   - 输出 MinerU 标准格式
-   - 支持 debug 模式可视化
-   - 表格 HTML 包含单元格坐标
+| 输出文件 | 说明 |
+|---------|------|
+| `{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.*` | 标准化前的原始文件(如有修改) |
 
-3. **TableCellMatcher** (来自 `ocr_verify/merger`)
-   - 使用动态规划进行行内单元格匹配
-   - 将 OCR 检测框与 VLM 表格结构匹配
-   - 输出带坐标的增强 HTML
+---
 
-### 配置说明
+## 配置说明
 
 配置文件采用 YAML 格式,主要配置项:
 
 ```yaml
+# 场景名称
+scene_name: "bank_statement"
+
+# 输入配置
+input:
+  supported_formats: [".pdf", ".png", ".jpg", ".jpeg"]
+  dpi: 200  # PDF 转图片的 DPI
+
 # 预处理(方向识别)
 preprocessor:
   module: "mineru"
@@ -178,46 +241,153 @@ preprocessor:
 
 # 版式检测
 layout_detection:
-  module: "mineru"
-  model_name: "layout"
+  module: "docling"  # 可选: "mineru", "paddle", "docling"
+  model_name: "docling-layout-old"
+  model_dir: "ds4sd/docling-layout-old"  # HuggingFace 模型仓库
+  device: "cpu"
+  conf: 0.3
 
-# VL识别(表格、公式)
+# VL 识别(表格、公式)
 vl_recognition:
-  module: "mineru"  # 或 "paddle"
+  module: "paddle"  # 可选: "mineru", "paddle"
   backend: "http-client"
-  server_url: "http://xxx:8121"
+  server_url: "http://xxx:8110"
+  table_recognition:
+    return_cells_coordinate: true
 
-# OCR识别
+# 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模式开启
+  save_layout_image: false    # debug 模式开启
+  save_ocr_image: false       # debug 模式开启
+  normalize_numbers: true     # 金额数字标准化
+```
+
+---
+
+## 支持的布局检测器
+
+### 1. Docling Layout (推荐)
+
+基于 HuggingFace transformers 的 RT-DETR 模型。
+
+```yaml
+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 布局检测器。
+
+```yaml
+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 内置的布局检测模型。
+
+```yaml
+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 检测与去重
+- 元素分类处理
+- 阅读顺序排序
+- 坐标转换
+
+### 2. ElementProcessors (`element_processors.py`)
+
+元素处理器,处理不同类型的元素:
+- `process_text_element()` - 文本处理
+- `process_table_element()` - 表格处理(VLM + OCR 坐标匹配)
+- `process_image_element()` - 图片处理
+- `process_equation_element()` - 公式处理
+- `process_code_element()` - 代码处理
+- `process_discard_element()` - 丢弃元素处理
+
+### 3. OutputFormatterV2 (`output_formatter_v2.py`)
+
+统一输出格式化器:
+- MinerU 标准 middle.json 格式
+- 每页独立 JSON(含单元格坐标)
+- Markdown 输出(完整版 + 按页)
+- 表格 HTML(带 data-bbox 属性)
+- 可视化图片(Layout/OCR)
+- 金额数字标准化
+
+### 4. TableCellMatcher (来自 `merger`)
+
+表格单元格坐标匹配器:
+- 使用动态规划进行行内单元格匹配
+- 将 OCR 检测框与 VLM 表格结构匹配
+- 输出带坐标的增强 HTML
+
 ---
 
 ## 依赖说明
 
 ### MinerU 组件
-- `mineru.backend.pipeline.model_init` - 模型初始化
-- `mineru.backend.vlm.vlm_analyze` - VLM 分析
-- `mineru.utils.pdf_classify` - PDF 分类
 - `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` - 文本匹配
-- `merger.bbox_extractor.BBoxExtractor` - 坐标提取
 
 ### 其他依赖
-- PyMuPDF (fitz) - PDF 处理
+- transformers - Docling 模型加载
+- huggingface_hub - 模型下载
+- onnxruntime - ONNX 模型推理
 - Pillow - 图像处理
 - NumPy - 数值计算
 - BeautifulSoup4 - HTML 解析
@@ -225,24 +395,21 @@ output:
 - loguru - 日志
 
 ---
-# 如何将 merger 模块导入到 MinerU 项目
 
-## 快速开始 🚀
-
-### 推荐方案:可编辑安装
+## 安装 merger 模块
 
 ```bash
 # 1. 进入 ocr_verify 目录
 cd /Users/zhch158/workspace/repository.git/ocr_verify
 
-# 2. 安装 merger 模块(可编辑模式)
+# 2. 安装 merger 模块(可编辑模式)
 pip uninstall -y merger && pip install -e .
 
 # 3. 验证安装
 python3 -c "from merger.table_cell_matcher import TableCellMatcher; print('✅ 安装成功')"
 ```
 
-完成后,在任何 Python 文件中都可以直接导入:
+完成后,在任何 Python 文件中都可以直接导入:
 
 ```python
 from merger.table_cell_matcher import TableCellMatcher
@@ -252,44 +419,22 @@ from merger.bbox_extractor import BBoxExtractor
 
 ---
 
-## 为什么需要导入 merger?
-
-`pipeline_manager_v2.py` 需要使用 `merger` 模块的以下功能:
-
-1. **TableCellMatcher**: 匹配表格单元格坐标与 OCR 结果
-2. **TextMatcher**: 文本匹配和对齐
-3. **BBoxExtractor**: 提取和转换边界框坐标
-
-这些组件用于实现表格识别流程中的**坐标匹配**步骤:
-
-```
-OCR检测(获取文本框坐标) + VLM识别(获取表格结构HTML)
-                ↓
-        TableCellMatcher 匹配
-                ↓
-    带精确坐标的表格单元格
-```
-
----
-
 ## 项目结构
 
 ```
 /Users/zhch158/workspace/repository.git/
 ├── ocr_verify/                          # 源项目
 │   ├── setup.py                         # 安装配置
-│   └── merger/                          # 要导入的模块
-│       ├── __init__.py
+│   └── merger/                          # 表格匹配模块
 │       ├── table_cell_matcher.py        # 表格单元格匹配
 │       ├── text_matcher.py              # 文本匹配
-│       ├── bbox_extractor.py            # 边界框提取
-│       └── ...
+│       └── bbox_extractor.py            # 边界框提取
 └── MinerU/                              # 目标项目
     └── zhch/
-        └── universal_doc_parser/
-            └── core/
-                └── pipeline_manager_v2.py  # 需要导入 merger
+        └── universal_doc_parser/        # 金融文档处理框架
+            ├── core/                    # 核心处理模块
+            ├── models/adapters/         # 模型适配器
+            ├── utils/                   # 输出工具
+            └── config/                  # 配置文件
 ```
-
----