Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Omni Parse Bench

test Python 3.11+ Code: Apache 2.0 Data: per source Dataset on Hugging Face

This repository contains a way to run our document-parsing benchmark using our dataset on HuggingFace or your own dataset. It also provides lower-level primitives (score and predict) to run in your own pipelines however you like. Every test is a yes/no question about one page: is this text in the output, in this order, in a table cell under these headings, etc. The README is split up into the following table of contents.

The design

The benchmark's design: headline, families, tests, args and tags

The headline is the mean of three family scores: text, tables and layout. A family is a group of test types:

test type checks family
present this text, number or equation appears text
order text A comes before text B text
repeat this line appears exactly N times text
table_cell this cell sits under these headings and beside these neighbors tables
layout_kind the block holding this line is a heading, text or table layout

A test checks one or more args, each of which is the content at one place on the page. Each arg is tagged:

  • structure: table, math, form and multi_column;
  • rendering: handwriting, tiny, rotated and degraded;
  • role: heading, caption, footnote, list, code, figure and header_footer;
  • script: ISO 15924 codes (Latn, Hani, Deva, ...); and
  • language: ISO 639-3 codes (eng, fra, tha, ...).

A test's tags are the union of its args' tags. Tags never decide whether a test passes or what the headline is. It is only used to query tests and rerank.

Install

uv pip install omni-parse-bench                 # score(): no network, no API keys
uv pip install 'omni-parse-bench[harness]'      # + vendor adapters, to predict
uv pip install 'omni-parse-bench[benchmark]'    # + dataset access, to run the benchmark

Run the benchmark

With [benchmark] installed, run vendors on the dataset (5 pages here):

opb benchmark --out runs/ --limit 5 --providers datalab openai/gpt-5.6-sol

It shows the plan and asks before calling any vendor; with no terminal to ask (a pipe, a notebook, CI) it goes ahead without asking, so a script runs as written. A run is resumable. Each setting of a provider is its own run. For example here we have two:

opb benchmark --out runs/ --limit 5 --providers datalab \
  --options '{"datalab": [{"mode": "balanced"}, {"mode": "accurate"}]}'

--dataset picks the dataset: a folder, or hf://datasets/<repo>[@revision] (ours by default). --suites, --sample and --pages choose pages. docs/API.md has every option.

Score

Here is one page with three tests. It is written inline with unit_tests.tests.parse so the gold file's shape is visible. unit_tests is the benchmark's scorer: it owns what a test is, and how one is graded.

from omni_parse_bench import data
from omni_parse_bench.scorers import unit_tests

tests = unit_tests.tests.parse("example-p1", {"tests": [
    {
        "id": "t1",
        "test_type": "present",
        "output_type": "html",
        "derivation": "text_layer",
        "tags": ["Latn", "eng"],
        "args": {"content": {"text": "Quarterly revenue rose 12%", "max_diffs": 1}},
        "settings": {},
    },
    {
        "id": "t2",
        "test_type": "order",
        "output_type": "html",
        "derivation": "text_layer",
        "tags": ["Latn", "eng", "heading"],
        "args": {
            "before": {"text": "Summary", "max_diffs": 0},
            "after": {"text": "Outlook", "max_diffs": 0},
        },
        "settings": {},
    },
    {
        "id": "t3",
        "test_type": "table_cell",
        "output_type": "html",
        "derivation": "publisher_markup",
        "tags": ["table"],
        "args": {
            "cell": {"text": "4.2", "max_diffs": 0},
            "top_heading": {"text": "Q3", "max_diffs": 0},
        },
        "settings": {},
    },
]})

pred = {
    "html": (
        "<h2>Summary</h2>"
        "<p>Quarterly revenue rose 12% on the year.</p>"
        "<table>"
        "<tr><th>Q2</th><th>Q3</th></tr>"
        "<tr><td>3.9</td><td>4.1</td></tr>"
        "</table>"
        "<h2>Outlook</h2>"
    ),
}
verdicts = unit_tests.score(pred, tests)
>>> verdicts
[Verdict(id='t1', result='pass', why=''),
 Verdict(id='t2', result='pass', why=''),
 Verdict(id='t3', result='fail', why="no cell matching '4.2' in any table")]

