MCPcopy
hub / github.com/datalab-to/marker

github.com/datalab-to/marker @v1.10.2 sqlite

repository ↗ · DeepWiki ↗ · release v1.10.2 ↗
904 symbols 4,229 edges 209 files 58 documented · 6%
README

Marker

Marker converts documents to markdown, JSON, chunks, and HTML quickly and accurately.

  • Converts PDF, image, PPTX, DOCX, XLSX, HTML, EPUB files in all languages
  • Formats tables, forms, equations, inline math, links, references, and code blocks
  • Extracts and saves images
  • Removes headers/footers/other artifacts
  • Extensible with your own formatting and logic
  • Does structured extraction, given a JSON schema (beta)
  • Optionally boost accuracy with LLMs (and your own prompt)
  • Works on GPU, CPU, or MPS

For our managed API or on-prem document intelligence solution, check out our platform here.

Performance

Marker benchmarks favorably compared to cloud services like Llamaparse and Mathpix, as well as other open source tools.

The above results are running single PDF pages serially. Marker is significantly faster when running in batch mode, with a projected throughput of 25 pages/second on an H100.

See below for detailed speed and accuracy benchmarks, and instructions on how to run your own benchmarks.

Hybrid Mode

For the highest accuracy, pass the --use_llm flag to use an LLM alongside marker. This will do things like merge tables across pages, handle inline math, format tables properly, and extract values from forms. It can use any gemini or ollama model. By default, it uses gemini-2.0-flash. See below for details.

Here is a table benchmark comparing marker, gemini flash alone, and marker with use_llm:

As you can see, the use_llm mode offers higher accuracy than marker or gemini alone.

Examples

PDF File type Markdown JSON
Think Python Textbook View View
Switch Transformers arXiv paper View View
Multi-column CNN arXiv paper View View

Commercial usage

Our model weights use a modified AI Pubs Open Rail-M license (free for research, personal use, and startups under $2M funding/revenue) and our code is GPL. For broader commercial licensing or to remove GPL requirements, visit our pricing page here.

Hosted API & On-prem

There's a hosted API and painless on-prem solution for marker - it's free to sign up, and we'll throw in credits for you to test it out.

The API: - Supports PDF, image, PPT, PPTX, DOC, DOCX, XLS, XLSX, HTML, EPUB files - Is 1/4th the price of leading cloud-based competitors - Fast - ~15s for a 250 page PDF - Supports LLM mode - High uptime (99.99%)

Community

Discord is where we discuss future development.

Installation

You'll need python 3.10+ and PyTorch.

Install with:

pip install marker-pdf

If you want to use marker on documents other than PDFs, you will need to install additional dependencies with:

pip install marker-pdf[full]

Usage

First, some configuration:

  • Your torch device will be automatically detected, but you can override this. For example, TORCH_DEVICE=cuda.
  • Some PDFs, even digital ones, have bad text in them. Set --force_ocr to force OCR on all lines, or the strip_existing_ocr to keep all digital text, and strip out any existing OCR text.
  • If you care about inline math, set force_ocr to convert inline math to LaTeX.

Interactive App

I've included a streamlit app that lets you interactively try marker with some basic options. Run it with:

pip install streamlit streamlit-ace
marker_gui

Convert a single file

marker_single /path/to/file.pdf

You can pass in PDFs or images.

