marker将pdf转为Markdown
GitHub:
marker.git安装:
pip install marker-pdf
使用:
marker_single /path/to/file.pdf --force_ocr --use_llm --llm_service=marker.services.ollama.OllamaService --ollama_model=qwen3-vl:8b-instruct
Marker 快速且准确地将文档转换为 markdown、JSON、块和 HTML。
- 转换所有语言的 PDF、图像、PPTX、DOCX、XLSX、HTML、EPUB 文件
- 格式化表格、表单、方程、行内数学公式、链接、引用和代码块
- 提取并保存图像
- 去除页眉/页脚/其他无关内容
- 可扩展的格式和逻辑
- 根据给定的 JSON 模式进行结构化提取(测试版)
- 可选择使用 LLMs(以及您自己的提示)来提高准确性
- 可在 GPU、CPU 或 MPS 上运行
对于我们的托管 API 或本地部署文档智能解决方案,请通过 这里访问我们的平台 了解更多信息。
性能

Marker 的基准测试结果优于云服务(如 Llamaparse 和 Mathpix)以及其他开源工具。
上述结果是依次运行单个 PDF 页面。当以批处理模式运行时,Marker 的速度明显更快,在 H100 上的预计吞吐量为每秒 25 页。
请参见下方详细信息 ,了解速度和准确性的详细基准测试,以及如何运行您自己的基准测试的说明。
混合模式
为了达到最高精度,可以传递 --use_llm 标志,使用 LLM 与 marker 一起工作。这将执行诸如跨页合并表格、处理内联数学公式、正确格式化表格以及从表单中提取值等操作。它可以使用任何 gemini 或 ollama 模型。默认情况下,它使用 gemini-2.0-flash。有关详细信息,请参见 下方 。
以下是对比 marker、gemini flash 单独使用以及 marker 使用 LLM 的表格基准:

如你所见,使用 use_llm 模式提供的准确性比单独使用 marker 或 gemini 更高。
示例
商业用途
我们的模型权重使用了修改后的 AI Pubs Open Rail-M 许可证(用于研究、个人使用以及营收低于 200 万美元的初创公司时免费),而我们的代码采用 GPL 许可证。如需更广泛的商业许可证或去除 GPL 要求,请访问我们的定价页面 此处 。
托管 API & 本地部署
有一个 托管 API 和 简单的本地解决方案 可用于 marker – 注册是免费的,我们还会赠送一些积分供您试用。
API:
- 支持 PDF、图像、PPT、PPTX、DOC、DOCX、XLS、XLSX、HTML、EPUB 文件
- 1/4的价格是否是领先的基于云的竞争对手的价格
- 快速 – ~15 秒处理 250 页 PDF
- 支持 LLM 模式
- 高可用性(99.99%)
社区
Discord 是我们讨论未来开发的地方。
安装
您需要 Python 3.10+ 和 PyTorch。
通过以下方式安装:
pip install marker-pdf
如果你想在非 PDF 的文档上使用 marker,你需要通过以下方式安装额外的依赖项:
pip install marker-pdf[full]
用法
首先,一些配置:
- 您的 torch 设备将被自动检测,但您可以覆盖此设置。例如,
TORCH_DEVICE=cuda。 - 有些 PDF,即使是数字版的,其中的文本质量也可能很差。可以设置
--force_ocr强制对所有行进行 OCR,或者使用strip_existing_ocr保留所有数字文本,并去除任何现有的 OCR 文本。 - 如果你关心行内数学公式,请将
force_ocr设置为将行内数学公式转换为 LaTeX。
交互式应用
我提供了一个 streamlit 应用程序,可以让你通过一些基本选项交互式地尝试 marker。通过以下方式运行它:
pip install streamlit streamlit-ace marker_gui
转换单个文件
marker_single /path/to/file.pdf
你可以传入 PDF 或图像。
选项:
--page_range TEXT: 指定要处理的页面。接受用逗号分隔的页码和范围。示例:--page_range "0,5-10,20"将处理第 0 页、第 5 至 10 页以及第 20 页。--output_format [markdown|json|html|chunks]: 指定输出结果的格式。--output_dir PATH: 保存输出文件的目录。默认值为 settings.OUTPUT_DIR 中指定的值。--paginate_output: 对输出进行分页,使用\n\n{PAGE_NUMBER}后跟-* 48,然后是\n\n--use_llm: 使用 LLM 来提高准确性。你需要配置 LLM 后端 – 请参见 下方 。--force_ocr: 强制对整个文档进行 OCR 处理,即使页面中可能包含可提取的文本。这也将正确格式化内联数学公式。--block_correction_prompt: 如果启用了 LLM 模式,这是一个可选的提示,将用于修正 marker 的输出。这对于您想要应用到输出的自定义格式或逻辑非常有用。--strip_existing_ocr: 删除文档中所有现有的 OCR 文本,并使用 surya 重新进行 OCR。--redo_inline_math: 如果您希望获得最高质量的行内数学公式转换,请与--use_llm一起使用此选项。--disable_image_extraction: 不从 PDF 中提取图像。如果您还指定了--use_llm,则图像将被描述文字替换。--debug: 启用调试模式以获取额外的日志和诊断信息。--processors TEXT: 通过提供完整的模块路径(以逗号分隔)来覆盖默认的处理器。示例:--processors "module1.processor1,module2.processor2"--config_json PATH: 包含其他设置的 JSON 配置文件的路径。config --help: 列出所有可用的构建器、处理器和转换器及其相关配置。这些值可用于构建一个 JSON 配置文件,以便进一步调整 marker 的默认设置。--converter_cls: 为marker.converters.pdf.PdfConverter(默认)或marker.converters.table.TableConverter之一。PdfConverter会将整个 PDF 进行转换,而TableConverter仅提取并转换表格。--llm_service: 如果传递了--use_llm,使用哪个 LLM 服务。默认为marker.services.gemini.GoogleGeminiService。--help: 查看可以传递给 marker 的所有标志。(它支持比上面列出的更多选项)
surya OCR 支持的语言列表请参见 此处 。如果您不需要 OCR,marker 可以支持任何语言。
转换多个文件
marker /path/to/input/folder
marker支持以上marker_single中的所有相同选项。--workers表示同时运行的转换工作进程数量。默认情况下会自动设置,但你可以增加这个数值以提高吞吐量,代价是更高的 CPU/GPU 使用率。Marker 在峰值时每个工作进程会使用 5GB 的 VRAM,平均使用 3.5GB。
在多个 GPU 上转换多个文件
NUM_DEVICES=4 NUM_WORKERS=15 marker_chunk_convert ../pdf_in ../md_out
NUM_DEVICES表示使用的 GPU 数量。应为2或更大。NUM_WORKERS是在每个 GPU 上运行的并行进程数量。
从 Python 使用
请参见 marker/converters/pdf.py 文件中的 PdfConverter 类,以查看可以传递的其他参数。
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 将是一个 pydantic 基类模型,其属性会根据请求的输出类型有所不同。使用 markdown 输出(默认),您将拥有 markdown、metadata 和 images 属性。对于 json 输出,您将拥有 children、block_type 和 metadata 属性。
自定义配置
你可以使用 ConfigParser 来传递配置。要查看所有可用选项,请执行 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")
提取块
每个文档由一个或多个页面组成。页面包含块,这些块本身还可以包含其他块。可以编程方式操作这些块。
这是一个从文档中提取所有表单的示例:
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,))
查看处理器以获取更多关于提取和操作块的示例。
其他转换器
你也可以使用其他定义了不同转换流程的转换器:
提取表格
TableConverter 只会转换和提取表格:
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)
这使用与 PdfConverter 相同的所有配置。您可以指定配置 force_layout_block=Table 以避免布局检测,并假设每一页都是表格。设置 output_format=json 还可以获得单元格边界框。
你也可以通过 CLI 运行此命令
marker_single FILENAME --use_llm --force_layout_block Table --converter_cls marker.converters.table.TableConverter --output_format json
仅 OCR
如果你只想运行 OCR,也可以通过 OCRConverter 来实现。设置 --keep_chars 以保留单个字符和边界框。
from marker.converters.ocr import OCRConverter
from marker.models import create_model_dict
converter = OCRConverter(
artifact_dict=create_model_dict(),
)
rendered = converter("FILEPATH")
这使用与 PdfConverter 相同的所有配置。
你也可以通过 CLI 运行此命令
marker_single FILENAME --converter_cls marker.converters.ocr.OCRConverter
结构化提取(测试版)
你可以通过 ExtractionConverter 运行结构化提取。这需要首先设置一个 llm 服务(详见 此处 )。你将得到一个包含提取值的 JSON 输出。
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")
渲染结果将包含一个 original_markdown 字段。如果你下次运行转换器时将此字段作为 existing_markdown 配置键传回,就可以跳过重新解析文档。
输出格式
Markdown
Markdown 输出将包括:
- 图片链接(图片将保存在相同文件夹中)
- 格式化的表格
- 嵌入的 LaTeX 公式(用
$$包裹) - 代码用三个反引号包裹起来
- 脚注上标
HTML
HTML 输出与 markdown 输出类似:
- 图片是通过
img标签包含的 - 方程使用
<math>标签进行围栏 - 代码在
pre标签中
JSON
JSON 输出将采用树状结构组织,叶节点为块。叶节点的示例包括单个列表项、一段文本或一张图片。
输出将是一个列表,每个列表项代表一页。在内部 marker 架构中,每页被视为一个块。有不同的块类型来表示不同的元素。
页面具有以下键:
id– 块的唯一标识符。block_type– 块的类型。可能的块类型可以在marker/schema/__init__.py中看到。截至目前,它们是 [“Line”, “Span”, “FigureGroup”, “TableGroup”, “ListGroup”, “PictureGroup”, “Page”, “Caption”, “Code”, “Figure”, “Footnote”, “Form”, “Equation”, “Handwriting”, “TextInlineMath”, “ListItem”, “PageFooter”, “PageHeader”, “Picture”, “SectionHeader”, “Table”, “Text”, “TableOfContents”, “Document”]html– 页面的 HTML 代码。请注意,这将包含对子内容的递归引用。如果你想生成完整的 HTML,必须将content-ref标签替换为子内容。你可以在marker/output.py:json_to_html中看到这个例子。该函数将从 JSON 输出中获取一个单独的块,并将其转换为 HTML。polygon– 页面的四角多边形,格式为 (x1,y1), (x2,y2), (x3, y3), (x4, y4)。(x1,y1) 是左上角,坐标按顺时针方向排列。children– 子块。
子块有两个额外的键:
section_hierarchy– 表示该块所属的章节。1表示 h1 标签,2表示 h2,依此类推。images– 以 base64 编码的图像。键将是块的 ID,数据将是编码后的图像。
请注意,页面的子块也可以拥有自己的子块(树状结构)。
{
"id": "/page/10/Page/366",
"block_type": "Page",
"html": "<content-ref src='/page/10/SectionHeader/0'></content-ref><content-ref src='/page/10/SectionHeader/1'></content-ref><content-ref src='/page/10/Text/2'></content-ref><content-ref src='/page/10/Text/3'></content-ref><content-ref src='/page/10/Figure/4'></content-ref><content-ref src='/page/10/SectionHeader/5'></content-ref><content-ref src='/page/10/SectionHeader/6'></content-ref><content-ref src='/page/10/TextInlineMath/7'></content-ref><content-ref src='/page/10/TextInlineMath/8'></content-ref><content-ref src='/page/10/Table/9'></content-ref><content-ref src='/page/10/SectionHeader/10'></content-ref><content-ref src='/page/10/Text/11'></content-ref>",
"polygon": [[0.0, 0.0], [612.0, 0.0], [612.0, 792.0], [0.0, 792.0]],
"children": [
{
"id": "/page/10/SectionHeader/0",
"block_type": "SectionHeader",
"html": "<h1>Supplementary Material for <i>Subspace Adversarial Training</i> </h1>",
"polygon": [
[217.845703125, 80.630859375], [374.73046875, 80.630859375],
[374.73046875, 107.0],
[217.845703125, 107.0]
],
"children": null,
"section_hierarchy": {
"1": "/page/10/SectionHeader/1"
},
"images": {}
},
...
]
}
块
Chunks 格式类似于 JSON,但会将所有内容展平为一个单一列表,而不是树状结构。每页中只显示最顶层的块。它还包含每个块的完整 HTML 内容,因此无需爬取树结构即可重新构建它。这使得 RAG 的分块更加灵活和容易。
元数据
所有输出格式都将返回一个包含以下字段的元数据字典:
{
"table_of_contents": [
{
"title": "Introduction",
"heading_level": 1,
"page_id": 0,
"polygon": [...]
}
], // computed PDF table of contents
"page_stats": [
{
"page_id": 0,
"text_extraction_method": "pdftext",
"block_counts": [("Span", 200), ...]
},
...
]
}
LLM 服务
当使用 --use_llm 标志运行时,您可以选择使用的服务:
Gemini– 默认情况下,这将使用 Gemini 开发者 API。你需要将--gemini_api_key传递给配置。Google Vertex– 这将使用顶点,这可能更可靠。你需要传递--vertex_project_id。要使用它,请设置--llm_service=marker.services.vertex.GoogleVertexService。Ollama– 这将使用本地模型。您可以配置--ollama_base_url和--ollama_model。要使用它,请设置--llm_service=marker.services.ollama.OllamaService。Claude– 这将使用 anthropic API。您可以配置--claude_api_key和--claude_model_name。要使用它,请设置--llm_service=marker.services.claude.ClaudeService。OpenAI– 这支持任何类似 OpenAI 的端点。您可以配置--openai_api_key、--openai_model和--openai_base_url。要使用它,请设置--llm_service=marker.services.openai.OpenAIService。Azure OpenAI– 这使用了 Azure OpenAI 服务。您可以配置--azure_endpoint、--azure_api_key和--deployment_name。要使用它,请设置--llm_service=marker.services.azure_openai.AzureOpenAIService。
这些服务可能还有其他可选配置 – 你可以通过查看类来了解。
内部结构
Marker 易于扩展。Marker 的核心单元是:
Providers,位于marker/providers。这些提供者从源文件(如 PDF)中提取信息。Builders,位于marker/builders。这些生成初始的文档块并填充文本,使用来自提供者的信息。Processors,位于marker/processors。这些处理特定的块,例如表格格式化器是一个处理器。Renderers,位于marker/renderers。这些使用块来渲染输出。Schema,位于marker/schema。所有块类型的类。Converters,位于marker/converters。它们运行整个端到端的流程。
要自定义处理行为,请覆盖 processors。要添加新的输出格式,请编写一个新的 renderer。如需额外的输入格式,请编写一个新的 provider。
处理器和渲染器可以直接传递给基础的 PDFConverter,因此你可以轻松地指定自己的自定义处理方式。
API 服务器
有一个非常简单的 API 服务器,你可以像这样运行它:
pip install -U uvicorn fastapi python-multipart marker_server --port 8001
这将启动一个 fastapi 服务器,您可以通过 localhost:8001 访问。您可以前往 localhost:8001/docs 查看端点选项。
你可以这样发送请求:
import requests
import json
post_data = {
'filepath': 'FILEPATH',
# Add other params here
}
requests.post("http://localhost:8001/marker", data=json.dumps(post_data)).json()
请注意,这不是一个非常稳定的 API,仅适用于小规模使用。如果您想使用此服务器,但希望获得更稳定的转换选项,可以使用托管的 Datalab API。
故障排除
如果事情没有按你预期的方式进行,你会发现一些有用的设置:
- 如果对准确性有疑问,请尝试设置
--use_llm以使用 LLM 来提高质量。要使此功能生效,必须将GOOGLE_API_KEY设置为 Gemini API 密钥。 - 如果看到乱码文本,请确保设置
force_ocr– 这将重新对文档进行 OCR 处理。 TORCH_DEVICE– 设置此参数以强制 marker 使用指定的 torch 设备进行推理。- 如果你遇到内存不足的错误,请减少工作线程数量。你也可以尝试将长 PDF 文件拆分成多个文件。
调试
传递 debug 选项以激活调试模式。这将保存每页检测到的布局和文本的图像,并输出一个包含额外边界框信息的 json 文件。
基准测试
整体 PDF 转换
我们通过从常见爬取数据中提取单个 PDF 页面创建了一个 基准数据集 。我们根据一个将文本与真实文本段对齐的启发式方法进行评分,并使用一个 LLM 作为评分方法的裁判。
| 方法 | 平均时间 | 启发式得分 | LLM 分数 |
|---|---|---|---|
| marker | 2.83837 | 95.6709 | 4.23916 |
| llamaparse | 23.348 | 84.2442 | 3.97619 |
| mathpix | 6.36223 | 86.4281 | 4.15626 |
| docling | 3.69949 | 86.7073 | 3.70429 |
基准测试在 H100 上运行,用于 markjer 和 docling – llamaparse 和 mathpix 使用了他们的云服务。我们也可以按文档类型来看:

| 文档类型 | Marker 启发式方法 | Marker LLM | Llamaparse 启发式方法 | Llamaparse LLM | Mathpix 启发式方法 | Mathpix LLM | Docling Heuristic | Docling LLM |
|---|---|---|---|---|---|---|---|---|
| 科学论文 | 96.6737 | 4.34899 | 87.1651 | 3.96421 | 91.2267 | 4.46861 | 92.135 | 3.72422 |
| 书页 | 97.1846 | 4.16168 | 90.9532 | 4.07186 | 93.8886 | 4.35329 | 90.0556 | 3.64671 |
| 其他 | 95.1632 | 4.25076 | 81.1385 | 4.01835 | 79.6231 | 4.00306 | 83.8223 | 3.76147 |
| 表单 | 88.0147 | 3.84663 | 66.3081 | 3.68712 | 64.7512 | 3.33129 | 68.3857 | 3.40491 |
| 演示 | 95.1562 | 4.13669 | 81.2261 | 4 | 83.6737 | 3.95683 | 84.8405 | 3.86331 |
| 财务文件 | 95.3697 | 4.39106 | 82.5812 | 4.16111 | 81.3115 | 4.05556 | 86.3882 | 3.8 |
| 信 | 98.4021 | 4.5 | 93.4477 | 4.28125 | 96.0383 | 4.45312 | 92.0952 | 4.09375 |
| 工程文档 | 93.9244 | 4.04412 | 77.4854 | 3.72059 | 80.3319 | 3.88235 | 79.6807 | 3.42647 |
| 法律文件 | 96.689 | 4.27759 | 86.9769 | 3.87584 | 91.601 | 4.20805 | 87.8383 | 3.65552 |
| 报纸页面 | 98.8733 | 4.25806 | 84.7492 | 3.90323 | 96.9963 | 4.45161 | 92.6496 | 3.51613 |
| 杂志页面 | 98.2145 | 4.38776 | 87.2902 | 3.97959 | 93.5934 | 4.16327 | 93.0892 | 4.02041 |
吞吐量
我们通过使用一个 长 PDF 来评估吞吐量。
| 方法 | 每页耗时 | 每份文档的时间 | 已使用的显存 |
|---|---|---|---|
| marker | 0.18 | 43.42 | 3.17GB |
预计在 H100 上的吞吐量为每秒 122 页 – 考虑到使用的 VRAM,我们可以运行 22 个独立进程。
表格转换
Marker 可以使用 marker.converters.table.TableConverter 从 PDF 中提取表格。表格提取的性能是通过将提取出的表格的 HTML 表示与原始 HTML 表示进行比较,使用 FinTabNet 的测试分割来衡量的。HTML 表示是通过基于树编辑距离的指标进行比较,以判断结构和内容。Marker 能够检测并识别 PDF 页面中所有表格的结构,并实现了这些分数:
| 方法 | 平均分 | 总表格数 |
|---|---|---|
| marker | 0.816 | 99 |
| marker w/use_llm | 0.907 | 99 |
| gemini | 0.829 | 99 |
--use_llm 标志可以显著提高表格识别性能,如您所见。
我们过滤掉无法与真实数据对齐的表格,因为 fintabnet 和我们的布局模型检测方法略有不同(这导致一些表格被拆分/合并)。
运行您自己的基准测试
你可以在自己的设备上对 marker 的性能进行基准测试。手动安装 marker 的方法是:
git clone https://github.com/VikParuchuri/marker.git poetry install
整体 PDF 转换
下载基准数据 here 并解压缩。然后像这样运行整体基准测试:
python benchmarks/overall.py --methods marker --scores heuristic,llm
选项:
--use_llm使用 LLM 来提升 marker 的结果。--max_rows用于基准测试时要处理的行数。--methods可以是llamaparse,mathpix,docling,marker。用逗号分隔。--scores要使用的评分函数,可以是llm,heuristic。用逗号分隔。
表格转换
已处理的 FinTabNet 数据集托管 此处 并会自动下载。使用以下命令运行基准测试:
python benchmarks/table/table.py --max_rows 100
选项:
--use_llm使用 llm 与 marker 结合以提高准确性。--use_gemini还对 gemini 2.0 flash 进行基准测试。
它是如何工作的
Marker 是一个深度学习模型的流程:
- 提取文本,必要时进行 OCR(启发式方法,surya)
- 检测页面布局并确定阅读顺序(surya)
- 清理并格式化每个块(启发式方法,texify, surya)
- 可选择使用 LLM 来提高质量
- 合并块并处理完整文本
它只在必要时使用模型,这提高了速度和准确性。
限制
PDF 是一种复杂的格式,因此 marker 并不总能完美地工作。以下是一些已知的限制,这些问题正在计划中逐步解决:
- 非常复杂的布局,包含嵌套表格和表单,可能无法正常工作
- 表单可能无法正确显示
注意:传递 --use_llm 和 --force_ocr 标志通常可以解决这些问题。
使用和部署示例
你始终可以本地运行 marker,但如果你想将其作为 API 暴露出来,我们有几个选项:
- 我们的平台 API 由
marker和surya提供支持,易于测试 – 注册是免费的,我们将提供积分, 在这里试用 - 我们无痛的本地解决方案适用于商业用途,您可以 在这里阅读更多 ,并提供隐私保证和高吞吐量推理优化。
- 使用 Modal 部署的示例 ,展示了如何通过
Modal的网络端点部署和访问marker。Modal 是一个 AI 计算平台,使开发者能够在几分钟内部署和扩展 GPU 上的模型。
