MinerU 深度评测:2026年最强开源PDF解析引擎,附完整代码实战
一、前言:为什么 PDF 解析是 AI 应用的"最后一公里"难题?
在大模型(LLM)与 RAG(检索增强生成)爆发的时代,如何把非结构化文档喂给 AI 已经成为工程落地的核心瓶颈。一个企业知识库里可能有成千上万份 PDF——学术论文、财务报告、产品手册、法律合同——这些文档中混杂着多栏排版、LaTeX 公式、复杂表格、嵌套图片、印章水印……
传统方案(PyMuPDF、pdfplumber、PDFMiner)在面对这类复杂 PDF 时,往往只能提取出乱序的文本流,公式变成乱码,表格结构全部丢失。
MinerU 的出现,正是为了彻底解决这个痛点。
MinerU 是由上海人工智能实验室 OpenDataLab 团队开发的开源高精度文档解析引擎,将非结构化文档(PDF、图片、Office 文件等)转换为机器可读的 Markdown 和 JSON,专为 LLM 预训练、RAG 和 Agent 工作流场景设计。
截至 2025 年,MinerU 在 GitHub 上已获得数万 Star,成为文档解析领域最受关注的开源项目之一。本文将从功能特性、安装配置、Python SDK 实战、性能评测四个维度,带你全面了解这款工具。
二、MinerU 核心功能一览
2.1 功能矩阵
MinerU 提供全面的文档解析能力,主要功能包括:
| 功能模块 | 支持能力 | 备注 |
|---|---|---|
| 版面分析 | 多栏排版、阅读顺序恢复 | 保留非正文元素(页眉页脚等) |
| 文字识别 | 中英文 OCR、竖排文字 | 印章文字识别 |
| 公式识别 | LaTeX 格式输出 | 行内/行间公式,含序号识别,准确率 92.5% |
| 表格解析 | 旋转表格、无边框/半边框表格 | 表格内图片/公式解析 |
| 图片提取 | 自动提取并关联上下文 | 支持图片描述生成 |
| 输出格式 | Markdown、JSON、PDF | 结构化输出,LLM 友好 |
| 多端部署 | 本地 CLI、Python SDK、在线 API、Docker、桌面客户端 | 全场景覆盖 |
2.2 最新版本亮点(MinerU 2.x)
最新版本重点强化了以下能力:
- ✅ 突破性公式解析:支持复杂长数学公式,准确识别中英文混合方程式
- ✅ 增强表格鲁棒性:轻松处理旋转表格、无边框表格、跨页表格
- ✅ 印章文字识别:专门针对中国文档中的圆形印章
- ✅ 竖排文本支持:兼容日文、古汉语等竖排排版
- ✅ 极低资源占用:在保持高精度的同时,大幅降低内存与算力消耗
三、安装与环境配置
3.1 环境要求
操作系统:Windows / Linux / macOS
Python:3.10 ~ 3.13
GPU(可选):8GB+ 显存(有 GPU 解析速度可提升 3~5x)
3.2 标准安装(推荐)
# 升级 pip
pip install --upgrade pip
# 安装 uv(更快的包管理器)
pip install uv
# 使用 pip 安装 MinerU
pip install mineru
或使用国内镜像加速:
pip install mineru -i https://mirrors.aliyun.com/pypi/simple
3.3 首次初始化(下载模型)
安装完成后,需要下载模型权重。执行以下命令,MinerU 会自动下载并配置 magic-pdf.json:
# 自动下载所有模型(含 OCR、公式、表格模型)
mineru-download-models
⚠️ 模型下载完成后,会在用户目录生成
~/magic-pdf.json配置文件,可通过MINERU_TOOLS_CONFIG_JSON环境变量指定自定义路径。
3.4 命令行快速体验
安装完成后,最快的方式是使用 CLI:
# 解析单个 PDF,输出到 output 目录
mineru -p your_document.pdf -o ./output
# 启用 OCR 模式(适合扫描版 PDF)
mineru -p your_document.pdf -o ./output --method ocr
# 关闭公式识别(加速处理纯文字文档)
mineru -p your_document.pdf -o ./output --formula false
四、Python SDK 完整实战
4.1 最简单的调用方式(新版 API)
MinerU 2.x 提供了极简的高层 API:
import mineru
# 方式一:直接调用顶层接口
result = mineru.parse("your_document.pdf")
# 输出 Markdown 内容
print(result.markdown)
# 输出 JSON 结构
import json
print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2))
4.2 基于 magic_pdf 的底层调用(精细控制)
对于需要精细控制解析过程的场景,可以使用 magic_pdf 核心库:
import os
import json
from pathlib import Path
from loguru import logger
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
def parse_pdf_to_markdown(pdf_path: str, output_dir: str) -> str:
"""
将 PDF 解析为 Markdown 格式
Args:
pdf_path: PDF 文件路径
output_dir: 输出目录
Returns:
Markdown 字符串
"""
# 创建输出目录
pdf_name = Path(pdf_path).stem
output_path = os.path.join(output_dir, pdf_name)
os.makedirs(output_path, exist_ok=True)
# 图片输出子目录
image_dir = os.path.join(output_path, "images")
os.makedirs(image_dir, exist_ok=True)
# 初始化读写器
writer = FileBasedDataWriter(output_path)
image_writer = FileBasedDataWriter(image_dir)
reader = FileBasedDataReader("")
# 读取 PDF 字节流
pdf_bytes = reader.read(pdf_path)
# 构建数据集对象
ds = PymuDocDataset(pdf_bytes)
# 执行文档分析(自动选择 OCR 或文字层解析)
infer_result = doc_analyze(ds, ocr=True)
# 选择解析方法(AUTO / TXT / OCR)
pipe_result = infer_result.pipe_ocr_mode(image_writer)
# 导出 Markdown
md_content = pipe_result.get_markdown(image_dir)
# 保存 Markdown 文件
md_path = os.path.join(output_path, f"{pdf_name}.md")
with open(md_path, "w", encoding="utf-8") as f:
f.write(md_content)
# 导出 JSON(含完整结构信息)
content_list = pipe_result.get_content_list(image_dir)
json_path = os.path.join(output_path, f"{pdf_name}_content.json")
with open(json_path, "w", encoding="utf-8") as f:
json.dump(content_list, f, ensure_ascii=False, indent=2)
logger.info(f"解析完成!Markdown: {md_path}")
return md_content
if __name__ == "__main__":
md = parse_pdf_to_markdown("paper.pdf", "./output")
print(md[:2000]) # 打印前 2000 字符预览
4.3 批量处理多个 PDF
import os
import glob
from concurrent.futures import ThreadPoolExecutor, as_completed
import mineru
def batch_parse(input_dir: str, output_dir: str, max_workers: int = 4):
"""
批量解析目录下所有 PDF
Args:
input_dir: 输入目录
output_dir: 输出目录
max_workers: 并发线程数
"""
pdf_files = glob.glob(os.path.join(input_dir, "**/*.pdf"), recursive=True)
print(f"共发现 {len(pdf_files)} 个 PDF 文件,开始批量解析...")
results = {}
failed = []
def parse_single(pdf_path):
try:
result = mineru.parse(pdf_path)
return pdf_path, result.markdown, None
except Exception as e:
return pdf_path, None, str(e)
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(parse_single, f): f for f in pdf_files}
for future in as_completed(futures):
pdf_path, markdown, error = future.result()
filename = os.path.basename(pdf_path)
if error:
print(f"❌ 失败:{filename} | 错误:{error}")
failed.append(pdf_path)
else:
print(f"✅ 成功:{filename} | 字符数:{len(markdown)}")
# 保存结果
out_path = os.path.join(output_dir, filename.replace(".pdf", ".md"))
with open(out_path, "w", encoding="utf-8") as f:
f.write(markdown)
results[pdf_path] = markdown
print(f"\n完成!成功:{len(results)} 个,失败:{len(failed)} 个")
return results
# 调用示例
batch_parse("./pdfs", "./output", max_workers=2)
4.4 与 LangChain / RAG 集成
MinerU 官方提供了 langchain-mineru 集成包,可以直接嵌入 LangChain 管道:
from langchain_mineru import MinerULoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
# 1. 使用 MinerU 加载并解析 PDF
loader = MinerULoader("research_paper.pdf")
documents = loader.load()
print(f"成功加载 {len(documents)} 个文档块")
print(f"首块内容预览:\n{documents[0].page_content[:500]}")
# 2. 文本分块
splitter = RecursiveCharacterTextSplitter(
chunk_size=512,
chunk_overlap=50
)
chunks = splitter.split_documents(documents)
print(f"分块后共 {len(chunks)} 个片段")
# 3. 构建向量库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
# 4. 相似度检索
query = "这篇论文的核心贡献是什么?"
relevant_docs = vectorstore.similarity_search(query, k=3)
for i, doc in enumerate(relevant_docs):
print(f"\n--- 相关片段 {i+1} ---")
print(doc.page_content)
五、性能评测:MinerU 在 OmniDocBench 上的表现
5.1 评测基准介绍
OmniDocBench 是目前最权威的 PDF 文档解析评测基准,由 OpenDataLab 团队在 CVPR 2025 发布。它涵盖:
- 📄 9 种文档类型:学术论文、教材、PPT、试卷、财务报告等
- 📊 评测维度:文字识别、公式识别、表格解析、版面分析
- 📐 评测指标:Edit Distance、BLEU、TEDS(表格)、CDM(公式)
5.2 MinerU 综合评测得分
MinerU2.5-Pro 在 OmniDocBench v1.6 上取得了 SOTA(当前最优) 成绩:
| 模型/工具 | OmniDocBench 综合得分 | 文字识别(英文 NED) | 公式识别(CDM) | 开源 |
|---|---|---|---|---|
| MinerU2.5-Pro | 95.69 | 0.061 | 高精度 | ✅ |
| MinerU2.5 (baseline) | 92.98 | 0.092 | 高精度 | ✅ |
| Mathpix | ~88 | 较好 | 优秀 | ❌(商业) |
| Docling | ~82 | 一般 | 较弱 | ✅ |
| Marker | ~80 | 一般 | 较弱 | ✅ |
| LlamaParse Agentic | 84.88 | 较好 | 较好 | ❌(商业) |
📌 关键数据:MinerU2.5-Pro 通过将训练数据从不足 1000 万样本扩展至 6550 万样本,在不修改任何模型架构的前提下,综合得分提升 2.71 分,超越所有现有方法(含商业工具)。
5.3 文字识别详细对比
根据 EulerAI 的深度评测报告,在 OmniDocBench 文字识别子任务上:
| 指标 | MinerU | Docling | Marker | Unstructured |
|---|---|---|---|---|
| 英文 NED(↓越低越好) | 0.061 | 0.142 | 0.118 | 0.203 |
| 中文 NED(↓越低越好) | 0.215 | 0.389 | 0.312 | 0.467 |
| 排名 | 🥇 第一 | 第三 | 第二 | 第四 |
MinerU 在英文和中文文字识别上均排名第一。
5.4 速度与资源消耗横向对比
基于社区实测数据(20 页学术 PDF,RTX 3090 环境):
| 工具 | 平均耗时 | GPU 显存占用 | CPU 模式 |
|---|---|---|---|
| MinerU(GPU) | 8.3s | ~6GB | 支持(慢 3-5x) |
| Docling | 12.1s | ~4GB | 支持 |
| Marker | 9.8s | ~5GB | 支持 |
| LlamaParse | ~5s(API) | N/A(云端) | N/A |
⚠️ 注:速度数据来自社区基准测试,实际结果因文档复杂度和硬件环境存在差异。
六、典型使用场景与最佳实践
6.1 场景一:学术论文批量转换(RAG 预处理)
import mineru
import os
def papers_to_rag_corpus(paper_dir: str, output_file: str):
"""将目录下所有论文 PDF 转为 RAG 语料库"""
corpus = []
for pdf in os.listdir(paper_dir):
if not pdf.endswith(".pdf"):
continue
try:
result = mineru.parse(os.path.join(paper_dir, pdf))
corpus.append({
"source": pdf,
"content": result.markdown,
"metadata": {
"chars": len(result.markdown),
"pages": result.page_count
}
})
print(f"✅ {pdf}: {result.page_count} 页,{len(result.markdown)} 字符")
except Exception as e:
print(f"❌ {pdf}: {e}")
import json
with open(output_file, "w", encoding="utf-8") as f:
json.dump(corpus, f, ensure_ascii=False, indent=2)
print(f"\n共处理 {len(corpus)} 篇论文 → {output_file}")
return corpus
6.2 场景二:财务报告关键信息提取
import mineru
import re
def extract_financial_tables(pdf_path: str) -> list:
"""从财务报告 PDF 中提取所有表格"""
result = mineru.parse(pdf_path)
# MinerU 输出的 Markdown 中,表格以标准 Markdown 表格格式呈现
# 使用正则提取所有表格块
table_pattern = r'(\|.+\|[\r\n]+(?:\|[-:| ]+\|[\r\n]+)(?:\|.+\|[\r\n]*)+)'
tables = re.findall(table_pattern, result.markdown)
print(f"共发现 {len(tables)} 个表格")
for i, table in enumerate(tables):
print(f"\n=== 表格 {i+1} ===")
print(table[:300]) # 预览前 300 字符
return tables
tables = extract_financial_tables("annual_report_2024.pdf")
6.3 场景三:数学论文公式提取
import mineru
import re
def extract_formulas(pdf_path: str) -> dict:
"""提取 PDF 中的所有 LaTeX 公式"""
result = mineru.parse(pdf_path)
markdown = result.markdown
# 提取行间公式(
$$ ... $$
)
block_formulas = re.findall(r'\$\$(.*?)\$\$', markdown, re.DOTALL)
# 提取行内公式($...$)
inline_formulas = re.findall(r'(?<!\$)\$(?!\$)(.*?)(?<!\$)\$(?!\$)', markdown)
print(f"行间公式:{len(block_formulas)} 个")
print(f"行内公式:{len(inline_formulas)} 个")
# 打印前 5 个行间公式
for i, formula in enumerate(block_formulas[:5]):
print(f"\n公式 {i+1}:\n
$$ {formula.strip()} $$
")
return {
"block_formulas": block_formulas,
"inline_formulas": inline_formulas
}
formulas = extract_formulas("math_paper.pdf")
七、与竞品的综合对比
7.1 MinerU vs 主流方案对比表
| 维度 | MinerU | Docling | Marker | LlamaParse | PyMuPDF |
|---|---|---|---|---|---|
| 开源免费 | ✅ | ✅ | ✅ | ❌(收费) | ✅ |
| 公式识别(LaTeX) | ✅ 优秀 | ⚠️ 较弱 | ⚠️ 较弱 | ✅ 较好 | ❌ |
| 复杂表格 | ✅ 优秀 | ✅ 较好 | ⚠️ 一般 | ✅ 优秀 | ❌ |
| 中文支持 | ✅ 原生 | ⚠️ 有限 | ⚠️ 有限 | ✅ 支持 | ⚠️ 基础 |
| OmniDocBench 得分 | 95.69 | ~82 | ~80 | 84.88 | N/A |
| 本地部署 | ✅ | ✅ | ✅ | ❌ | ✅ |
| Python SDK | ✅ | ✅ | ✅ | ✅ | ✅ |
| MCP 协议支持 | ✅ | ❌ | ❌ | ❌ | ❌ |
| LangChain 集成 | ✅ 官方 | ✅ | ❌ | ✅ 官方 | ⚠️ 社区 |
7.2 选型建议
📌 优先选择 MinerU,当你需要:
✅ 处理含大量公式的学术论文
✅ 解析中文复杂排版文档
✅ 构建企业私有化 RAG 系统(不能用云端 API)
✅ 需要高精度表格识别
✅ 预算有限,必须开源免费
📌 考虑其他方案,当你需要:
→ 极致处理速度、对精度要求不高 → Marker
→ 极简集成 LlamaIndex → LlamaParse
→ 仅做基础文字提取 → PyMuPDF
八、常见问题与解决方案
Q1:解析速度很慢怎么办?
# 确认是否在使用 CPU 模式,建议切换到 GPU
# 检查设备配置
python -c "import torch; print(torch.cuda.is_available())"
# 若无 GPU,可关闭公式和表格识别来加速
mineru -p doc.pdf -o output --formula false --table false
Q2:中文乱码或识别错误?
# 确保使用最新版本(2.x 对中文支持大幅改善)
pip install --upgrade mineru
# 对扫描版中文 PDF,显式启用 OCR 模式
result = mineru.parse("chinese_doc.pdf", method="ocr")
Q3:表格无法正确识别?
# 确认 table 功能已开启(默认开启)
result = mineru.parse("doc.pdf", table=True)
# 查看 JSON 输出中的表格结构
for block in result.to_dict()["content"]:
if block["type"] == "table":
print(block["table_body"])
九、总结
MinerU 已经从一个实验性工具成长为工业级文档解析引擎。在 OmniDocBench v1.6 上以 95.69 分的 SOTA 成绩证明了自身实力,在中英文文字识别上均排名第一,同时完全开源、支持本地部署、拥有完整的 Python SDK 与 LangChain 集成生态。
核心优势总结
| 🏆 领先优势 | 📊 量化数据 |
|---|---|
| 综合解析精度 | OmniDocBench 95.69 分,全球 SOTA |
| 英文文字识别 | NED 仅 0.061,排名第一 |
| 公式识别准确率 | 92.5%,支持 LaTeX 输出 |
| 训练数据规模 | 6550 万样本,持续迭代 |
| 开源协议 | Apache 2.0,商用友好 |
如果你正在构建 RAG 系统、LLM 训练语料管道、或者只是需要一个靠谱的 PDF 转 Markdown 工具,MinerU 是目前开源领域毫无疑问的首选。
📎 项目地址:https://github.com/opendatalab/MinerU
📎 在线体验:https://mineru.net
📎 技术报告:https://arxiv.org/abs/2604.04771
如果本文对你有帮助,欢迎点赞收藏!有任何问题欢迎在评论区留言交流 🙌
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)