微信扫码
添加专属顾问
我要投稿
探索MinerU最新版本v1.3.10文档解析的内部机制核心内容:1. MinerU更新频率及版本概述2. 环境准备与magic-pdf安装升级3. MinerU文档解析步骤详细拆解
MinerU更新频率也相当频繁,在短短一个月内,更新了10个小版本。
本文结合最新版本v1.3.10
,深入拆解下它进行文档解析时的内部操作细节。
MinerU仓库地址:https://github.com/opendatalab/MinerU
在之前的文章中,已经安装了magic-pdf
(MinerU的解析包名),先通过以下的命令进行升级。
pip install magic-pdf --upgrade
如果是第一次安装,不需要加--upgrade
参数:
pip install magic-pdf
下面根据官方提供的运行示例,一步步拆解具体的流程。
import os
# 导入必要的模块和类
from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader
from magic_pdf.data.dataset import PymuDocDataset
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.config.enums import SupportedPdfParseMethod
# 参数设置
pdf_file_name = "file.pdf"# 要处理的PDF文件路径,使用时替换为实际路径
name_without_suff = pdf_file_name.split(".")[0] # 去除文件扩展名
# 准备环境
local_image_dir, local_md_dir = "output/images", "output"# 图片和输出目录
image_dir = str(os.path.basename(local_image_dir)) # 获取图片目录名
# 创建输出目录(如果不存在)
os.makedirs(local_image_dir, exist_ok=True)
# 初始化数据写入器
image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
local_md_dir
)
# 读取PDF文件内容
reader1 = FileBasedDataReader("") # 初始化数据读取器
pdf_bytes = reader1.read(pdf_file_name) # 读取PDF文件内容为字节流
# 处理流程
## 创建PDF数据集实例
ds = PymuDocDataset(pdf_bytes) # 使用PDF字节流初始化数据集
## 推理阶段
if ds.classify() == SupportedPdfParseMethod.OCR:
# 如果是OCR类型的PDF(扫描件/图片型PDF)
infer_result = ds.apply(doc_analyze, ocr=True) # 应用OCR模式的分析
## 处理管道
pipe_result = infer_result.pipe_ocr_mode(image_writer) # OCR模式的处理管道
else:
# 如果是文本型PDF
infer_result = ds.apply(doc_analyze, ocr=False) # 应用普通文本模式的分析
## 处理管道
pipe_result = infer_result.pipe_txt_mode(image_writer) # 文本模式的处理管道
### 绘制模型分析结果到每页PDF
infer_result.draw_model(os.path.join(local_md_dir, f"{name_without_suff}_model.pdf"))
### 获取模型推理结果
model_inference_result = infer_result.get_infer_res()
### 绘制布局分析结果到每页PDF
pipe_result.draw_layout(os.path.join(local_md_dir, f"{name_without_suff}_layout.pdf"))
### 绘制文本块(span)分析结果到每页PDF
pipe_result.draw_span(os.path.join(local_md_dir, f"{name_without_suff}_spans.pdf"))
### 获取Markdown格式的内容
md_content = pipe_result.get_markdown(image_dir) # 包含图片相对路径
### 保存Markdown文件
pipe_result.dump_md(md_writer, f"{name_without_suff}.md", image_dir)
### 获取内容列表(JSON格式)
content_list_content = pipe_result.get_content_list(image_dir)
### 保存内容列表到JSON文件
pipe_result.dump_content_list(md_writer, f"{name_without_suff}_content_list.json", image_dir)
### 获取中间JSON格式数据
middle_json_content = pipe_result.get_middle_json()
### 保存中间JSON数据
pipe_result.dump_middle_json(md_writer, f'{name_without_suff}_middle.json')
调用:magic_pdf\data\data_reader_writer\filebase.py
中FileBasedDataReader
的read_at
方法
def read_at(self, path: str, offset: int = 0, limit: int = -1) -> bytes:
"""Read at offset and limit.
Args:
path (str): the path of file, if the path is relative path, it will be joined with parent_dir.
offset (int, optional): the number of bytes skipped. Defaults to 0.
limit (int, optional): the length of bytes want to read. Defaults to -1.
Returns:
bytes: the content of file
"""
fn_path = path
if not os.path.isabs(fn_path) and len(self._parent_dir) > 0:
fn_path = os.path.join(self._parent_dir, path)
with open(fn_path, 'rb') as f:
f.seek(offset)
if limit == -1:
return f.read()
else:
return f.read(limit)
可设定offset
和limit
两个参数:
默认读取文件所有内容,以二进制形式读取,直接加载进内存。
如果文件特别大,可以考虑用这两个参数做分批读取。
对于PDF文件,进一步判断是图片型PDF(扫描件)还是文本型PDF。
具体判断逻辑在magic_pdf\filter\pdf_classify_by_type.py
的classify
函数:
def classify(total_page: int, page_width, page_height, img_sz_list: list, text_len_list: list, img_num_list: list,
# text_layout_list: list,
invalid_chars: bool):
results = {
'by_image_area': classify_by_area(total_page, page_width, page_height, img_sz_list, text_len_list),
'by_text_len': classify_by_text_len(text_len_list, total_page),
'by_avg_words': classify_by_avg_words(text_len_list),
'by_img_num': classify_by_img_num(img_sz_list, img_num_list),
# 'by_text_layout': classify_by_text_layout(text_layout_list),
'by_img_narrow_strips': classify_by_img_narrow_strips(page_width, page_height, img_sz_list),
'by_invalid_chars': invalid_chars,
}
这里进行了多方面的判断,具体方式如下:
最后,综合这6个条件,如果这6个条件都为True,即判定文件是文本型的PDF,有任意条件不通过,则判定文件为图片型PDF。
在正式处理前,需要先指定运行设备。
首先需要读取配置文件,相关代码在MinerU\magic_pdf\libs\config_reader.py
# 定义配置文件名常量
CONFIG_FILE_NAME = os.getenv('MINERU_TOOLS_CONFIG_JSON', 'magic-pdf.json')
def read_config():
if os.path.isabs(CONFIG_FILE_NAME):
config_file = CONFIG_FILE_NAME
else:
home_dir = os.path.expanduser('~')
config_file = os.path.join(home_dir, CONFIG_FILE_NAME)
ifnot os.path.exists(config_file):
raise FileNotFoundError(f'{config_file} not found')
with open(config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
return config
该代码表明,它会根据系统环境变量MINERU_TOOLS_CONFIG_JSON
去查找json的配置文件。
如果未设置此环境变量,默认会到用户家目录下,寻找magic-pdf.json
这个文件。
该文件中,device-mode
设定了模型运行的设备,有cpu
、cuda
、npu
三种模式进行选择(如果填入值非这三类,视作cpu)。
如果选择了cuda
或npu
,会自动计算显存容量,并自适应调节batch_ratio
,具体调节规则如下:
if gpu_memory >= 16:
batch_ratio = 16
elif gpu_memory >= 12:
batch_ratio = 8
elif gpu_memory >= 8:
batch_ratio = 4
elif gpu_memory >= 6:
batch_ratio = 2
else:
batch_ratio = 1
对于CPU设备,batch_ratio
默认设为1。
顺带一提,在配置文件中,无法显性指定多卡同时解析,如有多卡解析的需求,可参考仓库中基于 LitServe 的多 GPU 并行处理方案。
文件地址: https://github.com/opendatalab/MinerU/tree/master/projects/multi_gpu
具体的处理流程在magic_pdf\model\batch_analyze.py
。
图片型PDF会比文本型PDF多一个OCR处理的步骤,其它步骤一致。
布局分析提供了两套模型可供选择:layoutlmv3
和doclayout_yolo
,默认采用后者。
doclayout_yolo
也是MinerU所在组织OpenDataLab的研究成果。
仓库地址:https://github.com/opendatalab/DocLayout-YOLO
该算法是基于YOLO-v10
对文件布局标记的数据集D4LA
和DocSynth300K
进行训练,从而检测出不同的布局信息。
数据集包含的文档布局示例如下:
公式处理包含两个阶段:公式检测(MFD) 和 公式识别(MFR) 。
公式检测是指检测出公式所在位置,采用yolo_v8_mfd
算法,未找到该算法的详细介绍,根据揣测是采用yolov8
算法,在公式块标记的相关数据集上进行训练得到。
公式识别是指在得到公式区域的基础上,识别其中的具体内容,将其中的数学表达式图像转换为 LaTeX 语言,具体算法采用unimernet
算法。
该算法也是OpenDataLab的自研算法。
仓库地址:https://github.com/opendatalab/UniMERNet
考虑到并不是所有的PDF文件中都有公式,因此,可以在配置文件中,将其关闭。默认的"enable"
设置为开启状态,如需关闭公式处理,设为false
。
"formula-config": {
"mfd_model": "yolo_v8_mfd",
"mfr_model": "unimernet_small",
"enable": true
},
OCR是指将图像区域内容识别成文本,和公式处理类似,同样包含区域检测和区域识别两个阶段。
这两个阶段均是使用百度的PaddleOCR,该算法原生使用的PaddlePaddle框架,这里使用了pytorch的实现版本。
在这个文件magic_pdf\model\sub_modules\ocr\paddleocr2pytorch\pytorch_paddle.py
中,有一个测试样例。
对于不同的语言进行OCR,需要使用不同的模型,在magic_pdf\model\sub_modules\ocr\paddleocr2pytorch\pytorchocr\utils\resources\models_config.yml
这个配置文件,规定了不同语言所对应的采取的不同模型。
对于中文文本,检测模型使用ch_PP-OCRv3_det_infer
,识别模型采用ch_PP-OCRv4_rec_infer
。
在下载模型时,会将所有常见语言(中文、英文、日文、拉丁文等语言)的模型一次性下载下来,每个模型体积不大,基本在10-20MB左右。
表格识别包含两个部分:表格文本识别和表格结构识别。
表格文本识别默认采用rapid_table
这个依赖库,底层同样使用的是PaddleOCR,用来识别表格中的文本内容。
表格结构识别默认采用slanet_plus
算法,用来识别表格结构。
该部分代码来自RapidTable这个仓库。
仓库地址:https://github.com/RapidAI/RapidTable
表格识别同样可以在配置文件中自由选择关闭,和公式处理一样,通过enable
参数来控制开启和关闭。
"table-config": {
"model": "rapid_table",
"sub_model": "slanet_plus",
"enable": true,
"max_time": 400
},
最后可输出结果包括:
具体的相关接口参见magic_pdf\operators\pipes.py
由于MinerU是针对PDF进行解析,因此本身的处理管道并不能处理其它格式的文件。
在v1.0.1
版本后,进一步支持图像(.jpg及.png)、Word(.doc及.docx)、以及PPT(.ppt及.pptx)三类文件的解析。
对于 MS-Office 文件,需要通过 LibreOffice 将其转换成 PDF文件,再复用PDF的解析管道。(本地使用时,需要提前安装LibreOffice,并设置相应环境变量)
python示例脚本如下:
import os
from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.data.read_api import read_local_office
# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))
os.makedirs(local_image_dir, exist_ok=True)
image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
local_md_dir
)
# proc
## Create Dataset Instance
input_file = "demo.pptx" # replace with real ms-office file
input_file_name = input_file.split(".")[0]
ds = read_local_office(input_file)[0]
infer_result = ds.apply(doc_analyze, ocr=True)
## 处理管道
pipe_result = infer_result.pipe_ocr_mode(image_writer)
pipe_result.dump_md(md_writer, f"{input_file_name}.md", image_dir)
### 获取内容列表(JSON格式)
content_list_content = pipe_result.get_content_list(image_dir)
### 保存内容列表到JSON文件
pipe_result.dump_content_list(md_writer, f"{input_file_name}_content_list.json", image_dir)
### 获取中间JSON格式数据
middle_json_content = pipe_result.get_middle_json()
### 保存中间JSON数据
pipe_result.dump_middle_json(md_writer, f'{input_file_name}_middle.json')
具体转换过程在magic_pdf\data\read_api.py
文件的read_local_office
方法。
考虑到Excel文件也属于MS-Office
文件,因此,拿excel文件试了一下,发现也能正常跑通,只是会将整张表格内容变成一个html的格式,没有自动将每行内容区分开。
另外,拿这个脚本试了下.txt
和.md
文件,发现也能正常使用,后面可以直接借此拓展RagflowPlus的文件支持形式。
对于图片文件,无需转换成pdf,原本的管道可兼容,示例python脚本如下:
import os
from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader
from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze
from magic_pdf.data.read_api import read_local_images
# prepare env
local_image_dir, local_md_dir = "output/images", "output"
image_dir = str(os.path.basename(local_image_dir))
os.makedirs(local_image_dir, exist_ok=True)
image_writer, md_writer = FileBasedDataWriter(local_image_dir), FileBasedDataWriter(
local_md_dir
)
# proc
## Create Dataset Instance
input_file = "demo.jpg" # replace with real image file
input_file_name = input_file.split(".")[0]
ds = read_local_images(input_file)[0]
infer_result = ds.apply(doc_analyze, ocr=True)
## 处理管道
pipe_result = infer_result.pipe_ocr_mode(image_writer)
pipe_result.dump_md(md_writer, f"{input_file_name}.md", image_dir)
### 获取内容列表(JSON格式)
content_list_content = pipe_result.get_content_list(image_dir)
### 保存内容列表到JSON文件
pipe_result.dump_content_list(md_writer, f"{input_file_name}_content_list.json", image_dir)
### 获取中间JSON格式数据
middle_json_content = pipe_result.get_middle_json()
### 保存中间JSON数据
pipe_result.dump_middle_json(md_writer, f'{input_file_name}_middle.json')
查看源代码时,发现了MinerU
实际上复用了很多PDF-Extract-Kit
的代码。
MinerU
更多的是工程上的整合,如需更细致地挖掘某个步骤,可参考同属opendatalab的PDF-Extract-Kit
这个仓库。
仓库地址:https://github.com/opendatalab/PDF-Extract-Kit
参考文档:https://pdf-extract-kit.readthedocs.io/zh-cn/latest/task_extend/code.html
大模型原理知识相关
1.DeepSeek-R1各版本模型推理显存需求测算" data-itemshowtype="0" target="_blank" linktype="text" data-linktype="2">DeepSeek-R1各版本模型推理显存需求测算
4.如何正确评估DeepSeek-R1各版本所需推理显存?KV Cache原理和显存计算解析
7.MCP:从理论到实践" data-itemshowtype="0" target="_blank" linktype="text" data-linktype="2">MCP:从理论到实践
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-05-19
3小时开发健身小程序!腾讯新神器CodeBuddy 3.0真实测评
2025-05-19
如何利用 AI 工具生成精美的 Mermaid 图表
2025-05-19
ChatGPT 是个好名字
2025-05-19
我们和中欧国际工商学院一起,撰写了这份AI商业创新报告!
2025-05-19
Cherry Studio v1.3.5新功能解读
2025-05-19
AI编程最佳实践:打造更出色软件的核心策略
2025-05-19
用AI重新定义编程效率!Trae新版本深度评测+保姆级教程来了
2025-05-19
独家对话 Lovart 创始人陈冕:我们没有产品经理,只有设计师
2025-03-06
2024-09-04
2025-01-25
2024-09-26
2024-10-30
2024-09-03
2025-03-12
2024-12-11
2024-12-25
2025-02-18
2025-05-14
2025-05-06
2025-04-29
2025-04-25
2025-04-22
2025-04-16
2025-04-15
2025-04-13