Options: - --page_range TEXT: Specify which pages to process. Accepts comma-separated page numbers and ranges. Example: --page_range "0,5-10,20" will process pages 0, 5 through 10, and page 20. - --output_format [markdown|json|html|chunks]: Specify the format for the output results. - --output_dir PATH: Directory where output files will be saved. Defaults to the value specified in settings.OUTPUT_DIR. - --paginate_output: Paginates the output, using \n\n{PAGE_NUMBER} followed by - * 48, then \n\n - --use_llm: Uses an LLM to improve accuracy. You will need to configure the LLM backend - see below. - --force_ocr: Force OCR processing on the entire document, even for pages that might contain extractable text. This will also format inline math properly. - --block_correction_prompt: if LLM mode is active, an optional prompt that will be used to correct the output of marker. This is useful for custom formatting or logic that you want to apply to the output. - --strip_existing_ocr: Remove all existing OCR text in the document and re-OCR with surya. - --redo_inline_math: If you want the absolute highest quality inline math conversion, use this along with --use_llm. - --disable_image_extraction: Don't extract images from the PDF. If you also specify --use_llm, then images will be replaced with a description. - --debug: Enable debug mode for additional logging and diagnostic information. - --processors TEXT: Override the default processors by providing their full module paths, separated by commas. Example: --processors "module1.processor1,module2.processor2" - --config_json PATH: Path to a JSON configuration file containing additional settings. - config --help: List all available builders, processors, and converters, and their associated configuration. These values can be used to build a JSON configuration file for additional tweaking of marker defaults. - --converter_cls: One of marker.converters.pdf.PdfConverter (default) or marker.converters.table.TableConverter. The PdfConverter will convert the whole PDF, the TableConverter will only extract and convert tables. - --llm_service: Which llm service to use if --use_llm is passed. This defaults to marker.services.gemini.GoogleGeminiService. - --help: see all of the flags that can be passed into marker. (it supports many more options then are listed above)

The list of supported languages for surya OCR is here. If you don't need OCR, marker can work with any language.

Convert multiple files

marker /path/to/input/folder
  • marker supports all the same options from marker_single above.
  • --workers is the number of conversion workers to run simultaneously. This is automatically set by default, but you can increase it to increase throughput, at the cost of more CPU/GPU usage. Marker will use 5GB of VRAM per worker at the peak, and 3.5GB average.

Convert multiple files on multiple GPUs

NUM_DEVICES=4 NUM_WORKERS=15 marker_chunk_convert ../pdf_in ../md_out
  • NUM_DEVICES is the number of GPUs to use. Should be 2 or greater.
  • NUM_WORKERS is the number of parallel processes to run on each GPU.

Use from python

See the PdfConverter class at marker/converters/pdf.py function for additional arguments that can be passed.

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("FILEPATH")
text, _, images = text_from_rendered(rendered)

rendered will be a pydantic basemodel with different properties depending on the output type requested. With markdown output (default), you'll have the properties markdown, metadata, and images. For json output, you'll have children, block_type, and metadata.

Custom configuration

You can pass configuration using the ConfigParser. To see all available options, do marker_single --help.

from marker.converters.pdf import PdfConverter
from marker.models import create_model_dict
from marker.config.parser import ConfigParser

config = {
    "output_format": "json",
    "ADDITIONAL_KEY": "VALUE"
}
config_parser = ConfigParser(config)

converter = PdfConverter(
    config=config_parser.generate_config_dict(),
    artifact_dict=create_model_dict(),
    processor_list=config_parser.get_processors(),
    renderer=config_parser.get_renderer(),
    llm_service=config_parser.get_llm_service()
)
rendered = converter("FILEPATH")

Extract blocks

Each document consists of one or more pages. Pages contain blocks, which can themselves contain other blocks. It's possible to programmatically manipulate these blocks.

Here's an example of extracting all forms from a document:

from marker.converters.pdf import PdfConverter
from marker.models import create_model_dict
from marker.schema import BlockTypes

converter = PdfConverter(
    artifact_dict=create_model_dict(),
)
document = converter.build_document("FILEPATH")
forms = document.contained_blocks((BlockTypes.Form,))

Look at the processors for more examples of extracting and manipulating blocks.

Other converters

You can also use other converters that define different conversion pipelines:

Extract tables

The TableConverter will only convert and extract tables:

from marker.converters.table import TableConverter
from marker.models import create_model_dict
from marker.output import text_from_rendered

