This guide is for operators, integrators, and developers running MinerU in production or embedding it into a larger pipeline. It covers the full system architecture, every configuration knob, deployment topologies, security posture, performance tuning, code internals, and integration points.
For end-user usage, parsing recipes, and CLI quick-start, see the MinerU User Guide.
1. Architecture Overview
MinerU is a self-contained document-parsing engine that converts PDFs, images, and Office files (DOCX, PPTX, XLSX) into structured Markdown and JSON. The system is organized into three distinct layers, each with clear responsibilities.
1.1 Three-Layer Architecture
┌─────────────────────────────────────────────────────────────┐
│ CLI / API Layer │
│ mineru (client.py) │ mineru-api (fast_api.py) │
│ mineru-gradio │ mineru-router (router.py) │
│ mineru-openai-server│ download-models │
├─────────────────────────────────────────────────────────────┤
│ Backend Layer │
│ Pipeline Backend │ VLM Backend │ Hybrid Backend │
│ (OCR + layout + │ (vision-lang │ (pipeline + VLM │
│ formula + table) │ model direct) │ combined) │
│ │ │ │
│ Office Backend (DOCX / PPTX / XLSX) │
├─────────────────────────────────────────────────────────────┤
│ Model Layer │
│ Layout (DocLayoutV2) │ OCR (PytorchPaddle) │
│ Formula (Unimernet/FormulaNet+) │ Table (SLANet+/UNet) │
│ VLM (vLLM/LMDeploy) │ Orientation Classification │
│ Office Converters (DOCX/PPTX/XLSX) │
├─────────────────────────────────────────────────────────────┤
│ Support Modules │
│ utils/ (31 modules) │ data/ (I/O abstraction) │
│ resources/ (static assets, language model) │
└─────────────────────────────────────────────────────────────┘
1.2 Layer Responsibilities
CLI / API Layer (mineru/cli/): All user-facing entry points. The main mineru CLI command handles local and API-based parsing. mineru-api exposes a FastAPI server for programmatic access. mineru-router provides load balancing across multiple API instances. mineru-gradio offers a browser-based UI. mineru-openai-server exposes a VLM endpoint with OpenAI-compatible protocol.
Backend Layer (mineru/backend/): Processing pipelines that orchestrate model inference:
| Backend | Module Path | Strategy |
|---|---|---|
| Pipeline | mineru/backend/pipeline/ |
Traditional: layout detection → OCR → formula recognition → table extraction → paragraph splitting → Markdown generation |
| VLM | mineru/backend/vlm/ |
Vision-language model processes pages directly, producing Markdown without intermediate steps |
| Hybrid | mineru/backend/hybrid/ |
Combines pipeline and VLM approaches for best-of-both accuracy |
| Office | mineru/backend/office/ |
Direct conversion of DOCX, PPTX, XLSX without ML models |
Model Layer (mineru/model/): Thin wrappers around deep learning models. Each model type has its own subdirectory with initialization, inference, and post-processing logic.
1.3 Key Design Decisions
- Filesystem-only state: No database. Jobs, outputs, and configuration all live on the filesystem.
- Singleton model loading:
ModelSingletonensures each ML model is loaded exactly once per process, preventing VRAM waste. - Protocol versioning:
API_PROTOCOL_VERSIONconstant inapi_protocol.pyensures client/server compatibility. Mismatched versions raise explicit errors. - Atomic task management:
AsyncTaskManagerhandles concurrent parse requests with thread-safe task tracking.
1.4 Processing Pipeline Flow
The pipeline backend (the most complex path) processes documents through these stages:
Input (PDF/Image)
│
▼
PDF Classification ─── auto-detect "txt" vs "ocr" method
│ (pdf_classify.py)
▼
Page Rendering ──────── PDF pages → images via pypdfium2
│ (pdf_image_tools.py)
▼
Batch Analysis ──────── All models run in batched inference
│ (batch_analyze.py)
│
├── Layout Detection (DocLayoutV2)
│ → region classification
├── OCR Text Extraction (PytorchPaddle)
├── Formula Recognition (Unimernet/FormulaNet+)
├── Table Detection
│ ├── Wireless tables (SLANet+)
│ ├── Wired tables (UNet)
│ └── Table classification fallback
└── Orientation Classification
│
▼
MagicModel ──────────── Post-processing, 25+ methods
│ (pipeline_magic_model.py)
▼
Model JSON → Middle JSON conversion
│ (model_json_to_middle_json.py)
▼
Paragraph Splitting ─── (para_split.py)
│
▼
Table Merging ───────── Cross-page table merging
│ (table_merge.py)
▼
Content Generation ──── Markdown + content_list output
(pipeline_middle_json_mkcontent.py)
Note
The VLM and hybrid backends skip most of these steps. VLM sends page images directly to a vision-language model. Hybrid combines both approaches, using pipeline for structure and VLM for content enhancement.
2. System Requirements
2.1 Hardware Requirements
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores | 8+ cores |
| RAM | 8 GB | 16+ GB |
| GPU (CUDA) | 4 GB VRAM | 8+ GB VRAM (NVIDIA) |
| GPU (alternatives) | MPS (Apple Silicon), NPU (Ascend), DCU, GCU, KunlunXin, MACA, MLU, MUSA, PPU, CoreX | — |
| Disk | 10 GB for models | 20+ GB (models + working space) |
Important
GPU is strongly recommended for production use. Without GPU acceleration, the pipeline backend falls back to CPU inference, which is dramatically slower. The
MINERU_DEVICE_MODEenvironment variable controls device selection.
2.2 Software Requirements
| Dependency | Purpose |
|---|---|
| Python 3.10+ | Runtime |
| PyTorch (with CUDA/MPS/NPU) | Model inference |
| pypdfium2 | PDF rendering |
| FastAPI + Uvicorn | API server |
| Gradio | Web UI |
| Click | CLI framework |
| httpx | Async HTTP client |
| loguru | Structured logging |
| OpenCV (cv2) | Image processing |
| numpy | Array operations |
| BeautifulSoup | HTML parsing |
| Pydantic | Data validation |
| fasttext | Language detection |
| vLLM / LMDeploy | VLM inference engines (optional, for VLM/hybrid backends) |
2.3 Supported Accelerator Platforms
MinerU provides dedicated Dockerfiles for each platform:
| Platform | Dockerfile | Notes |
|---|---|---|
| NVIDIA CUDA | Dockerfile (global) |
Primary supported platform |
| Ascend NPU | Dockerfile.ascend |
Huawei Atlas hardware |
| DCU | Dockerfile.dcu |
Hygon DCU |
| GCU | Dockerfile.gcu |
Enflame GCU |
| KunlunXin | Dockerfile.kunlunxin |
Baidu XPU |
| MACA | Dockerfile.maca |
MetaX MACA |
| MLU | Dockerfile.mlu |
Cambricon MLU |
| MUSA | Dockerfile.musa |
Moore Threads MUSA |
| NPU | Dockerfile.npu |
Generic NPU |
| PPU | Dockerfile.ppu |
PPU accelerator |
| CoreX | Dockerfile.corex |
Iluvatar CoreX |
China-specific variants (with _cn suffix) use domestic mirror sources.
3. Configuration Reference
3.1 Configuration File: mineru.json
Located by default at ~/mineru.json, overridden by the MINERU_TOOLS_CONFIG_JSON environment variable. The configuration reader is in mineru/utils/config_reader.py.
{
"bucket_info": {
"bucket-name-1": ["access_key", "secret_key", "endpoint"]
},
"latex-delimiter-config": {
"display": {"left": "$$", "right": "$$"},
"inline": {"left": "$", "right": "$"}
},
"llm-aided-config": {
"title_aided": {
"api_key": "your_api_key",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen3.5-plus",
"enable_thinking": false,
"enable": false
}
},
"models-dir": {
"pipeline": "",
"vlm": ""
},
"config_version": "1.3.1"
}
Field reference:
| Field | Type | Purpose |
|---|---|---|
bucket_info |
Object | S3-compatible bucket credentials. Keys are bucket names; values are [access_key, secret_key, endpoint] arrays. |
latex-delimiter-config.display |
Object | LaTeX display math delimiters (left/right). |
latex-delimiter-config.inline |
Object | LaTeX inline math delimiters (left/right). |
llm-aided-config.title_aided |
Object | LLM-assisted title extraction config. Set enable: true to activate. |
models-dir.pipeline |
String | Custom directory for pipeline model weights. Empty string uses default. |
models-dir.vlm |
String | Custom directory for VLM model weights. Empty string uses default. |
config_version |
String | Configuration schema version. Current: 1.3.1. |
3.2 Environment Variables — Complete Reference
All 24 environment variables extracted from source, grouped by function:
Core Runtime
| Variable | Default | Source | Description |
|---|---|---|---|
MINERU_DEVICE_MODE |
None (auto-detect) |
config_reader.py |
Force device mode: cuda, mps, npu, cpu, etc. When None, auto-detects available hardware. |
MINERU_LOG_LEVEL |
INFO |
client.py |
Log verbosity. Accepts standard Python logging levels: DEBUG, INFO, WARNING, ERROR, CRITICAL. |
MINERU_TOOLS_CONFIG_JSON |
mineru.json |
models_download.py |
Path to the configuration JSON file. |
Feature Toggles
| Variable | Default | Source | Description |
|---|---|---|---|
MINERU_FORMULA_ENABLE |
(none) | config_reader.py |
Enable/disable formula recognition. Overrides CLI --formula flag. |
MINERU_TABLE_ENABLE |
(none) | config_reader.py |
Enable/disable table recognition. Overrides CLI --table flag. |
MINERU_TABLE_MERGE_ENABLE |
true |
runtime_utils.py |
Enable cross-page table merging. Set to false to disable. |
MINERU_FORMULA_CH_SUPPORT |
False |
model_init.py |
Enable Chinese formula recognition support. |
MINERU_OCR_DET_MASK_INLINE_FORMULA_ENABLE |
(none) | config_reader.py |
Enable masking of inline formulas during OCR detection. |
API Server
| Variable | Default | Source | Description |
|---|---|---|---|
MINERU_API_OUTPUT_ROOT |
(none) | fast_api.py |
Root directory for API output files. If unset, uses a temp directory. |
MINERU_API_MAX_CONCURRENT_REQUESTS |
(none) | config_reader.py |
Maximum concurrent parse requests the API server will accept. |
MINERU_API_DISABLE_ACCESS_LOG |
(none) | api_client.py |
Set internally when launching local API servers to suppress access logs. |
MINERU_API_SHUTDOWN_ON_STDIN_EOF |
(none) | api_client.py |
Set internally for managed local API servers; causes shutdown when parent process exits. |
MINERU_LOCAL_API_STARTUP_TIMEOUT_SECONDS |
300.0 |
api_client.py |
Timeout (seconds) for local API server startup. Increase for slow model loading. |
Router / Load Balancer
| Variable | Default | Source | Description |
|---|---|---|---|
CUDA_VISIBLE_DEVICES |
(none) | router.py |
Standard CUDA variable. Router uses this to determine available GPUs for managed workers. |
MINERU_ROUTER_LOCAL_GPUS |
(none) | router.py |
Explicit GPU list for router-managed workers. Overrides CUDA_VISIBLE_DEVICES parsing. |
MINERU_ROUTER_WORKER_HOST |
127.0.0.1 |
router.py |
Bind address for router-spawned worker processes. |
Model & Performance
| Variable | Default | Source | Description |
|---|---|---|---|
MINERU_MODEL_SOURCE |
huggingface |
models_download_utils.py |
Model download source. Options: huggingface, modelscope, etc. |
MINERU_VIRTUAL_VRAM_SIZE |
(none) | model_utils.py |
Override detected VRAM size (MB). Useful for testing or when VRAM detection is inaccurate. |
MINERU_PROCESSING_WINDOW_SIZE |
(none) | config_reader.py |
Number of pages processed per batch window. Affects memory usage and throughput. |
MINERU_LMDEPLOY_DEVICE |
(none) | common.py |
Device target for LMDeploy VLM inference. |
PDF Rendering
| Variable | Default | Source | Description |
|---|---|---|---|
MINERU_PDF_RENDER_TIMEOUT |
None |
os_env_config.py |
Timeout (seconds) for PDF page rendering. None means no timeout. |
MINERU_PDF_RENDER_THREADS |
None |
os_env_config.py |
Number of threads for parallel PDF rendering. None uses default. |
External
| Variable | Default | Source | Description |
|---|---|---|---|
FTLANG_CACHE |
(none) | language.py |
Cache directory for fasttext language detection model. |
Tip
For production deployments, always set
MINERU_API_OUTPUT_ROOTto a persistent directory. Without it, outputs go to a temporary directory that may be cleaned up by the OS.
3.3 Key Constants
These constants are defined in source and affect system behavior:
| Constant | Value | Location | Purpose |
|---|---|---|---|
API_PROTOCOL_VERSION |
(versioned) | api_protocol.py |
Client/server protocol compatibility check |
TASK_STATUS_POLL_INTERVAL_SECONDS |
1.0 |
CLI | Polling interval for async task status |
TASK_RESULT_TIMEOUT_SECONDS |
3600 |
CLI | Maximum wait time for async task results (1 hour) |
LOCAL_API_STARTUP_TIMEOUT_SECONDS |
300.0 |
api_client.py |
Default timeout waiting for local API server health |
LAYOUT_BASE_BATCH_SIZE |
1 |
Backend | Base batch size for layout model inference |
MFR_BASE_BATCH_SIZE |
16 |
Backend | Base batch size for formula recognition |
OCR_DET_BASE_BATCH_SIZE |
8 |
Backend | Base batch size for OCR detection |
4. Deployment & Scaling
4.1 Docker Deployment
MinerU provides a compose.yaml with four profiles:
| Profile | Service | Port | Purpose |
|---|---|---|---|
openai-server |
VLM server | 30000 | OpenAI-compatible VLM endpoint |
api |
FastAPI server | 8000 | REST API for document parsing |
router |
Load balancer | 8002 | Multi-GPU load balancing |
gradio |
Web UI | 7860 | Browser-based parsing interface |
Warning
All Docker profiles require NVIDIA GPU with the NVIDIA Container Toolkit installed. The containers will fail to start without GPU access.
Starting the API server:
docker compose --profile api up -d
Starting the router with multiple GPUs:
docker compose --profile router up -d
Starting the Gradio UI:
docker compose --profile gradio up -d
4.2 Bare-Metal Deployment
# Install MinerU
pip install mineru
# Download models
download-models -s huggingface
# Start API server
mineru-api --host 0.0.0.0 --port 8000
Caution
When binding to
0.0.0.0, the--allow-public-http-clientflag must be passed explicitly. Without it, the server enforcespublic_http_client_policy.pyrestrictions that block non-localhost connections. This is a deliberate security measure.
4.3 Multi-GPU Scaling with Router
The router (mineru-router) distributes parse requests across multiple API server instances:
# Option 1: Explicit upstream URLs
mineru-router --host 0.0.0.0 --port 8002 \
--upstream-url http://gpu1:8000 \
--upstream-url http://gpu2:8000 \
--upstream-url http://gpu3:8000
# Option 2: Auto-spawn workers on local GPUs
mineru-router --host 0.0.0.0 --port 8002 \
--local-gpus 0,1,2,3
Router architecture:
Client Request
│
▼
┌──────────────────┐
│ mineru-router │ Port 8002
│ (RouterSettings) │
│ (WorkerPool) │
│ (RouterTaskRegistry)│
├──────────────────┤
│ Load Balancing │
│ (round-robin) │
└──┬───┬───┬───────┘
│ │ │
▼ ▼ ▼
┌────┐┌────┐┌────┐
│GPU0││GPU1││GPU2│ mineru-api instances
│:8000│:8001│:8002│
└────┘└────┘└────┘
Key classes in the router:
| Class | Purpose |
|---|---|
RouterSettings |
Configuration for router behavior |
WorkerPool |
Manages upstream API server instances |
WorkerState |
Tracks health and load of each worker |
RouterTaskRegistry |
Maps async task IDs to upstream workers |
ManagedLocalServer |
Spawns and manages local API server processes |
4.4 VLM Preloading
For backends using VLM models, preloading prevents cold-start latency:
# API server with VLM preloading
mineru-api --host 0.0.0.0 --port 8000 --enable-vlm-preload
# Router with VLM preloading on workers
mineru-router --host 0.0.0.0 --port 8002 \
--local-gpus 0,1 --enable-vlm-preload
The vlm_preload.py module handles model warmup during server startup rather than on first request.
5. Operations
5.1 API Endpoints — Complete Reference
FastAPI Server (mineru-api)
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/file_parse |
None | Synchronous document parsing. Blocks until complete. |
POST |
/submit_parse_task |
None | Submit async parse task. Returns task ID immediately. |
GET |
/get_async_task_status |
None | Poll status of an async task by ID. |
GET |
/get_async_task_result |
None | Retrieve results of a completed async task. |
GET |
/health |
None | Health check. Returns server status and model readiness. |
Synchronous parse (POST /file_parse):
curl -X POST http://localhost:8000/file_parse \
-F "file=@document.pdf" \
-F "method=auto" \
-F "backend=hybrid-auto-engine"
Async parse workflow:
# 1. Submit task
TASK_ID=$(curl -s -X POST http://localhost:8000/submit_parse_task \
-F "file=@document.pdf" | jq -r '.task_id')
# 2. Poll status (repeats every 1 second)
curl -s "http://localhost:8000/get_async_task_status?task_id=$TASK_ID"
# 3. Get result when complete
curl -s "http://localhost:8000/get_async_task_result?task_id=$TASK_ID"
Router (mineru-router)
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/file_parse |
None | Synchronous parse, routed to best available worker. |
POST |
/submit_parse_task |
None | Async parse, routed to least-loaded worker. |
GET |
/get_router_task_status |
None | Task status (router resolves which upstream holds the task). |
GET |
/get_router_task_result |
None | Task result from upstream worker. |
GET |
/health |
None | Router health + upstream worker status. |
5.2 CLI Command Reference (Server-Side)
mineru-api — FastAPI Server
mineru-api [OPTIONS]
| Flag | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Bind address |
--port |
8000 |
Bind port |
--reload |
false |
Enable auto-reload on code changes (dev only) |
--allow-public-http-client |
false |
Allow non-localhost HTTP connections |
--enable-vlm-preload |
false |
Preload VLM models at startup |
mineru-router — Load Balancer
mineru-router [OPTIONS]
| Flag | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Bind address |
--port |
8002 |
Bind port |
--upstream-url |
(none) | Upstream API server URL (repeatable) |
--local-gpus |
(none) | Comma-separated GPU IDs to auto-spawn workers |
--worker-host |
127.0.0.1 |
Bind address for auto-spawned workers |
--enable-vlm-preload |
false |
Preload VLM models on workers |
mineru-openai-server — VLM Server
mineru-openai-server [OPTIONS]
| Flag | Default | Description |
|---|---|---|
-e, --engine |
(required) | VLM inference engine (vllm or lmdeploy) |
download-models — Model Downloader
download-models [OPTIONS]
| Flag | Default | Description |
|---|---|---|
-s, --source |
(none) | Model source: huggingface, modelscope |
-m, --model_type |
(none) | Model type to download |
5.3 Logging
MinerU uses loguru for structured logging throughout the codebase.
Log level control:
# Via environment variable
export MINERU_LOG_LEVEL=DEBUG
mineru-api --host 0.0.0.0 --port 8000
Valid levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
Access log suppression:
When the CLI spawns a local API server, it sets MINERU_API_DISABLE_ACCESS_LOG internally to reduce noise. For production deployments where you manage the API server directly, access logs are enabled by default.
5.4 Health Checks
The /health endpoint on both the API server and router returns server status:
# API server health
curl http://localhost:8000/health
# Router health (includes upstream worker status)
curl http://localhost:8002/health
Tip
Use the health endpoint in container orchestration (Docker health checks, Kubernetes liveness probes). The endpoint verifies model readiness, not just HTTP responsiveness.
5.5 Model Management
Downloading models:
# From Hugging Face (default)
download-models -s huggingface
# From ModelScope (faster in China)
export MINERU_MODEL_SOURCE=modelscope
download-models -s modelscope
Custom model directories:
Set in mineru.json:
{
"models-dir": {
"pipeline": "/opt/models/pipeline",
"vlm": "/opt/models/vlm"
}
}
Model singleton behavior:
The ModelSingleton class in mineru/backend/pipeline/model_init.py ensures each model type is loaded exactly once. Models are loaded lazily on first use unless VLM preloading is enabled. The AtomicModel enum defines all model types:
| AtomicModel | Purpose |
|---|---|
Layout |
Page layout detection (DocLayoutV2) |
MFD |
Math formula detection |
MFR |
Math formula recognition |
OCR |
Text extraction (PytorchPaddle) |
WirelessTable |
Borderless table recognition (SLANet+) |
WiredTable |
Bordered table recognition (UNet) |
TableCls |
Table type classification |
ImgOrientationCls |
Image orientation detection |
6. Performance
6.1 Batch Size Tuning
Model inference uses batched processing. Base batch sizes scale with available VRAM:
| Model | Base Batch Size | Scaling |
|---|---|---|
| Layout (DocLayoutV2) | 1 | Scales with VRAM |
| Formula Recognition (MFR) | 16 | Scales with VRAM |
| OCR Detection | 8 | Scales with VRAM |
VRAM override:
# Force VRAM size detection (MB)
export MINERU_VIRTUAL_VRAM_SIZE=8192
The model_utils.py module manages VRAM detection and batch size calculation.
6.2 Processing Window
The MINERU_PROCESSING_WINDOW_SIZE variable controls how many pages are processed in each batch window. Larger windows improve throughput on long documents but increase peak memory usage.
6.3 PDF Rendering Performance
# Set render timeout per page (seconds)
export MINERU_PDF_RENDER_TIMEOUT=30
# Parallel rendering threads
export MINERU_PDF_RENDER_THREADS=4
The pdf_image_tools.py module uses pypdfium2 for PDF-to-image conversion. Thread count defaults to a system-appropriate value when unset.
6.4 Concurrent Request Limiting
# Limit API server to 4 concurrent parse requests
export MINERU_API_MAX_CONCURRENT_REQUESTS=4
Without this limit, the server accepts all incoming requests, which can exhaust GPU memory.
6.5 Table Merging
Cross-page table merging (table_merge.py) detects tables that span page boundaries and stitches them together. This adds post-processing time proportional to the number of tables detected.
# Disable if not needed (slight speedup on table-heavy documents)
export MINERU_TABLE_MERGE_ENABLE=false
The TableMergeState class tracks merge state across pages.
6.6 Multi-GPU Throughput
For maximum throughput, deploy one mineru-api instance per GPU behind a mineru-router:
# 4-GPU setup
mineru-router --port 8002 --local-gpus 0,1,2,3
Each worker gets exclusive access to one GPU via CUDA_VISIBLE_DEVICES isolation. The router distributes requests across workers.
7. Security
7.1 Network Security
Public binding protection:
The public_http_client_policy.py module enforces a security policy when the API server binds to non-localhost addresses. Without the explicit --allow-public-http-client flag, the server rejects requests from external IPs.
# Secure: localhost only (default)
mineru-api --host 127.0.0.1 --port 8000
# Explicit public access (requires flag)
mineru-api --host 0.0.0.0 --port 8000 --allow-public-http-client
Warning
MinerU's API endpoints have no authentication. When exposing publicly, place the server behind a reverse proxy with authentication (e.g., nginx with basic auth, Traefik with middleware, or an API gateway).
7.2 Authentication
MinerU does not implement authentication or authorization at the application level. All API endpoints are unauthenticated. For production deployments:
- Use a reverse proxy with authentication
- Restrict network access via firewall rules
- Use Docker network isolation
- Consider VPN-only access for internal services
7.3 S3 Credential Handling
S3 credentials in mineru.json are stored as plaintext. The bucket_info field maps bucket names to credential arrays:
{
"bucket_info": {
"my-bucket": ["ACCESS_KEY", "SECRET_KEY", "https://s3.endpoint.com"]
}
}
Caution
Protect
mineru.jsonwith appropriate file permissions (chmod 600) when it contains S3 credentials. Do not commit credentials to version control.
7.4 LLM API Key Handling
The llm-aided-config section stores API keys for LLM-assisted title extraction. Same plaintext storage concern as S3 credentials.
7.5 Input Validation
The system validates inputs at multiple points:
- File type validation: only PDF, DOCX, PPTX, XLSX, and image formats accepted
- Page range validation:
--startand--endflags are bounds-checked - URL validation:
--urlinputs are validated before fetching - File size: implicitly limited by FastAPI's upload handling
7.6 Managed Server Lifecycle
The ReusableLocalAPIServer and LocalAPIServer classes in api_client.py spawn child API server processes. The MINERU_API_SHUTDOWN_ON_STDIN_EOF mechanism ensures child servers terminate when the parent process exits, preventing orphaned GPU-consuming processes.
8. Developer Internals
8.1 Module Reference
Core Engine (mineru/backend/pipeline/)
| Module | Lines | Purpose |
|---|---|---|
pipeline_magic_model.py |
Large | MagicModel class with 25+ methods for post-processing model outputs. Central orchestrator for the pipeline backend. |
batch_analyze.py |
Medium | BatchAnalyze class. Runs all atomic models in batched inference, managing GPU memory allocation. |
model_init.py |
Medium | ModelSingleton pattern. custom_model_init() initializes models based on AtomicModel enum. MINERU_FORMULA_CH_SUPPORT toggle. |
pipeline_analyze.py |
Medium | Main entry point for pipeline processing. Orchestrates the full analysis flow. |
model_json_to_middle_json.py |
Medium | Converts raw model JSON output to the intermediate "middle JSON" format used by downstream stages. |
pipeline_middle_json_mkcontent.py |
Medium | Converts middle JSON to final Markdown output and content_list structured data. |
para_split.py |
Medium | Paragraph boundary detection and text splitting logic. |
model_list.py |
Small | AtomicModel enum defining all model types. |
CLI Layer (mineru/cli/)
| Module | Lines | Purpose |
|---|---|---|
client.py |
1091+ | Main mineru CLI. Click-based command with extensive option handling. Manages local API server lifecycle. |
fast_api.py |
1563+ | FastAPI server implementation. All parse endpoints, async task management, file handling. |
router.py |
1465+ | Load balancing router. Worker pool management, task routing, health monitoring. |
gradio_app.py |
1079+ | Gradio web interface. File upload, progress display, result rendering. |
api_client.py |
Large | HTTP client for API communication. LocalAPIServer and ReusableLocalAPIServer for managed server lifecycle. |
api_protocol.py |
Small | API_PROTOCOL_VERSION constant for client/server compatibility. |
common.py |
Medium | Shared parsing logic used by both CLI and API paths. Backend dispatch based on --backend flag. |
output_paths.py |
Small | Output directory and file path resolution. |
vlm_preload.py |
Small | VLM model preloading during server startup. |
vlm_server.py |
Medium | OpenAI-compatible VLM server endpoint. |
models_download.py |
Small | download-models CLI command. Model download orchestration. |
visualization.py |
Small | Layout visualization utilities for debugging. |
public_http_client_policy.py |
Small | Security policy enforcement for public-facing servers. |
Model Layer (mineru/model/)
| Subdirectory | Key Classes | Purpose |
|---|---|---|
layout/ |
DocLayoutV2 | Page layout detection and region classification |
ocr/ |
PytorchPaddle | OCR text extraction (PaddleOCR weights via PyTorch) |
mfr/ |
Unimernet, FormulaNet+ | Mathematical formula recognition |
table/ |
PaddleTable, PaddleTableModel, UnetTableModel, WiredTableRecognition |
Table structure recognition (wireless via SLANet+, wired via UNet) |
ori_cls/ |
— | Image orientation classification |
vlm/ |
— | VLM model integration (vLLM, LMDeploy engines) |
docx/ |
DocxConverter |
DOCX → Markdown conversion |
pptx/ |
PptxConverter |
PPTX → Markdown conversion |
xlsx/ |
XlsxConverter |
XLSX → Markdown conversion |
Data I/O (mineru/data/)
| Module | Key Classes | Purpose |
|---|---|---|
data_reader_writer/ |
Local, S3, MultiBucketS3 | File I/O abstraction supporting local filesystem and S3-compatible storage |
io/ |
HTTP reader, S3 reader | Input readers for remote sources |
utils/ |
S3Config, PageInfo, exceptions |
Data schemas, path utilities, exception types |
Exception classes in mineru/data/utils/:
| Exception | Meaning |
|---|---|
FileNotExisted |
Referenced file not found on filesystem or S3 |
InvalidConfig |
Configuration file malformed or missing required fields |
InvalidParams |
Invalid parameters passed to a function |
EmptyData |
Input document contains no extractable content |
CUDA_NOT_AVAILABLE |
GPU required but CUDA not available |
Utilities (mineru/utils/ — 31 modules)
| Module | Purpose |
|---|---|
config_reader.py |
Reads mineru.json and environment variable overrides |
pdf_classify.py |
PDF type classification: determines txt (extractable text) vs ocr (image-based) |
pdf_image_tools.py |
PDF page rendering to images via pypdfium2 |
table_merge.py |
Cross-page table merging with TableMergeState tracking |
ocr_utils.py |
OCR bounding box processing and text alignment |
model_utils.py |
VRAM detection, batch size calculation, MINERU_VIRTUAL_VRAM_SIZE handling |
models_download_utils.py |
Model download helpers, source selection (huggingface/modelscope) |
runtime_utils.py |
Runtime feature flag reading (MINERU_TABLE_MERGE_ENABLE) |
os_env_config.py |
PDF render timeout and thread configuration |
language.py |
Language detection via fasttext (FTLANG_CACHE for model caching) |
bbox_utils.py |
Bounding box math (overlap, intersection, union) |
char_utils.py |
Character-level utilities |
draw_utils.py |
Debug visualization for bounding boxes |
hash_utils.py |
File hashing |
8.2 Key Enums and Types
class AtomicModel(Enum):
Layout = "layout"
MFD = "mfd"
MFR = "mfr"
OCR = "ocr"
WirelessTable = "wireless_table"
WiredTable = "wired_table"
TableCls = "table_cls"
ImgOrientationCls = "img_orientation_cls"
class BlockType: # Layout block classification
class ContentType: # Output content types (v1)
class ContentTypeV2: # Output content types (v2)
class MakeMode: # Markdown generation mode
class ModelPath: # Model weight paths
class SplitFlag: # Paragraph split markers
class ImageType: # Image format types
class NotExtractType: # Regions to skip during extraction
8.3 Code Patterns and Conventions
Singleton pattern for models:
class ModelSingleton:
_instance = None
_models = {}
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
All model loading goes through ModelSingleton to prevent duplicate VRAM allocation.
Backend dispatch:
The common.py module dispatches to the appropriate backend based on the --backend CLI flag:
| Backend Value | Processing Path |
|---|---|
pipeline |
Traditional OCR pipeline |
vlm |
Direct VLM inference |
hybrid-auto-engine (default) |
Hybrid pipeline + VLM |
office |
Office document conversion |
Async task lifecycle:
class AsyncTaskManager:
# Thread-safe task registry
# submit_task() → task_id
# get_status(task_id) → status dict
# get_result(task_id) → output data
Tasks follow: submitted → processing → completed | failed.
Data I/O abstraction:
All file operations go through data_reader_writer/ classes, allowing transparent switching between local filesystem and S3 storage. The S3Config class validates bucket credentials from mineru.json.
8.4 Repository Structure
mineru/
├── __init__.py
├── version.py # __version__ = "3.1.0"
├── cli/
│ ├── api_client.py # HTTP client + local server management
│ ├── api_protocol.py # API_PROTOCOL_VERSION
│ ├── client.py # Main `mineru` CLI (1091+ lines)
│ ├── common.py # Shared parse logic, backend dispatch
│ ├── fast_api.py # FastAPI server (1563+ lines)
│ ├── gradio_app.py # Gradio web UI (1079+ lines)
│ ├── models_download.py # download-models CLI
│ ├── output_paths.py # Output path resolution
│ ├── public_http_client_policy.py # Public binding security
│ ├── router.py # Load balancing router (1465+ lines)
│ ├── visualization.py # Layout visualization
│ ├── vlm_preload.py # VLM model preloading
│ └── vlm_server.py # OpenAI-compatible VLM server
├── backend/
│ ├── pipeline/ # Traditional OCR pipeline
│ │ ├── batch_analyze.py # Batched model inference
│ │ ├── model_init.py # ModelSingleton initialization
│ │ ├── model_json_to_middle_json.py
│ │ ├── model_list.py # AtomicModel enum
│ │ ├── para_split.py # Paragraph splitting
│ │ ├── pipeline_analyze.py # Main pipeline entry
│ │ ├── pipeline_magic_model.py # MagicModel (25+ methods)
│ │ └── pipeline_middle_json_mkcontent.py
│ ├── vlm/ # VLM-based parsing
│ ├── hybrid/ # Hybrid pipeline+VLM
│ ├── office/ # Office document parsing
│ └── utils/ # Backend utilities
├── model/
│ ├── layout/ # DocLayoutV2
│ ├── ocr/ # PytorchPaddle OCR
│ ├── mfr/ # Math formula recognition
│ ├── table/ # Table recognition
│ ├── ori_cls/ # Orientation classification
│ ├── vlm/ # VLM model integration
│ ├── docx/ # DocxConverter
│ ├── pptx/ # PptxConverter
│ └── xlsx/ # XlsxConverter
├── data/
│ ├── data_reader_writer/ # File I/O (local, S3)
│ ├── io/ # Input readers (HTTP, S3)
│ └── utils/ # Exceptions, schemas
├── utils/ # 31 utility modules
│ ├── config_reader.py
│ ├── pdf_classify.py
│ ├── pdf_image_tools.py
│ ├── table_merge.py
│ ├── ocr_utils.py
│ ├── model_utils.py
│ ├── models_download_utils.py
│ └── ...
└── resources/
├── header.html
└── fasttext-langdetect/lid.176.ftz
8.5 Testing
Tests are located in tests/unittest/. The test_e2e.py file contains end-to-end tests that exercise the full pipeline from input to output.
9. Integration Points
9.1 S3 Storage Integration
MinerU supports S3-compatible storage for both input and output:
{
"bucket_info": {
"my-input-bucket": ["ACCESS_KEY", "SECRET_KEY", "https://s3.amazonaws.com"],
"my-output-bucket": ["ACCESS_KEY", "SECRET_KEY", "https://s3.amazonaws.com"]
}
}
The MultiBucketS3 reader/writer supports multiple buckets with different credentials. Input files can be read directly from S3, and output can be written back to S3.
9.2 HTTP Input
Documents can be fetched from URLs for parsing:
mineru -u https://example.com/document.pdf -o ./output
The data/io/ module handles HTTP fetching with appropriate timeout and error handling.
9.3 LLM-Assisted Processing
The llm-aided-config section enables LLM-assisted title extraction:
{
"llm-aided-config": {
"title_aided": {
"api_key": "your_api_key",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen3.5-plus",
"enable_thinking": false,
"enable": true
}
}
}
When enabled, ambiguous titles detected during layout analysis are sent to the configured LLM for disambiguation.
9.4 VLM Server Integration
The mineru-openai-server command exposes a VLM endpoint compatible with the OpenAI API format:
# Start VLM server with vLLM engine
mineru-openai-server -e vllm
# Or with LMDeploy engine
mineru-openai-server -e lmdeploy
This allows MinerU's VLM capabilities to be consumed by any OpenAI-compatible client.
9.5 Programmatic Python API
from mineru.backend.pipeline.pipeline_analyze import pipeline_analyze
from mineru.backend.vlm import vlm_analyze
from mineru.backend.hybrid import hybrid_analyze
Direct Python imports bypass the CLI/API layer entirely. This is useful for embedding MinerU into larger Python applications.
9.6 Output Formats
MinerU produces two output types:
| Format | Description |
|---|---|
Markdown (.md) |
Human-readable document with tables, formulas, and image references |
| Content List (JSON) | Structured representation with bounding boxes, content types, and page references |
The MakeMode enum controls which output format is generated.
10. Troubleshooting
Error: Protocol version mismatch
Cause: Client and server are running different versions of MinerU with incompatible API_PROTOCOL_VERSION values.
Solution: Ensure both mineru CLI client and mineru-api server are the same version:
pip install --upgrade mineru
Prevention: Pin MinerU version in your requirements file and upgrade client and server together.
Error: Timed out while polling task status
Cause: Async task exceeded TASK_RESULT_TIMEOUT_SECONDS (default: 3600 seconds / 1 hour). Common with very large PDFs or underpowered hardware.
Solution:
- Check GPU utilization — the process may be stuck or OOM
- Check server logs for errors during processing
- For large documents, increase the timeout or use page range limiting (
--start/--end)
Prevention: Set MINERU_API_MAX_CONCURRENT_REQUESTS to prevent overloading the server.
Error: HybridDependencyError
Cause: The hybrid backend requires both pipeline and VLM dependencies. One or both are missing.
Solution: Install the full dependency set:
pip install mineru[full]
Prevention: Use the pipeline backend if VLM dependencies are unavailable.
Error: CUDA not available / CUDA_NOT_AVAILABLE
Cause: PyTorch cannot find CUDA drivers or GPU hardware.
Solution:
- Verify NVIDIA drivers:
nvidia-smi - Verify PyTorch CUDA:
python -c "import torch; print(torch.cuda.is_available())" - For CPU-only operation:
export MINERU_DEVICE_MODE=cpu
Prevention: Use Docker images with pre-configured CUDA support.
Error: Empty PDF / EmptyData
Cause: Input PDF contains no extractable pages or content.
Solution: Verify the PDF is not corrupt and contains actual content. Try opening in a PDF viewer.
Error: Unsupported file suffix
Cause: Input file has an extension not in the supported set (PDF, DOCX, PPTX, XLSX, common image formats).
Solution: Rename the file with the correct extension or convert to a supported format.
Error: Health check failure on startup
Cause: API server failed to become healthy within MINERU_LOCAL_API_STARTUP_TIMEOUT_SECONDS (default: 300 seconds). Usually caused by slow model downloads or loading.
Solution:
# Increase startup timeout
export MINERU_LOCAL_API_STARTUP_TIMEOUT_SECONDS=600
# Pre-download models before starting server
download-models -s huggingface
Prevention: Always run download-models before first server start.
Error: Upstream unavailable/rejected (Router)
Cause: Router cannot reach any upstream API server, or all upstreams are rejecting requests (overloaded).
Solution:
- Check upstream server health:
curl http://upstream:8000/health - Check network connectivity between router and upstreams
- Verify
--upstream-urlvalues are correct
Prevention: Monitor upstream health and scale horizontally when load increases.
Note
For issues related to specific document types (Arabic text ordering, image segmentation anomalies, table extraction quality), see the GitHub Issues tracker. Known issues include #2551 (Arabic PDF parsing order), #4008 (image segmentation), and #4207 (table extraction).
11. Quick Reference
Environment Variables Cheat Sheet
# Essential production settings
export MINERU_DEVICE_MODE=cuda
export MINERU_LOG_LEVEL=INFO
export MINERU_API_OUTPUT_ROOT=/data/mineru/output
export MINERU_API_MAX_CONCURRENT_REQUESTS=4
export MINERU_MODEL_SOURCE=huggingface
# Performance tuning
export MINERU_PDF_RENDER_THREADS=4
export MINERU_PDF_RENDER_TIMEOUT=30
export MINERU_VIRTUAL_VRAM_SIZE=8192
export MINERU_PROCESSING_WINDOW_SIZE=10
# Feature flags
export MINERU_FORMULA_ENABLE=true
export MINERU_TABLE_ENABLE=true
export MINERU_TABLE_MERGE_ENABLE=true
export MINERU_FORMULA_CH_SUPPORT=false
# Router settings
export MINERU_ROUTER_LOCAL_GPUS=0,1,2,3
export MINERU_ROUTER_WORKER_HOST=0.0.0.0
Port Reference
| Service | Default Port | Command |
|---|---|---|
| API Server | 8000 | mineru-api |
| Router | 8002 | mineru-router |
| Gradio UI | 7860 | mineru-gradio |
| VLM Server | 30000 | mineru-openai-server |
Backend Selection Guide
| Use Case | Backend | Flag |
|---|---|---|
| Best accuracy (default) | Hybrid | --backend hybrid-auto-engine |
| Fast, traditional OCR | Pipeline | --backend pipeline |
| VLM-only (no OCR models needed) | VLM | --backend vlm |
| Office documents | Office | (auto-detected by file extension) |
Docker Profiles
docker compose --profile api up -d # API server
docker compose --profile router up -d # Load balancer
docker compose --profile gradio up -d # Web UI
docker compose --profile openai-server up -d # VLM server