>>> page = data.Page("example-p1", "example", "example", "pages/example-p1.pdf", "gold/example-p1.json", ("html",))
>>> s = unit_tests.summarize(unit_tests.lines(verdicts, tests, page))["html"]
>>> s["score"], s["per_test_type"], s["per_tag"]["table"]
(0.6666666666666666, {'present': 1.0, 'order': 1.0, 'table_cell': 0.0}, {'score': 0.0, 'tests': 1, 'pages': 1, 'documents': 1})

A verdict is pass, fail or unsupported, with why saying what went wrong. unsupported verdicts are left out of every score. A test whose grading raises is a bug in our scorer: it is raised, naming the page and the test, not scored.

From the command line:

opb score --pred outputs.json --gold gold/<page_id>.json

It prints the verdicts.

A score is a number over many pages: summarize in your code, or summary.json from opb benchmark.

To grade predictions you brought on the benchmark see Grading your own predictions.

Predict

With [harness] installed, predict with our provider adapters:

from omni_parse_bench import harness
from omni_parse_bench.scorers import unit_tests

record = harness.predict("datalab", "pages/<page_id>.pdf", {"html", "blocks"}, mode="balanced")
record["outputs"]       # {"html": "...", "blocks": [...]}
record["errors"]        # {output: why} for anything that failed
record["calls"]         # what was sent, cost, wall time

unit_tests.score(record["outputs"], unit_tests.tests.read("gold/<page_id>.json"))

From the command line:

opb predict --provider openai/gpt-5.6-sol --page pages/<page_id>.pdf --wants html
opb providers        # every provider, and its options

Every provider gets the same timeout per call and its most accurate settings by default.

Documentation

Found a test that's wrong, or a page you hold rights in? Open an issue.

License

The code is Apache 2.0: see LICENSE, and NOTICE for the third-party code it includes (KaTeX, MIT; a rewrite of olmOCR-bench's table parser, Apache 2.0).

The data's licenses are per source. Each source of the pages, its license and the credit it requires are in licenses/, one file per source. The tests are CC BY 4.0, except those converted from olmOCR-bench (ODC-BY 1.0) and fr-bench-pdf2md (MIT), and those quoting Wikipedia on three handwriting pages (CC BY-SA 4.0).

Citation

@misc{omniparsebench2026,
  title        = {Omni Parse Bench: A Document-Parsing Benchmark},
  author       = {{Datalab}},
  year         = {2026},
  howpublished = {\url{https://github.com/datalab-to/omni_parse_bench}},
}

Please also cite the upstream datasets whose pages or tests this benchmark uses; they are listed in licenses/.

Metadata

Release files for omni-parse-bench 1.0.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for omni-parse-bench 1.0.0rc1
File Size Uploaded
omni_parse_bench-1.0.0rc1.tar.gz 541.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for omni-parse-bench 1.0.0rc1
File Interpreter ABI Platform
omni_parse_bench-1.0.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 937.3 kB

Release files / omni_parse_bench-1.0.0rc1.tar.gz

Download URL omni_parse_bench-1.0.0rc1.tar.gz
Size 541.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8bf2d98208dcb0fefa60152e44143d01f71962180077b1c695eda15b4cc0e4d8
BLAKE2b-256 checksum
How to use checksums
602d3dd09e6cf2661dfb440121d9dbfdf41c0fb139d7fbd913995d6869aff869
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / omni_parse_bench-1.0.0rc1-py3-none-any.whl

Download URL omni_parse_bench-1.0.0rc1-py3-none-any.whl
Size 396.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b66f9931792db7b31ef77aa9cd36759b0bd83b3591cfee522f5ee66e99902e4
BLAKE2b-256 checksum
How to use checksums
46d5a62cf15c19b2ca5b28ee7f0d548163c53a4e5d37701a5061226db49d6310
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0rc1 This release

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page