📄 Serverless MinerU 2.5 Pro PDF parser on RunPod. Scales to zero. PDF → Markdown + JSON.
See the codeServerless MinerU document parser on RunPod. MinerU 3.4.x runtime with the MinerU2.5-Pro-2605-1.2B VLM. Scales to zero; best-case warm parses measured about $0.0003 per page on a 24 GB serverless RTX 4090.
Docs · Get started on RunPod · Blog
⚠️ Not an official MinerU project. This is an independent wrapper that packages the open-source MinerU runtime as a RunPod Serverless worker. It is not affiliated with, endorsed by, or supported by OpenDataLab, who publish MinerU, or by RunPod. Parsing behavior belongs upstream; anything about this worker belongs here.
Python (mineru_client):
from mineru_client import MineruClient
client = MineruClient(endpoint_id="<your-endpoint-id>")
result = client.parse_document(file_url="https://example.com/report.pdf", end_page=4)
client.save_tarball(result, "./out/doc")
# → markdown + content_list + middle.json + images
curl (no SDK):
curl -X POST "https://api.runpod.ai/v2/<endpoint-id>/runsync" \
-H "Authorization: Bearer $RUNPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":{"file_url":"https://example.com/report.pdf","end_page":4,"transport":"inline"}}'
The response wraps each parsed file as an entry inside results: [...]. For a single document, the markdown sits at output.results[0].markdown — pipe it straight to a file: curl ... | jq -r '.output.results[0].markdown' > report.md.
Accepts PDF, image (PNG/JPEG/GIF/BMP/TIFF/WebP), DOCX, PPTX, XLSX. Two orthogonal knobs control output — transport (tarball_b64 / inline / s3) and formats — both covered in Output modes.
MineruClientA small Python wrapper that lives in this repo. Best for prototyping and single-user scripts — usage is the snippet above. Install it with:
# pip
pip install "mineru-client @ git+https://github.com/sergeyshmakov/mineru-runpod"
# or uv
uv pip install "mineru-client @ git+https://github.com/sergeyshmakov/mineru-runpod"
For high-throughput, async, or non-Python callers. Hit the endpoint directly using the documented JSON payload contract.
import runpod
runpod.api_key = "..."
endpoint = runpod.Endpoint("<endpoint-id>")
result = endpoint.run_sync({"input": {"file_url": "https://example.com/report.pdf"}})
Already calling the MinerU cloud API (mineru.net/api/v4/...)? MineruApiClient mirrors its create_task / get_task surface over your own endpoint, so you can evaluate or migrate with a near-identical code path. See Migrate from the MinerU API.
Prototype with A; switch to B once you need async, retries, or multi-language callers. See Clients for the full comparison.
Send {"input": {...}} to /runsync (or /run). The most-used fields:
| Field | Required | Default | Notes |
|---|---|---|---|
file_url / file_b64 / volume_path | exactly one | — | Public URL, base64 bytes, or an absolute container path under the worker's input roots. Format auto-detected. |
end_page | no | -1 | 0-based inclusive; -1 = end of doc |
backend | no | "vlm-auto-engine" | pipeline / vlm-auto-engine / hybrid-* / *-http-client |
transport | no | "tarball_b64" | tarball_b64 / inline / s3 — how output ships back |
formats | no | all four | Subset of markdown / content_list / middle / images |
Responses wrap each file in a results: [...] list alongside a top-level debug block; failures set ok=false with a top-level error. The full field list, per-transport response shapes, and validation rules live in the API reference (mirrored from the docstring atop handler.py).
Under that contract, this repo is the MinerU half: the engine, the input schema and the job envelope. Fetching the input, checking outbound targets, packing the response, structured logging and the model-cache probe come from runpod-doc-worker (docs), an engine-agnostic harness extracted from this worker. What this worker declares to it — its env prefix, input roots and output manifest — is one file, worker/harness.py.
Parsing accuracy is MinerU's domain; their published OmniDocBench leaderboard puts the 1.2B VLM ahead of much larger general-purpose models:
Source: MinerU2.5-Pro-2605-1.2B model card and the MinerU 2.5 technical report.
| mineru-runpod (this) | Marker | GROBID | Nougat | |
|---|---|---|---|---|
| Scale-to-zero | ✅ ready to use | ⚠️ possible, needs extra setup | ❌ (always-on) | ❌ |
| GPU support | GPU only | CPU or GPU | CPU | GPU required |
| Equations | ✅ LaTeX | ✅ LaTeX | ❌ | ✅ LaTeX |
| Multi-lang | ✅ script-family OCR models (pipeline backend) | per upstream README | EN only | per upstream README |
| Setup time | 5 min | 10 min | 30 min | 20 min |
| License | MinerU Open Source License* | GPL-3.0 code + modified RAIL-M weights** | Apache 2.0 | MIT code + CC-BY-NC 4.0 weights |
| Commercial SaaS | ✅ permitted below stated thresholds* | ⚠️ depends on RAIL-M competitor clause** | ✅ free | ⚠️ subject to CC-BY-NC non-commercial clause |
*The MinerU Open Source License is based on Apache 2.0, requires attribution for third-party online services, and requires a separate commercial license when consolidated monthly active users exceed 100 million or total monthly revenue exceeds USD 20 million. Review the current upstream license for your use case.
**Marker's code is GPL-3.0; its OCR engine (Surya) ships under a modified RAIL-M licence whose §2(c) prohibits use by entities that "provide … any product or service that competes with … Licensor." Datalab's own README says Marker is free for "startups under $2M funding/revenue" — that carveout doesn't appear in the literal licence text, so the two read differently. Verify the current licence against your own usage with counsel before depending on Marker for a competing service. Datalab ships Chandra (the model behind their hosted API) under the same modified RAIL-M licence. See Surya MODEL_LICENSE and Chandra MODEL_LICENSE.
The license row matters for production use. Marker pairs GPL-3.0 code with modified RAIL-M weights whose competitor clause warrants review. Nougat's model weights are CC-BY-NC 4.0. GROBID is Apache 2.0. MinerU uses its own Apache-based license with additional terms, so evaluate the current upstream text rather than treating any of these projects as interchangeable on licensing.
The docs site covers the rest:
MineruClient vs. direct RunPod SDK| Version part | Moves when |
|---|---|
| Major | MinerU itself has a major release (currently pinned mineru[core,vllm]>=3.4.0,<3.5.0) |
| Minor | New features, and breaking changes to the job contract -- these lead the release notes under Job Contract Changes |
| Patch | Fixes and internal work |
The major is reserved for the engine because that is the change that moves output quality and behaviour. A template-contract break ships on a minor, so read the release notes before upgrading a minor -- they lead with anything that needs action.
A change that breaks pip install mineru-client -- a raised Python floor, a dropped
import path -- is also a minor, under Compatibility Changes. It is not a major:
nothing range-pins a git-URL install, so the release notes are what reach you, and
spending the major there would put it permanently out of step with MinerU.
The engine version is stated in the docs compatibility table rather than encoded in the version number.
See CONTRIBUTING.md. Commits follow Conventional Commits; commitlint enforces this in CI and CHANGELOG.md is generated automatically by semantic-release on push to main.
If this saves you time, the cheapest way to support development is to sign up for RunPod through this link. Costs you nothing extra and lets the maintainer keep iterating.
The wrapper code is MIT. The underlying MinerU and its model retain the MinerU Open Source License; the RunPod SDK is MIT.
Python
97.8%
Dockerfile
1.5%
📄 Serverless MinerU 2.5 Pro PDF parser on RunPod. Scales to zero. PDF → Markdown + JSON.
See the codeServerless MinerU document parser on RunPod. MinerU 3.4.x runtime with the MinerU2.5-Pro-2605-1.2B VLM. Scales to zero; best-case warm parses measured about $0.0003 per page on a 24 GB serverless RTX 4090.
Docs · Get started on RunPod · Blog
⚠️ Not an official MinerU project. This is an independent wrapper that packages the open-source MinerU runtime as a RunPod Serverless worker. It is not affiliated with, endorsed by, or supported by OpenDataLab, who publish MinerU, or by RunPod. Parsing behavior belongs upstream; anything about this worker belongs here.
Python (mineru_client):
from mineru_client import MineruClient
client = MineruClient(endpoint_id="<your-endpoint-id>")
result = client.parse_document(file_url="https://example.com/report.pdf", end_page=4)
client.save_tarball(result, "./out/doc")
# → markdown + content_list + middle.json + images
curl (no SDK):
curl -X POST "https://api.runpod.ai/v2/<endpoint-id>/runsync" \
-H "Authorization: Bearer $RUNPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":{"file_url":"https://example.com/report.pdf","end_page":4,"transport":"inline"}}'
The response wraps each parsed file as an entry inside results: [...]. For a single document, the markdown sits at output.results[0].markdown — pipe it straight to a file: curl ... | jq -r '.output.results[0].markdown' > report.md.
Accepts PDF, image (PNG/JPEG/GIF/BMP/TIFF/WebP), DOCX, PPTX, XLSX. Two orthogonal knobs control output — transport (tarball_b64 / inline / s3) and formats — both covered in Output modes.
MineruClientA small Python wrapper that lives in this repo. Best for prototyping and single-user scripts — usage is the snippet above. Install it with:
# pip
pip install "mineru-client @ git+https://github.com/sergeyshmakov/mineru-runpod"
# or uv
uv pip install "mineru-client @ git+https://github.com/sergeyshmakov/mineru-runpod"
For high-throughput, async, or non-Python callers. Hit the endpoint directly using the documented JSON payload contract.
import runpod
runpod.api_key = "..."
endpoint = runpod.Endpoint("<endpoint-id>")
result = endpoint.run_sync({"input": {"file_url": "https://example.com/report.pdf"}})
Already calling the MinerU cloud API (mineru.net/api/v4/...)? MineruApiClient mirrors its create_task / get_task surface over your own endpoint, so you can evaluate or migrate with a near-identical code path. See Migrate from the MinerU API.
Prototype with A; switch to B once you need async, retries, or multi-language callers. See Clients for the full comparison.
Send {"input": {...}} to /runsync (or /run). The most-used fields:
| Field | Required | Default | Notes |
|---|---|---|---|
file_url / file_b64 / volume_path | exactly one | — | Public URL, base64 bytes, or an absolute container path under the worker's input roots. Format auto-detected. |
end_page | no | -1 | 0-based inclusive; -1 = end of doc |
backend | no | "vlm-auto-engine" | pipeline / vlm-auto-engine / hybrid-* / *-http-client |
transport | no | "tarball_b64" | tarball_b64 / inline / s3 — how output ships back |
formats | no | all four | Subset of markdown / content_list / middle / images |
Responses wrap each file in a results: [...] list alongside a top-level debug block; failures set ok=false with a top-level error. The full field list, per-transport response shapes, and validation rules live in the API reference (mirrored from the docstring atop handler.py).
Under that contract, this repo is the MinerU half: the engine, the input schema and the job envelope. Fetching the input, checking outbound targets, packing the response, structured logging and the model-cache probe come from runpod-doc-worker (docs), an engine-agnostic harness extracted from this worker. What this worker declares to it — its env prefix, input roots and output manifest — is one file, worker/harness.py.
Parsing accuracy is MinerU's domain; their published OmniDocBench leaderboard puts the 1.2B VLM ahead of much larger general-purpose models:
Source: MinerU2.5-Pro-2605-1.2B model card and the MinerU 2.5 technical report.
| mineru-runpod (this) | Marker | GROBID | Nougat | |
|---|---|---|---|---|
| Scale-to-zero | ✅ ready to use | ⚠️ possible, needs extra setup | ❌ (always-on) | ❌ |
| GPU support | GPU only | CPU or GPU | CPU | GPU required |
| Equations | ✅ LaTeX | ✅ LaTeX | ❌ | ✅ LaTeX |
| Multi-lang | ✅ script-family OCR models (pipeline backend) | per upstream README | EN only | per upstream README |
| Setup time | 5 min | 10 min | 30 min | 20 min |
| License | MinerU Open Source License* | GPL-3.0 code + modified RAIL-M weights** | Apache 2.0 | MIT code + CC-BY-NC 4.0 weights |
| Commercial SaaS | ✅ permitted below stated thresholds* | ⚠️ depends on RAIL-M competitor clause** | ✅ free | ⚠️ subject to CC-BY-NC non-commercial clause |
*The MinerU Open Source License is based on Apache 2.0, requires attribution for third-party online services, and requires a separate commercial license when consolidated monthly active users exceed 100 million or total monthly revenue exceeds USD 20 million. Review the current upstream license for your use case.
**Marker's code is GPL-3.0; its OCR engine (Surya) ships under a modified RAIL-M licence whose §2(c) prohibits use by entities that "provide … any product or service that competes with … Licensor." Datalab's own README says Marker is free for "startups under $2M funding/revenue" — that carveout doesn't appear in the literal licence text, so the two read differently. Verify the current licence against your own usage with counsel before depending on Marker for a competing service. Datalab ships Chandra (the model behind their hosted API) under the same modified RAIL-M licence. See Surya MODEL_LICENSE and Chandra MODEL_LICENSE.
The license row matters for production use. Marker pairs GPL-3.0 code with modified RAIL-M weights whose competitor clause warrants review. Nougat's model weights are CC-BY-NC 4.0. GROBID is Apache 2.0. MinerU uses its own Apache-based license with additional terms, so evaluate the current upstream text rather than treating any of these projects as interchangeable on licensing.
The docs site covers the rest:
MineruClient vs. direct RunPod SDK| Version part | Moves when |
|---|---|
| Major | MinerU itself has a major release (currently pinned mineru[core,vllm]>=3.4.0,<3.5.0) |
| Minor | New features, and breaking changes to the job contract -- these lead the release notes under Job Contract Changes |
| Patch | Fixes and internal work |
The major is reserved for the engine because that is the change that moves output quality and behaviour. A template-contract break ships on a minor, so read the release notes before upgrading a minor -- they lead with anything that needs action.
A change that breaks pip install mineru-client -- a raised Python floor, a dropped
import path -- is also a minor, under Compatibility Changes. It is not a major:
nothing range-pins a git-URL install, so the release notes are what reach you, and
spending the major there would put it permanently out of step with MinerU.
The engine version is stated in the docs compatibility table rather than encoded in the version number.
See CONTRIBUTING.md. Commits follow Conventional Commits; commitlint enforces this in CI and CHANGELOG.md is generated automatically by semantic-release on push to main.
If this saves you time, the cheapest way to support development is to sign up for RunPod through this link. Costs you nothing extra and lets the maintainer keep iterating.
The wrapper code is MIT. The underlying MinerU and its model retain the MinerU Open Source License; the RunPod SDK is MIT.
Python
97.8%
Dockerfile
1.5%