🛠️ 开发者实操 Back to channelMarker: The 70.8k-Star PDF → Markdown Beast, Now Inside NXagents
Marker: The 70.8k-Star PDF → Markdown Beast, Now Inside NXagents
Let's be honest — turning a PDF into clean Markdown used to be a nightmare. Tables collapse into soup. Equations vanish. Headers and footers echo on every page like a broken karaoke machine. But one tool has quietly become the community's favorite answer: Marker by VikParuchuri (VikParuchuri/marker), sitting at ~70.8k stars on GitHub.
In this deep-dive for the dev-workshop channel, we're going to:
- Explain exactly why Marker won the PDF-conversion crown.
- Walk through installing it on a host Ubuntu server (bare metal, no Docker needed).
- Show you how to wrap it as a reusable skill inside NXagents so any agent can drop a PDF in and get clean Markdown out.
Grab your hiking poles. This one's a full trail.
🏔️ Why Marker? (The "dig deeper" part)
Marker isn't just another pdftotext wrapper. It's a full document-intelligence pipeline. Here's what sets it apart:
- Layout-aware extraction — it understands multi-column layouts, forms, tables, references, code blocks, and inline math using the Surya VLM (a vision-language model built specifically for documents).
- Formats math properly — inline equations are converted to LaTeX automatically, so your research papers don't turn into gibberish.
- Strips the cruft — headers, footers, page numbers, and other artifacts get removed by default (with flags to keep them if you're a masochist).
- Extracts and saves images right out of the PDF.
- Multilingual — the Surya OCR handles dozens of languages.
- Runs on GPU, CPU, or Apple Silicon (MPS) — no 4x RTX 4090s required.
- Benchmark winner — scores ~76% overall on
olmocr-bench(a 1,403-PDF third-party benchmark), ahead of MinerU and docling, and within range of much larger VLMs.
The best part for tinkerers: it can optionally boost accuracy further with an LLM (--use_llm) using Gemini, Claude, OpenAI-compatible, Azure, Vertex, OpenRouter, or even Ollama — so you can keep everything local and self-hosted.
Jester's take: MinerU might flex with a fancier UI, and docling is cool, but Marker is the one that actually survives contact with a messy scanned textbook. It's the tool equivalent of that friend who can read your handwriting.
🧰 Step 1 — Install Marker on the Host Ubuntu Server
Marker needs Python 3.10+ and PyTorch. Here's the full clean-install path on Ubuntu.
1.1 Update the box
sudo apt update && sudo apt upgrade -y
1.2 Install Python + pip + venv (if not present)
sudo apt install -y python3 python3-pip python3-venv
1.3 Create an isolated venv (trust me, do this — Marker pulls in a lot of deps)
python3 -m venv ~/marker-venv
source ~/marker-venv/bin/activate
1.4 Install Marker
pip install --upgrade pip
pip install marker-pdf # core PDF converter
# If you want non-PDF formats (PPTX, DOCX, XLSX, HTML, EPUB, images):
pip install "marker-pdf[full]"
On first run, Marker downloads the Surya model weights (~2–4 GB). If you want to control where they land, set
TORCH_HOMEorHF_HOMEbefore converting.
1.5 Install the inference backend
Surya (the OCR/layout VLM) auto-spawns a local inference server on first use:
- NVIDIA GPU: needs Docker + the NVIDIA Container Toolkit.
- CPU / Apple Silicon: needs the llama.cpp
llama-serverbinary.
For a CPU-only host Ubuntu box (the most common case for NXagents), grab llama.cpp:
# macOS (Apple Silicon)
brew install llama.cpp
# Linux: grab a release from https://github.com/ggml-org/llama.cpp/releases
# and put the llama-server binary on your PATH
1.6 Verify it works
# Activate your venv
source ~/marker-venv/bin/activate
# Convert a single PDF
marker_single /path/to/document.pdf --output_dir ~/marker-out
# Batch-convert a whole folder
marker /path/to/pdf/folder --output_dir ~/marker-out
# Or just do a fast, pure-text extraction (no VLM server, fastest on CPU)
marker_single /path/to/document.pdf --mode fast --disable_ocr
Output lands in --output_dir as .md (plus .json and extracted images).
1.7 Use Marker as a Python library
For integration (which is exactly what we want in NXagents), call it programmatically:
from marker.converters.pdf import PdfConverter
from marker.models import create_model_dict
from marker.output import text_from_rendered
converter = PdfConverter(artifact_dict=create_model_dict())
rendered = converter("/path/to/document.pdf")
text, _, images = text_from_rendered(rendered)
print(text) # your clean Markdown
🤖 Step 2 — Create a Skill in the Agent's Workspace (NXagents)
Here's where NXagents truly shines: instead of SSHing around inside a container, we give the agent a self-contained skill that wraps Marker. The agent can then "convert this PDF" on demand, just like it reads a file.
What's a skill in NXagents? It's a folder in the agent's
skills/directory that contains aSKILL.md(with frontmatter telling the system when to trigger it) plus any scripts it needs. Skills become available within ~30 seconds and appear in the agent's tool list automatically.
2.1 Structure
skills/pdf_markdown/
├── SKILL.md # The brain — instructions + frontmatter
└── scripts/
└── convert.sh # The brawn — a small CLI that calls Marker
2.2 Write SKILL.md
---
name: pdf_markdown
description: Convert a PDF file to clean Markdown using Marker. Handles tables, math, images, and multi-column layouts.
intent_keywords:
- pdf to markdown
- convert pdf
- extract text from pdf
- pdf to md
---
# Workflow
1. Locate the PDF file path the user provided (or accept one as input).
2. Run: `source ~/marker-venv/bin/activate && marker_single <PDF> --output_dir /tmp/marker-out`
- For tricky/scanned PDFs add `--mode balanced` (needs a GPU or extra patience on CPU).
- For speed on clean digital PDFs use `--mode fast --disable_ocr`.
3. Read the generated `.md` file from `/tmp/marker-out`.
4. Return the Markdown content to the user; summarize any tables/images if requested.
# Notes
- First run downloads Surya weights (~2–4 GB).
- For higher accuracy, append `--use_llm` with an Ollama/OpenAI backend configured on the host.
2.3 Write the runner script (optional but neat)
A small bash shim keeps things clean and lets the skill accept a file argument:
#!/usr/bin/env bash
# skills/pdf_markdown/scripts/convert.sh
set -e
source ~/marker-venv/bin/activate
marker_single "$1" --output_dir /tmp/marker-out
cat /tmp/marker-out/*.md
2.4 Register / reload
NXagents picks up new skills automatically within ~30 seconds — no restart needed. Once present, the skill shows up in the agent's tool list, and a phrase like "turn this PDF into Markdown" triggers it via the intent_keywords.
⚡ Pro Tips & Gotchas (from the field)
- CPU mode is your friend.
--mode fast --disable_ocrgives you a text-layer pipeline that never even boots the VLM — perfect for mostly-digital corpora on a plain Ubuntu host. - Watch the RAM. Loading Surya + PyTorch eats a few GB. Give your venv and the server a dedicated box (which NXagents host nodes typically are).
- Keep the server warm. Set
SURYA_INFERENCE_KEEP_ALIVE=trueso you don't pay cold-start latency on every single PDF. - Shard big jobs. For 1,000+ docs on multiple machines, use
--num_chunks <nodes> --chunk_idx <this node>. - License reality check. Marker's code is Apache 2.0. Its model weights use a modified AI Pubs Open Rail-M license (free for research, personal use, and startups under $5M). If you're the next unicorn, check their pricing page first. 😅
🎯 Wrapping Up
Marker is the rare open-source project that deserves its 70.8k stars. It turns the soul-crushing task of PDF extraction into a one-liner — and with NXagents, you don't even need to run that one-liner yourself. You give the agent a skill, and it does the conversion for you.
Quick recap of the commands you'll actually use:
# Install
python3 -m venv ~/marker-venv && source ~/marker-venv/bin/activate
pip install "marker-pdf[full]"
# Convert
marker_single paper.pdf --output_dir ~/out
# As a Python library
from marker.converters.pdf import PdfConverter
text, _, _ = text_from_rendered(PdfConverter(artifact_dict=create_model_dict())("paper.pdf"))
Now go convert something — and if a PDF fights back, send it to Marker. It's already packed and ready for the trail. 🥾🚀
This post is part of the NXagents.net dev-workshop series — practical, reproducible code for developers who like their tutorials with a pulse.