MinerU 2.x는 패키지명(magic-pdf→mineru), PyMuPDF 제거, VLM/Hybrid 백엔드 추가 등 대규모 변경을 거쳤다. Pipeline 백엔드 기준으로 DocLayout-YOLO(YOLOv10)→YOLOv8 MFD→UniMERNet→SLANET+/UNet→PytorchPaddleOCR 순서로 파싱이 진행된다. Apple Silicon MPS 가속 테스트 결과 CPU 대비 약 37% 빠른 처리 속도를 확인했다.
들어가며
약 1년 전 MinerU에 대한 글을 쓴 적이 있다. 당시에는 magic-pdf라는 패키지명으로 PyMuPDF에 의존하고 있었고, Pipeline 백엔드만 존재했다. 그 사이 MinerU는 v2.0에서 대규모 브레이킹 체인지를 거쳐 현재 v2.7.6까지 왔다. RAG-Anything의 핵심 파서로도 사용되고 있어, 내부 파이프라인을 제대로 파악해둘 필요가 있었다.
이 글에서는 MinerU 2.7.6 소스코드를 직접 분석한 결과를 정리하고, Apple Silicon(M시리즈) 환경에서 CPU vs MPS 성능을 실측 비교한다.
1.x → 2.x 주요 변경사항
MinerU는 v2.0에서 근본적인 변화를 겪었다. 단순한 기능 추가가 아니라 패키지명, CLI, 의존성, 아키텍처 전반이 바뀌었다.
Breaking Changes (v2.0)
| 항목 | 이전 (1.x) | 현재 (2.x) |
|---|---|---|
| 패키지명 | magic-pdf | mineru |
| CLI 명령어 | magic-pdf convert | mineru -p <input> -o <output> |
| Python import | from magic_pdf import ... | from mineru.cli.common import ... |
| 설치 | pip install "magic-pdf[full]" | uv pip install "mineru[all]" |
| PyMuPDF | 핵심 의존성 (AGPL) | 완전 제거 |
| PDF 처리 | PyMuPDF (fitz) | pypdfium2 + pypdf + pdfminer.six |
| 기본 백엔드 | pipeline (유일) | hybrid-auto-engine |
주요 마일스톤
- v2.0.0 (2025): PyMuPDF 완전 제거, 패키지명 변경
- v2.5.0: MinerU 2.5 모델 출시 (1.2B 파라미터, GPT-4o/Gemini 2.5 Pro 벤치마크 능가)
- v2.7.0 (2026.01): Hybrid 백엔드 추가, 기본 백엔드 변경, 설치 간소화
라이선스 상황
이전 글에서 "PyMuPDF 때문에 AGPL"이라고 썼는데, PyMuPDF가 제거되면서 AGPL의 원인은 YOLO 코드(DocLayout-YOLO, ultralytics) 만 남았다. 여전히 AGPL-3.0이지만, PyMuPDF 의존성은 해소된 상태다.
3가지 백엔드 아키텍처
MinerU 2.7부터는 3가지 백엔드를 선택할 수 있다.
Pipeline 백엔드
전통적인 다단계 파이프라인. 각 단계별로 전용 모델이 처리한다.
PDF → 이미지 변환 → 레이아웃 감지 → 수식 감지 → 수식 인식
→ 테이블 분류/인식
→ OCR
→ 후처리 → Markdown/JSON
- 장점: 가장 상세하고 정밀한 구조 추출, CPU에서도 동작
- 단점: 모델이 많아 메모리 사용량이 큼
- 디바이스: cpu, cuda, mps, npu
VLM 백엔드
Qwen2VL 같은 비전 언어 모델 하나로 전체를 처리한다.
- 장점: 단일 모델, 단순한 구조
- 단점: GPU/VLM 서버 필요, 단순 PDF에 적합
- 엔진: transformers, vLLM, LMDeploy, MLX(Apple Silicon), HTTP client
Hybrid 백엔드 (기본값)
VLM으로 먼저 처리하고, 부족한 부분만 Pipeline 모델로 보완한다.
- 장점: 속도와 정확도의 균형
- 단점: VLM + Pipeline 모두 필요
- v2.7.0부터 기본값:
hybrid-auto-engine
# 백엔드 선택 예시
mineru -p input.pdf -o output/ -b pipeline # Pipeline만 사용
mineru -p input.pdf -o output/ -b vlm-auto-engine # VLM만 사용
mineru -p input.pdf -o output/ # Hybrid (기본)Pipeline 백엔드 상세 파이프라인
Pipeline 백엔드의 내부 흐름을 소스코드 기반으로 분석했다. 이하 분석은 MinerU v2.7.6 기준이다.
전체 흐름
1. PDF → 이미지 변환 (pypdfium2, 200 DPI)
2. DocLayout-YOLO (YOLOv10) → 레이아웃 감지
3. YOLOv8 MFD → 수식 영역 감지
4. UniMERNet → 수식 인식 (LaTeX)
5. PP-LCNet → 테이블 분류 (유선/무선)
6. SLANET+ / UNet → 테이블 구조 인식 → HTML
7. PytorchPaddleOCR → 텍스트 인식
8. 후처리 → Markdown + JSON 출력
Step 1: PDF → 이미지 변환
pypdfium2를 사용하여 PDF 각 페이지를 200 DPI PIL Image로 변환한다. 멀티스레딩을 지원하며, PyMuPDF를 대체한 핵심 변경점이다.
Step 2: 레이아웃 감지 — DocLayout-YOLO (YOLOv10)
모델: doclayout_yolo_docstructbench_imgsz1280_2501.pt
입력: 1280×1280px 리사이즈
Confidence: 0.1 / IoU: 0.45
문서의 각 영역을 카테고리별로 감지한다:
| Category ID | 이름 | 용도 |
|---|---|---|
| 0 | Title | 제목/헤딩 |
| 1 | Text | 본문 텍스트 |
| 2 | Abandon | 헤더/푸터 등 불필요 영역 |
| 3 | ImageBody | 이미지 본체 |
| 4 | ImageCaption | 이미지 캡션 |
| 5 | TableBody | 테이블 본체 |
| 6 | TableCaption | 테이블 캡션 |
| 7 | TableFootnote | 테이블 각주 |
| 8 | InterlineEquation | 행간 수식 (레이아웃 모델) |
| 13 | InlineEquation | 인라인 수식 (MFD) |
| 14 | InterlineEquation | 행간 수식 (MFD) |
| 101 | ImageFootnote | 이미지 각주 |
아래는 실제 레이아웃 감지 결과다. 각 영역이 색상별로 구분되어 있다:


Step 3: 수식 감지 — YOLOv8 MFD
모델: yolo_v8_ft.pt
입력: 1888×1888px (레이아웃보다 큰 해상도)
Confidence: 0.25 / IoU: 0.45
레이아웃 감지와 별도로 수식 전용 감지를 수행한다:
- Class 0: 인라인 수식 ( 같은)
- Class 1: 디스플레이 수식 (독립 행의 큰 수식)
Step 4: 수식 인식 — UniMERNet
모델: unimernet_small (Vision Encoder-Decoder)
- Encoder: UnimerSwin (Swin Transformer 변형)
- Decoder: UnimerMBART (mBART 변형)
- 출력: LaTeX 문자열
감지된 수식 영역의 이미지를 받아 LaTeX 코드로 변환한다. 이번 테스트에서 18페이지 논문에서 77개의 수식이 감지·인식되었다.
중국어 수식이 많은 문서의 경우, 환경변수
MINERU_FORMULA_CH_SUPPORT=True로 PP-FormulaNet-Plus-M 모델로 전환할 수 있다.
Step 5: 테이블 분류 — PP-LCNet
모델: PP-LCNet_x1_0_table_cls.onnx
감지된 테이블을 두 가지로 분류한다:
- Wireless (무선): 선 없는 테이블 → SLANET+ 처리
- Wired (유선): 선 있는 테이블 → UNet 처리
Wireless 점수가 0.9 미만이면 Wired로도 처리하여 더 나은 결과를 선택한다.
Step 6: 테이블 구조 인식
무선 테이블 → SLANET+ (slanet-plus.onnx)
rapid_table 라이브러리를 사용한다:
- 구조 토큰 생성 (
<tr>,<td>등) - OCR 텍스트와 IoU 기반 매칭
- HTML 테이블 생성
유선 테이블 → UNet (unet.onnx)
형태학적 연산으로 선을 감지한다:
- 수평/수직선 감지
- 셀 구조 복원
- HTML 테이블 생성
하이브리드 선택: 두 모델 결과의 셀 수, 텍스트 커버리지를 비교하여 더 나은 쪽을 자동 채택한다.
Step 7: OCR — PytorchPaddleOCR
PaddleOCR의 PyTorch 재구현이다 (원래 PaddlePaddle 프레임워크가 아님).
- 2단계: 텍스트 감지(DET) → 텍스트 인식(REC)
- 109개 이상 언어 지원
- 회전 텍스트, 박스 병합/필터링 포함
Step 8: 후처리 및 출력
최종 출력 파일:
| 파일 | 설명 |
|---|---|
{name}.md | 최종 Markdown 문서 |
{name}_content_list.json | 구조화된 콘텐츠 목록 (타입별) |
{name}_middle.json | 중간 표현 (모든 감지 결과) |
{name}_model.json | 모델 원시 출력 |
{name}_layout.pdf | 레이아웃 감지 시각화 |
{name}_span.pdf | 텍스트 스팬 시각화 |
images/ | 추출된 이미지 파일들 |
모델 목록 정리
Pipeline 백엔드에서 다운로드되는 전체 모델 목록:
| 모델 | 용도 | 포맷 | 단계 |
|---|---|---|---|
doclayout_yolo_docstructbench_imgsz1280_2501.pt | 레이아웃 감지 | PyTorch | Step 2 |
yolo_v8_ft.pt | 수식 영역 감지 (MFD) | PyTorch | Step 3 |
unimernet_small | 수식 인식 (MFR) | HuggingFace | Step 4 |
PP-LCNet_x1_0_table_cls.onnx | 테이블 분류 | ONNX | Step 5 |
slanet-plus.onnx | 무선 테이블 구조 인식 | ONNX | Step 6 |
unet.onnx | 유선 테이블 구조 인식 | ONNX | Step 6 |
pytorch_paddle | OCR (감지+인식) | PyTorch | Step 7 |
layout_reader | 읽기 순서 결정 | - | 후처리 |
paddle_orientation_classification | 이미지 회전 보정 | ONNX | 전처리 |
pp_formulanet_plus_m | 중국어 수식 인식 (대안) | PyTorch | Step 4 |
CLI 옵션 정리
mineru -p <input> -o <output> [OPTIONS]| 옵션 | 설명 | 기본값 |
|---|---|---|
-b, --backend | 백엔드 선택 | hybrid-auto-engine |
-m, --method | 파싱 방식 (auto/txt/ocr) | auto |
-d, --device | 추론 디바이스 (cpu/cuda/mps/npu) | 자동 |
-l, --lang | 문서 언어 (OCR 정확도 향상) | ch |
-f, --formula | 수식 파싱 활성화 | True |
-t, --table | 테이블 파싱 활성화 | True |
-s, --start | 시작 페이지 (0부터) | - |
-e, --end | 끝 페이지 (0부터) | - |
--vram | GPU 메모리 상한 (MB) | - |
--source | 모델 소스 (huggingface/modelscope) | huggingface |
지원 언어 (-l): ch, en, korean, japan, chinese_cht, ta, te, ka, th, el, latin, arabic, east_slavic, cyrillic, devanagari
Apple Silicon MPS vs CPU 성능 테스트
테스트 환경
| 항목 | 스펙 |
|---|---|
| 머신 | Apple Silicon Mac |
| MinerU | v2.7.6 |
| PyTorch | 2.10.0 (MPS 지원) |
| 백엔드 | Pipeline |
| 테스트 문서 | RAG-Anything 논문 (18페이지, 표 6개, 수식 77개, 이미지 23개) |
MPS 설정 및 적용 확인
MPS(Metal Performance Shaders)는 Apple Silicon의 GPU를 활용하는 PyTorch 백엔드다. MinerU에서는 Pipeline 백엔드에서만 사용 가능하다.
# 0. 설치 (uv 사용)
uv venv mineru-env --python 3.12
source mineru-env/bin/activate
uv pip install -U "mineru[all]"
mineru-models-download -s huggingface -m pipeline
# 1. MPS 사용 가능 여부 확인
uv run python -c "import torch; print('MPS available:', torch.backends.mps.is_available()); print('MPS built:', torch.backends.mps.is_built())"
# MPS available: True
# MPS built: True
# 2. MPS로 파싱 실행
mineru -p input.pdf -o output/ -b pipeline -d mps
# 3. MPS 적용 확인 방법: CPU 사용률로 판별
# - CPU 모드: CPU 사용률 80% (연산을 CPU가 전담)
# - MPS 모드: CPU 사용률 41% (GPU가 추론을 분담하므로 CPU 사용이 줄어듦)
# time 명령어로 확인:
time mineru -p input.pdf -o output/ -b pipeline -d mps
# → 37.99s user 7.72s system 41% cpu 1:49.97 total ← 41%면 MPS 적용됨MPS 적용 여부는 처리 속도로도 확인할 수 있다. Layout Predict 단계에서 CPU는 1.18s/it인 반면 MPS는 4.26it/s로 약 5배 차이가 나므로, 속도가 확연히 빠르면 MPS가 정상 작동 중인 것이다.
MPS는 Pipeline 백엔드(
-b pipeline)에서만-d mps옵션으로 지정할 수 있다. Hybrid/VLM 백엔드에서는 VLM 모델의 추론 엔진(vLLM, MLX 등)이 별도로 GPU를 관리한다.
성능 비교 결과
총 처리 시간
| 모드 | 총 시간 | CPU 사용률 | 페이지당 시간 |
|---|---|---|---|
| CPU | 2분 54.85초 | 80% | 9.71초 |
| MPS | 1분 49.97초 | 41% | 6.11초 |
| 차이 | -37.1% |
단계별 상세 비교
| 단계 | CPU | MPS | MPS 속도 향상 |
|---|---|---|---|
| 모델 초기화 | 12.3초 | 14.0초 | -13.8% (MPS 초기화 오버헤드) |
| Layout Predict (18p) | 21초 (1.18s/it) | 4초 (4.26it/s) | 5.0x |
| MFD Predict (18p) | 27초 (1.56s/it) | 4초 (4.21it/s) | 6.6x |
| MFR Predict (77식) | 33초 (2.28it/s) | 6초 (12.46it/s) | 5.5x |
| Table-wireless (6개) | <1초 | <1초 | 비슷 (ONNX) |
| Table-wired (6개) | <1초 | 3초 | -3x (MPS 오버헤드) |
| OCR-det (18p) | 7초 (2.32it/s) | 14초 (1.28it/s) | -1.8x (더 느림) |
| OCR-rec (4배치) | <1초 | <1초 | 비슷 |
분석
- YOLO 계열 모델(Layout, MFD)에서 MPS가 5~6배 빠름 — GPU 가속의 핵심 효과
- UniMERNet(MFR)도 5.5배 빠름 — Transformer 기반 모델에서 GPU 가속이 잘 됨
- OCR-det은 MPS가 오히려 느림 — PytorchPaddleOCR의 MPS 최적화가 부족한 것으로 보임
- ONNX 기반 모델(SLANET+, PP-LCNet)은 차이 없음 — ONNX Runtime은 MPS를 별도로 사용하지 않음
- 모델 초기화는 MPS가 약간 느림 — GPU 메모리 할당 오버헤드
- 총합으로는 MPS가 37% 빠름 — YOLO/Transformer 가속 효과가 OCR 감속을 상쇄
결과 품질 비교
CPU와 MPS의 출력 결과는 거의 동일하지만 미세한 차이가 있다:
- 테이블 셀 값 일부 차이 (예: 빈 셀 vs
5) - OCR 인식 결과 차이 (예:
GPT-4o-minivsGPT-40-mini) - 수식 LaTeX 변환에서 공백 처리 차이
이는 부동소수점 연산의 플랫폼 차이에서 비롯된 것으로, 실사용에 영향을 줄 수준은 아니다.
원본 vs 레이아웃 감지 vs 스팬 시각화
원본 PDF:

레이아웃 감지 결과 (영역별 색상 구분):

텍스트 스팬 시각화:

추출된 이미지 예시
MinerU가 논문에서 자동 추출한 Figure:

파싱 결과물 분석
18페이지 논문(RAG-Anything paper)의 실제 파싱 결과를 요소별로 살펴본다.
콘텐츠 타입 분포
content_list.json 기준:
| 타입 | 개수 | 설명 |
|---|---|---|
| text | 190 | 본문 텍스트 블록 |
| discarded | 38 | 헤더/푸터 등 자동 제거된 영역 |
| image | 12 | 추출된 Figure |
| table | 6 | 추출된 테이블 |
| equation | 5 | 디스플레이 수식 (인라인 수식은 텍스트에 포함) |
헤딩 처리
MinerU는 레이아웃 감지에서 Title (Category ID: 0)로 감지된 영역을 헤딩으로 처리한다. 실제 출력:
# RAG-ANYTHING: ALL-IN-ONE RAG FRAMEWORK
# ABSTRACT
# 1 INTRODUCTION
# 2 THE RAG-ANYTHING FRAMEWORK
# 2.1 PRELIMINARY
# 2.1.1 MOTIVATING RAG-ANYTHING
# 2.2 UNIVERSAL REPRESENTATION FOR HETEROGENEOUS KNOWLEDGE
# 2.2.1 DUAL-GRAPH CONSTRUCTION FOR MULTIMODAL KNOWLEDGE한계점: 모든 헤딩이 #(H1)로 처리된다. 2.1.1은 H3이어야 하지만 H1으로 출력된다. MinerU의 레이아웃 모델이 Title 영역은 감지하지만, 헤딩 레벨(depth) 구분은 하지 않는다. 이전 버전에서도 동일한 한계였으며, 아직 개선되지 않았다.
참고: MinerU의
llm-aided-config에서title_aided를 활성화하면 LLM이 헤딩 레벨을 보정해주는 기능이 있지만, 별도 API 키가 필요하다.
테이블 처리
테이블은 HTML <table> 태그로 변환된다. rowspan, colspan 등 복잡한 구조도 처리한다. 테이블 이미지도 함께 추출되어 원본과 비교할 수 있다.
Table 1 (단순 테이블) — 원본 이미지와 HTML 변환 결과:

변환된 HTML:
| Dataset | # Documents | # Avg. Pages | # Avg. Tokens | # Doc Types | # Questions |
| DocBench | 229 | 66 | 46377 | 1102 | |
| MMLongBench | 135 | 47.5 | 21214 | 5 | 1082 |
Table 2 (복잡한 테이블 — rowspan/colspan 포함):

변환된 HTML (rowspan, colspan 포함):
| Method | Domains | Types | Overall | ||||||
| Aca. | Fin. | Gov. | Law. | News | Txt. | Mm. | Una. | ||
| GPT-4o-mini | 40.3 | 46.9 | 60.3 | 59.2 | 61.0 | 61.0 | 43.8 | 49.6 | 51.2 |
| LightRAG | 53.8 | 56.2 | 59.5 | 61.8 | 65.7 | 85.0 | 59.7 | 46.8 | 58.4 |
| MMGraphRAG | 64.3 | 52.8 | 64.9 | 40.0 | 61.5 | 67.6 | 66.0 | 60.5 | 61.0 |
| RAGAnything | 61.4 | 67.0 | 61.5 | 60.2 | 66.3 | 85.0 | 76.3 | 46.0 | 63.4 |
rowspan="2"와 colspan="5" 같은 복잡한 셀 병합도 정확하게 처리한다. 테이블 캡션도 별도로 추출된다.
주의점: CPU와 MPS에서 테이블 OCR 결과에 미세한 차이가 있다. 예를 들어 CPU에서는 GPT-4o-mini로 인식한 셀이 MPS에서는 GPT-40-mini로 인식되는 경우가 있었다.
수식 처리
인라인 수식과 디스플레이 수식 모두 LaTeX로 변환된다. 아래는 원본 수식 이미지와 변환 결과:

변환된 LaTeX:
인라인 수식도 텍스트 내에서 처리된다: $k _ { i } \in \mathcal { K }$
77개의 수식이 감지·인식되었으며, 복잡한 행렬 수식(\begin{array})도 처리된다. 다만 LaTeX 내 공백이 다소 과도하게 삽입되는 경향이 있다 (예: k _ { i } → 원래는 k_i).
이미지 처리
이미지는 images/ 폴더에 JPG로 추출된다. 12개의 Figure가 추출되었으며, 캡션도 함께 보존된다.
추출된 Figure 예시 — 성능 비교 차트:

추출된 Figure 예시 — 멀티패널 Figure:

파일명은 콘텐츠 해시값으로 자동 생성된다 (예: 55313ce6fd3136d1cb...83bc.jpg).
불필요 영역 제거
38개의 discarded 항목이 자동 제거되었다. 주로 페이지 헤더(RAG-ANYTHING: ALL-IN-ONE RAG FRAMEWORK), 페이지 번호, arXiv 메타데이터 등이다.
RAG-Anything에서의 활용
RAG-Anything은 MinerU를 기본 파서로 사용한다. MinerU가 출력한 content_list.json의 각 항목을 타입별로 분리하여 처리한다:
MinerU 출력 (content_list.json)
├── type: "text" → LightRAG에 직접 삽입
├── type: "image" → ImageModalProcessor (Vision LLM 분석)
├── type: "table" → TableModalProcessor (LLM 구조 분석)
└── type: "equation" → EquationModalProcessor (LLM 의미 해석)
각 멀티모달 프로세서는 LLM을 사용하여 콘텐츠를 분석하고, 결과를 LightRAG 지식 그래프에 엔티티/관계로 저장한다. 이 과정에서 MinerU의 파싱 품질이 최종 RAG 성능에 직접적인 영향을 미친다.
정리
MinerU 2.x는 1.x 대비 아키텍처가 근본적으로 달라졌다:
- PyMuPDF 완전 제거 → pypdfium2/pypdf/pdfminer.six로 대체 (라이선스 개선)
- 3가지 백엔드 → Pipeline(정밀), VLM(속도), Hybrid(균형) 선택 가능
- 테이블 인식 모델 변경 → StructEqTable/TableMaster에서 SLANET+/UNet으로
- Reading Order 모델 탑재 → 이전엔 "Coming Soon"이었던 기능 완성
- Apple Silicon MPS 지원 → CPU 대비 37% 성능 향상 (YOLO/Transformer 모델에서 5~6배)
다만 여전히 AGPL-3.0 라이선스(YOLO 의존성)라는 점은 상용 프로젝트에서 주의가 필요하다. 내부 도구나 연구 목적으로는 현존 최고 수준의 PDF 파서라고 할 수 있다.
이 파서의 헤딩/테이블/수식/이미지 처리 결과를 다른 파서와 직접 비교한 글: PDF 파서 5종 비교 분석
참고
- MinerU GitHub
- DocLayout-YOLO
- PDF-Extract-Kit
- MinerU - PDF Parser — 이전 MinerU 1.x 분석 글
- RAG-Anything 파헤치기 — MinerU를 활용하는 RAG 프레임워크 분석