converter = TableConverter(
    artifact_dict=create_model_dict(),
)
rendered = converter("FILEPATH")
text, _, images = text_from_rendered(rendered)

This takes all the same configuration as the PdfConverter. You can specify the configuration force_layout_block=Table to avoid layout detection and instead assume every page is a table. Set output_format=json to also get cell bounding boxes.

You can also run this via the CLI with

marker_single FILENAME --use_llm --force_layout_block Table --converter_cls marker.converters.table.TableConverter --output_format json

OCR Only

If you only want to run OCR, you can also do that through the OCRConverter. Set --keep_chars to keep individual characters and bounding boxes.

from marker.converters.ocr import OCRConverter
from marker.models import create_model_dict

converter = OCRConverter(
    artifact_dict=create_model_dict(),
)
rendered = converter("FILEPATH")

This takes all the same configuration as the PdfConverter.

You can also run this via the CLI with

marker_single FILENAME --converter_cls marker.converters.ocr.OCRConverter

Structured Extraction (beta)

You can run structured extraction via the ExtractionConverter. This requires an llm service to be setup first (see here for details). You'll get a JSON output with the extracted values.

from marker.converters.extraction import ExtractionConverter
from marker.models import create_model_dict
from marker.config.parser import ConfigParser
from pydantic import BaseModel

class Links(BaseModel):
    links: list[str]

schema = Links.model_json_schema()
config_parser = ConfigParser({
    "page_schema": schema
})

converter = ExtractionConverter(
    artifact_dict=create_model_dict(),
    config=config_parser.generate_config_dict(),
    llm_service=config_parser.get_llm_service(),
)
rendered = converter("FILEPATH")

Rendered will have an original_markdown field. If you pass this back in next time you run the converter, as the existing_markdown config key, you can skip re-parsing the document.

Output Formats

Markdown

Markdown output will include:

  • image links (images will be saved in the same folder)
  • formatted tables
  • embedded LaTeX equations (fenced with $$)
  • Code is fenced with triple backticks
  • Superscripts for footnotes

HTML

HTML output is similar to markdown output:

  • Images are included via img tags
  • equations are fenced with <math> tags
  • code is in pre tags

JSON

JSON output will be organized in a tree-like structure, with the leaf nodes being blocks. Examples of leaf nodes are a single list item, a paragraph of text, or an image.

The output will be a list, with each list item representing a page. Each page is considered a block in the internal marker schema. There are different types of blocks to represent different elements.

Pages have the keys:

  • id - unique id for the block.
  • block_type - the type of block. The possible block types can be seen in marker/schema/__init__.py. As of this writing, they are ["Line", "Span", "FigureGroup", "TableGroup", "ListGroup", "PictureGroup", "Page", "Caption", "Code", "Figure", "Footnot

Core symbols most depended-on inside this repo

contained_blocks
called by 71
marker/schema/document.py
get_block
called by 38
marker/schema/document.py
register_block_class
called by 31
marker/schema/registry.py
get_logger
called by 26
marker/logger.py
resolve_dependencies
called by 25
marker/converters/__init__.py
get_image
called by 22
marker/schema/blocks/base.py
update_metadata
called by 21
marker/schema/blocks/base.py
rescale
called by 17
marker/schema/polygon.py

Shape

Method 493
Function 213
Class 172
Route 26

Languages

Python100%

Modules by API surface

marker/schema/blocks/base.py31 symbols
marker/schema/polygon.py28 symbols
marker/schema/groups/page.py20 symbols
marker/renderers/markdown.py18 symbols
marker/processors/llm/__init__.py18 symbols
marker/providers/pdf.py17 symbols
marker/processors/table.py16 symbols
tests/conftest.py15 symbols
tests/services/test_service_init.py13 symbols
marker/util.py13 symbols
marker/providers/__init__.py13 symbols
marker/schema/text/span.py12 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add marker \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact