MinerU源码解析

流程

17417456605061741745659776.png

流程图 mermaid 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

graph TD
A[启动命令 magic-pdf] --> B{文件类型判断}
B --> |MS Office| C[convert_file_to_pdf]
B --> |Image| D[fitz转PDF]
B --> |PDF| E[直接读取]
C --> F[parse_doc]
D --> F
E --> F
F --> G[调用read_fn转换]
G --> H[调用do_parse解析]
H --> I{用户指定页面?}
I --> |是| J[convert_pdf_bytes_to_bytes_by_pymupdf]
I --> |否| K[prepare_env创建目录]
J --> K
K --> L[初始化PymuDocDataset]
L --> M{model_list为空?}
M --> |是| N[选择解析模式]
N --> O[doc_analyze]
O --> P{文本模式?}
P --> |是| Q[pipe_txt_mode]
P --> |否| R[pipe_ocr_mode]
Q --> S[获取模型实例]
R --> S
S --> T[检查NPU/GPU]
T --> U[设置batch_ratio]
U --> V[BatchAnalyze初始化]
V --> W{支持批处理?}
W --> |是| X[批量处理图像]
W --> |否| Y[逐页处理]
X --> Z[布局模型判断]
Z --> |LayoutLMv3| AA[逐个处理]
Z --> |DocLayout_YOLO| AB[批量处理]
AA --> AC[公式检测]
AB --> AC
AC --> AD[公式识别]
AD --> AE[合并布局结果]
AE --> AF[OCR识别]
AF --> AG[表格识别]
AG --> AH[返回InferenceResult]
Y --> AH
M --> |否| AI[初始化InferenceResult]
AI --> AJ[选择解析模式]
AJ --> AK[后续结果处理]
AH --> AK
AK --> AL{绘制边界框?}
AL --> |是| AM[draw_model/draw_layout等]
AL --> |否| AN[导出文件]
AN --> AO[导出Markdown]
AN --> AP[导出JSON]
AN --> AQ[导出PDF]
AN --> AR[导出内容列表]

style A fill:#4CAF50,stroke:#388E3C
style B fill:#FFC107,stroke:#FFA000
style O fill:#2196F3,stroke:#1976D2
style AK fill:#9C27B0,stroke:#7B1FA2

文字版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
1. 启动命令 magic-pdf -p /data/pdf/text.pdf -o /data/pdf/result -m auto 
2. 根据文件后缀判断文件类型。如果是 Microsoft Office 文件,使用 convert_file_to_pdf 函数将其转换为 PDF。如果是图像文件,使用 fitz 库将其转换为 PDF。如果是 PDF 文件,直接读取。
3. parse_doc 中调用 read_fn(做转换) 和 do_parse(解析入口)
4. 用户可以选择处理某些页面的数据,这里调用 convert_pdf_bytes_to_bytes_by_pymupdf 将 PDF 字节数据转换为指定页范围的字节数据(可以指定只处理某些页)
5. 调用 prepare_env 函数,创建输出目录结构,返回图像和 Markdown 目录路径。
6. 使用 PymuDocDataset 初始化数据集对象 ds,用于后续的解析。
7. 如果 model_list 为空且使用内部模型(model_list 其实为之前的解析结果,只是了方便调试使用),根据 parse_method 和数据集分类结果选择解析模式。
7.1 具体解析逻辑在 doc_analyze 中进行
7.1.1 如果分类为文本模式,调用 pipe_txt_mode 进行文本解析
7.1.2 否则,调用 pipe_ocr_mode 进行 OCR 解析。

7.1.3 使用 ModelSingleton 获取自定义模型实例(get_model 方法会根据是否启用 OCR,是否显示日志,语言设置,布局模型,是否启用公式识别,是否启用表格识别 来载入一组模型,主要是两大类,CustomPaddleModel 和 CustomPEKModel,然后在里面根据配置载入 ocr 模型,公式模型,表格模型等)。
7.1.4 检查设备是否支持 NPU(神经网络处理单元)或 GPU。
7.1.5 根据 GPU 内存大小设置批处理比例 batch_ratio,并初始化 BatchAnalyze 对象。判断是否启用批处理分析

7.1.6 如果支持批处理,则调用 BatchAnalyze 进行分析
7.1.7 BatchAnalyze 中会处理每一个图像(每一个页面)
7.1.7.1 如果当前 layout 模型是 LAYOUTLMv3,则逐个处理图像
7.1.7.2 如果当前 layout 模型是 DocLayout_YOLO,批量处理图像。
7.1.7.3 如果启用公式检测,首先进行公式检测,然后进行公式识别, 将识别结果合并到布局结果中。
7.1.7.4 调用 get_res_list_from_layout_res 得到每页需要进行 ocr 识别的列表(category_id 是 0, 1, 2, 4, 6, 或 7), table 识别的列表(category_id 是 5), 公式识别的列表(category_id 是 13 或 14)
7.1.7.4.1 进行 OCR 识别
7.1.7.4.2 表格识别
7.1.7.4.3 返回识别结果 images_layout_res
7.1.7.5 返回包含分析结果的 InferenceResult 对象。
7.1.8 如果未启用批处理分析,逐页分析并记录结果
7.2 后续结果处理


8. 否则如果提供了 model_list(model_list 其实为之前的解析结果,只是了方便调试使用) ,则初始化 InferenceResult 对象, 根据 parse_method 和数据集分类结果选择解析模式。
9. 后续结果处理
9.1 如果启用绘制模型边界框,调用 draw_model 方法生成模型边界框 PDF
9.2 如果启用绘制布局边界框,调用 draw_layout 方法生成布局边界框 PDF。
9.3 如果启用绘制跨度边界框,调用 draw_span 方法生成跨度边界框 PDF。
9.4 如果启用绘制行排序边界框,调用 draw_line_sort 方法生成行排序边界框 PDF。
9.5 如果启用绘制字符边界框,调用 draw_char_bbox 函数生成字符边界框 PDF。
9.6 如果启用导出 Markdown,调用 dump_md 方法生成 Markdown 文件。
9.7 如果启用导出中间 JSON,调用 dump_middle_json 方法生成中间 JSON 文件。
9.8 如果启用导出模型 JSON,调用 dump_model 方法生成模型 JSON 文件。
9.9 如果启用导出原始 PDF,调用 write 方法将原始 PDF 字节数据写入文件。
9.10 如果启用导出内容列表,调用 dump_content_list 方法生成内容列表 JSON 文件。


如何区分模式,是使用 classify 方法进行区分
分析 PDF 文件的字节数据,提取出一系列元信息,包括加密状态、页面尺寸、图像和文本信息、语言、无效字符等。
几个维度来评价:是否加密,是否需要密码,纸张大小,总页数,是否文字可提取