正在收集工作区信息正在筛选到最相关的信息根据 demo.py 的代码分析,我来生成 MinerU 的处理流程图:
graph TB
Start([开始: 输入PDF/图片文件]) --> ReadFile[read_fn: 读取文件字节]
ReadFile --> CheckBackend{选择后端?}
%% Pipeline 后端流程
CheckBackend -->|backend=pipeline| ConvertPDF1[convert_pdf_bytes_to_bytes_by_pypdfium2<br/>转换PDF字节流]
ConvertPDF1 --> PipelineAnalyze[pipeline_doc_analyze<br/>批量分析文档]
PipelineAnalyze --> CheckMethod{检查解析方法}
CheckMethod -->|parse_method=auto| Classify[classify模型<br/>PDF分类: txt/ocr]
CheckMethod -->|parse_method=txt| SetTxt[设置txt模式]
CheckMethod -->|parse_method=ocr| SetOcr[设置ocr模式]
Classify --> PDFType{PDF类型?}
SetTxt --> LoadImages1
SetOcr --> LoadImages1
PDFType -->|文字PDF txt模式| LoadImages1[load_images_from_pdf<br/>加载PDF页面图像<br/>data: images_list, pdf_doc]
PDFType -->|图片PDF ocr模式| LoadImages1
LoadImages1 --> BatchInfer[batch_image_analyze<br/>批量推理]
BatchInfer --> LayoutModel[布局检测模型<br/>MinerU Layout Detection]
LayoutModel --> LayoutResult[layout_det结果<br/>检测文本/表格/图片区域]
LayoutResult --> OCRBranch{需要OCR?}
OCRBranch -->|txt模式: 文字PDF| ExtractText[提取嵌入文本<br/>直接读取PDF文本层]
OCRBranch -->|ocr模式: 图片PDF| OCRModel[OCR识别模型<br/>PaddleOCR/Surya]
ExtractText --> MergeText[文本合并]
OCRModel --> OCRResult[OCR识别结果<br/>文本块坐标+内容]
OCRResult --> MergeText
MergeText --> FormulaCheck{公式识别?}
FormulaCheck -->|formula_enable=True| FormulaModel[公式识别模型<br/>UniMERNet]
FormulaCheck -->|formula_enable=False| TableCheck
FormulaModel --> FormulaResult[公式LaTeX结果]
FormulaResult --> TableCheck
TableCheck{表格识别?}
TableCheck -->|table_enable=True| TableModel[表格识别模型<br/>StructEqTable]
TableCheck -->|table_enable=False| ModelList
TableModel --> TableResult[表格HTML结果]
TableResult --> ModelList
ModelList[生成model_list<br/>原始模型输出JSON] --> ToMiddleJson[pipeline_result_to_middle_json<br/>转换为中间JSON格式]
ToMiddleJson --> MiddleJson[middle_json<br/>包含pdf_info数组]
MiddleJson --> ProcessOutput1[_process_output<br/>处理输出]
%% VLM 后端流程
CheckBackend -->|backend=vlm-xxx| ConvertPDF2[convert_pdf_bytes_to_bytes_by_pypdfium2<br/>转换PDF字节流]
ConvertPDF2 --> VLMAnalyze[vlm_doc_analyze<br/>VLM端到端分析]
VLMAnalyze --> CheckVLMBackend{VLM后端类型?}
CheckVLMBackend -->|transformers| VLMTransformers[加载本地VLM模型<br/>MinerU-VLM/MinerU2.5-2509-1.2B]
CheckVLMBackend -->|vllm-engine| VLMEngine[vLLM引擎<br/>本地GPU推理]
CheckVLMBackend -->|http-client| VLMClient[HTTP客户端<br/>连接远程vLLM服务器]
VLMTransformers --> VLMInfer[VLM模型推理<br/>输入: PDF图像<br/>输出: 结构化JSON]
VLMEngine --> VLMInfer
VLMClient --> HTTPRequest[发送HTTP请求<br/>server_url]
HTTPRequest --> VLMInfer
VLMInfer --> VLMResult[VLM输出结果<br/>直接生成结构化内容]
VLMResult --> VLMMiddleJson[result_to_middle_json<br/>转换为middle_json格式]
VLMMiddleJson --> ProcessOutput2[_process_output<br/>处理输出]
%% 输出处理流程
ProcessOutput1 --> DrawLayout{绘制布局框?}
ProcessOutput2 --> DrawLayout
DrawLayout -->|f_draw_layout_bbox=True| DrawLayoutPDF[draw_layout_bbox<br/>生成layout.pdf]
DrawLayout -->|False| DrawSpan
DrawLayoutPDF --> DrawSpan
DrawSpan{绘制span框?}
DrawSpan -->|f_draw_span_bbox=True| DrawSpanPDF[draw_span_bbox<br/>生成span.pdf]
DrawSpan -->|False| MakeMarkdown
DrawSpanPDF --> MakeMarkdown
MakeMarkdown{生成Markdown?}
MakeMarkdown -->|f_dump_md=True| UnionMake1[pipeline_union_make 或<br/>vlm_union_make]
MakeMarkdown -->|False| ContentList
UnionMake1 --> MarkdownFile[输出: xxx.md<br/>包含文本/公式/表格/图片]
MarkdownFile --> ContentList
ContentList{生成内容列表?}
ContentList -->|f_dump_content_list=True| UnionMake2[union_make<br/>MakeMode.CONTENT_LIST]
ContentList -->|False| MiddleJsonOut
UnionMake2 --> ContentListFile[输出: xxx_content_list.json<br/>结构化内容列表]
ContentListFile --> MiddleJsonOut
MiddleJsonOut{保存中间JSON?}
MiddleJsonOut -->|f_dump_middle_json=True| MiddleJsonFile[输出: xxx_middle.json<br/>中间处理结果]
MiddleJsonOut -->|False| ModelOut
MiddleJsonFile --> ModelOut
ModelOut{保存模型输出?}
ModelOut -->|f_dump_model_output=True| ModelFile[输出: xxx_model.json<br/>原始模型输出]
ModelOut -->|False| End
ModelFile --> End([结束: 所有文件保存到output_dir])
%% 样式定义
classDef modelClass fill:#e1f5ff,stroke:#01579b,stroke-width:2px
classDef dataClass fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef processClass fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
class LayoutModel,OCRModel,FormulaModel,TableModel,VLMTransformers,VLMEngine,Classify modelClass
class LayoutResult,OCRResult,FormulaResult,TableResult,ModelList,MiddleJson,VLMResult dataClass
class PipelineAnalyze,VLMAnalyze,ToMiddleJson,VLMMiddleJson,ProcessOutput1,ProcessOutput2 processClass
| 维度 | 文字PDF (txt模式) | 图片PDF (ocr模式) |
|---|---|---|
| 检测方式 | classify 模型自动判断 |
手动指定或分类识别 |
| 文本提取 | 直接读取PDF嵌入的文本层 | 使用OCR模型识别图像中的文字 |
| 处理速度 | 快速(无需OCR) | 较慢(需要OCR推理) |
| 准确性 | 高(原生文本) | 取决于OCR模型质量 |
| 典型场景 | Word转PDF、电子书 | 扫描件、截图PDF |
| 特性 | Pipeline后端 | VLM后端 |
|---|---|---|
| 模型架构 | 多个专用模型(Layout+OCR+公式+表格) | 单一端到端VLM模型 |
| 处理流程 | 分步骤处理,每步调用不同模型 | 一次性输出结构化结果 |
| 优势 | 可控性强,每步可优化 | 简化流程,理解能力强 |
| 劣势 | 流程复杂,错误累积 | 需要大模型支持 |
| 适用场景 | 通用文档解析 | 复杂布局/多语言混排 |
# Pipeline模式数据流
PDF字节流 → 图像列表(images_list) → 模型推理(model_list) → 中间JSON(middle_json) → Markdown
# VLM模式数据流
PDF字节流 → 图像列表 → VLM推理(infer_result) → 中间JSON(middle_json) → Markdown
pdf_info数组)[10.192.72.11:~/models/modelscope_cache/models/OpenDataLab/PDF-Extract-Kit-1___0/models]$ find .
.
./MFR
./MFR/unimernet_hf_small_2503
./MFR/unimernet_hf_small_2503/config.json
./MFR/unimernet_hf_small_2503/model.safetensors
./MFR/unimernet_hf_small_2503/README.md
./MFR/unimernet_hf_small_2503/tokenizer_config.json
./MFR/unimernet_hf_small_2503/tokenizer.json
./MFR/unimernet_hf_small_2503/special_tokens_map.json
./MFR/unimernet_hf_small_2503/generation_config.json
./TabRec
./TabRec/UnetStructure
./TabRec/UnetStructure/unet.onnx
./TabRec/SlanetPlus
./TabRec/SlanetPlus/slanet-plus.onnx
./ReadingOrder
./ReadingOrder/layout_reader
./ReadingOrder/layout_reader/config.json
./ReadingOrder/layout_reader/model.safetensors
./OCR
./OCR/paddleocr_torch
./OCR/paddleocr_torch/latin_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv3_det_infer.pth
./OCR/paddleocr_torch/en_PP-OCRv3_det_infer.pth
./OCR/paddleocr_torch/te_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv4_det_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv5_rec_server_infer.pth
./OCR/paddleocr_torch/en_PP-OCRv4_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv4_rec_server_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/korean_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/korean_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv4_rec_server_doc_infer.pth
./OCR/paddleocr_torch/en_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/ch_ptocr_mobile_v2.0_cls_infer.pth
./OCR/paddleocr_torch/th_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/latin_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/el_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/Multilingual_PP-OCRv3_det_infer.pth
./OCR/paddleocr_torch/arabic_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv4_rec_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv5_det_infer.pth
./OCR/paddleocr_torch/devanagari_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/eslav_PP-OCRv5_rec_infer.pth
./OCR/paddleocr_torch/ta_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/cyrillic_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/ka_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/chinese_cht_PP-OCRv3_rec_infer.pth
./OCR/paddleocr_torch/japan_PP-OCRv3_rec_infer.pth
./TabCls
./TabCls/paddle_table_cls
./TabCls/paddle_table_cls/PP-LCNet_x1_0_table_cls.onnx
./Layout
./Layout/YOLO
./Layout/YOLO/doclayout_yolo_docstructbench_imgsz1280_2501.pt
./OriCls
./OriCls/paddle_orientation_classification
./OriCls/paddle_orientation_classification/PP-LCNet_x1_0_doc_ori.onnx
./MFD
./MFD/YOLO
./MFD/YOLO/yolo_v8_ft.pt
# mineru调用的paddle模型是已经什么架构?是pytouch还是paddle自有文件格式,转换了吗?
从文件列表可以看到:
./OCR/paddleocr_torch/ch_PP-OCRv4_det_infer.pth
./OCR/paddleocr_torch/ch_PP-OCRv5_rec_infer.pth
# ... 等等
关键发现:
.pth (PyTorch 格式)paddleocr_torch(明确标注了 torch)查看 MinerU 的模型加载代码:
# mineru/model/ocr_rec/paddleocr_rec/paddleocr_rec.py
class RecPaddleOCRX:
def __init__(self, rec_model_path, lang=None):
# 加载 PyTorch 模型
self.model = torch.jit.load(rec_model_path) # 或者直接 torch.load
MinerU 使用的是 Paddle2ONNX → PyTorch 或 直接转换到 PyTorch 的模型:
graph LR
A[原始 PaddlePaddle 模型<br/>.pdparams + .pdmodel] --> B{转换方式}
B -->|方式1| C[Paddle2ONNX<br/>转换为 .onnx]
B -->|方式2| D[paddle2torch<br/>直接转 PyTorch]
C --> E[ONNX Runtime<br/>推理]
C --> F[ONNX → PyTorch<br/>转换为 .pth]
D --> G[PyTorch 模型<br/>.pth 文件]
F --> G
G --> H[MinerU 使用<br/>torch.load/jit.load]
E --> I[MinerU 使用<br/>onnxruntime]
style A fill:#ffe0b2
style G fill:#c8e6c9
style H fill:#bbdefb
| 模型类型 | 原始格式 | MinerU 使用格式 | 推理引擎 |
|---|---|---|---|
| OCR | .pdparams |
.pth (PyTorch) |
PyTorch |
| 表格分类 | .pdparams |
.onnx |
ONNX Runtime |
| 方向分类 | .pdparams |
.onnx |
ONNX Runtime |
| Layout检测 | - | .pt (YOLO原生) |
PyTorch |
| 公式识别 | - | .safetensors |
PyTorch |
查看 paddleocr_rec.py:
class RecPaddleOCRX:
def __init__(self, rec_model_path, ...):
# 加载 PyTorch 格式的模型
if rec_model_path.endswith('.pth'):
# PyTorch JIT 格式
self.model = torch.jit.load(rec_model_path, map_location=self.device)
else:
# 标准 PyTorch 格式
checkpoint = torch.load(rec_model_path, map_location=self.device)
self.model.load_state_dict(checkpoint)
查看 paddleocr_det.py:
class DetPaddleOCRX:
def __init__(self, det_model_path, ...):
# 同样加载 PyTorch 格式
self.model = torch.jit.load(det_model_path, map_location=self.device)
从文件列表还可以看到部分使用 ONNX:
./TabCls/paddle_table_cls/PP-LCNet_x1_0_table_cls.onnx
./OriCls/paddle_orientation_classification/PP-LCNet_x1_0_doc_ori.onnx
./TabRec/UnetStructure/unet.onnx
./TabRec/SlanetPlus/slanet-plus.onnx
这些使用 ONNX Runtime 推理:
# mineru/model/table/rec/slanet_plus/main.py
class RapidTableModel:
def __init__(self, model_path):
import onnxruntime as ort
self.session = ort.InferenceSession(
model_path,
providers=['CUDAExecutionProvider', 'CPUExecutionProvider']
)
MinerU 团队使用的转换工具可能包括:
Paddle2ONNX - 官方转换工具
paddle2onnx --model_dir paddle_model \
--model_filename model.pdmodel \
--params_filename model.pdiparams \
--save_file model.onnx
X2Paddle - Paddle 到其他框架的转换
x2paddle --framework=paddle \
--model=model.pdmodel \
--params=model.pdiparams \
--save_dir=pytorch_model \
--to_framework=pytorch
自定义转换脚本 - 直接映射权重
import paddle
import torch
# 加载 Paddle 模型
paddle_state_dict = paddle.load('model.pdparams')
# 转换为 PyTorch 格式
torch_state_dict = convert_paddle_to_torch(paddle_state_dict)
# 保存为 .pth
torch.save(torch_state_dict, 'model.pth')
| 特性 | 说明 |
|---|---|
| 原始格式 | PaddlePaddle (.pdparams + .pdmodel) |
| 转换后格式 | PyTorch (.pth) 或 ONNX (.onnx) |
| 推理引擎 | PyTorch / ONNX Runtime |
| 是否转换 | ✅ 已转换,不是原生 Paddle 格式 |
| 优势 | 统一推理引擎,无需安装 PaddlePaddle |
所以答案是:MinerU 使用的是已经转换为 PyTorch (.pth) 或 ONNX (.onnx) 格式的 PaddleOCR 模型,不是原生 Paddle 格式。