A Developer’s Guide to OmniParseBench: Leaderboard Benchmarks and OCR Testing
In this tutorial, we implement OmniParseBench, Datalab’s open benchmark for document parsers, which grades a parser’s output with 16,288 small pass-or-fail tests across 2,937 pages, from scanned forms and handwriting to arXiv math and dense tables.
Rather than trust the leaderboard, we rebuild it from the verdicts Datalab released for 27 parsers, after feeding the scorer a hand-made page to see which mistakes flip a verdict.
We then measure ranking certainty, slice it by document type, test whether the two models the card names as helping build tests behave differently on tests a model corrected, and run Tesseract and Indra OCR ourselves on a 50-page sample.
Along the way, we find that the top two parsers are statistically tied, the leader changes on most slices, and one launch figure doesn’t match the released files.
Copy CodeCopiedUse a different Browserimport os import re import sys import json import time import html import shutil import platform import traceback import subprocess import collections import urllib.
request from pathlib import Path RESULTS = {} # step -> one-line result, for the summary table CLAIMS = [] # (step, claim, held) CURRENT = ["1"] def banner(title): print("\n" + "=" 78) print(title) print("=" 78) def section(name): def wrap(fn): def run(a, kw): CURRENT[0] = name.split(".
")[0] banner(name) t0 = time.time() try: out = fn(a, kw) RESULTS[name] = out if isinstance(out, str) else "ok" return out except Exception as e: RESULTS[name] = f"SKIPPED / FAILED -> {type(e).name}: {e}" print(f"\n[!] {name} did not complete: {type(e).name}: {e}") traceback.
printexc(limit=3) return None finally: print(f"\n[{time.time() - t0:.1f} s]") return run return wrap def claim(text, held): CLAIMS.append((CURRENT[0], text, bool(held))) return held banner("1.Install omni-parse-bench 1.0.0rc1 and Tesseract, and pin the dataset revision") SYSTEM = platform.
system() OPBVERSION = "1.0.0rc1" # a pre-release: a bare pip install omni-parse-bench resolves to 0.2.0, whose API differs REPO = "datalab-to/omniparsebench" REV = "961c0f89a2da701f5ce53afbd5e80aa469b0369a" # the dataset with the published verdicts of 27 parsers INDRA = ["indra-ocr==0.3.
2", "numpy==2.5.4", "onnxruntime==1.31.0", "opencv-python-headless==5.0.0.93", "pypdfium2==5.14.0", "huggingfacehub==2.2.0"] # the pins of the package's own Indra server image WORK = Path(os.environ.get("OPBWORK") or ("/content/opb" if os.path.isdir("/content") else "opbwork")).resolve() WORK.
mkdir(parents=True, existok=True) subprocess.run([sys.executable, "-m", "pip", "install", "-q", f"omni-parse-bench[benchmark]=={OPBVERSION}", "uv"], check=True) if SYSTEM == "Linux" and shutil.
which("tesseract") is None: scripts = ("arab armn beng cans cher cyrl deva ethi frak geor grek gujr guru hang hang-vert hans hans-vert hant " "hant-vert hebr jpan jpan-vert knda khmr laoo latn mlym mymr orya sinh syrc taml telu thaa thai tibt viet").split() subprocess.
run(["apt-get", "-qq", "update"], check=True) subprocess.run(["apt-get", "-qq", "install", "-y", "tesseract-ocr", "tesseract-ocr-eng", "tesseract-ocr-osd"] + [f"tesseract-ocr-script-{s}" for s in scripts], check=True, stdout=subprocess.
DEVNULL) import numpy as np import pandas as pd import importlib.metadata as md from huggingfacehub import snapshotdownload from omniparsebench import benchmark, data, harness, markdown, vocab from omniparsebench.scorers import unittests print(f"omni-parse-bench {md.
version('omni-parse-bench')}, Python {platform.pythonversion()}, {SYSTEM} {platform.machine()}, " f"{os.cpucount()} CPU cores") if SYSTEM == "Linux": print("os:", open("/etc/os-release").read().split('PRETTYNAME="')[1].split('"')[0]) tess = subprocess.
run(["tesseract", "--version"], captureoutput=True, text=True) print("tesseract:", (tess.stdout or tess.stderr).splitlines()[0]) TESSMAJOR = int((tess.stdout or tess.stderr).split()[1].split(".")[0]) print("test families:", {f: [t for t, g in vocab.FAMILIES.items() if g == f] for f in dict.
fromkeys(vocab.FAMILIES.values())}) print(f"dataset {REPO} @ {REV[:7]}; work folder {WORK}") RESULTS["1.Install omni-parse-bench 1.0.0rc1 and Tesseract, and pin the dataset revision"] = ( f"omni-parse-bench {md.version('omni-parse-bench')}, tesseract {(tess.stdout or tess.stderr).
split()[1]}, dataset @ {REV[:7]}") We install omni-parse-bench pinned to 1.0.0rc1, because a bare pip install still resolves to 0.2.0, an older release with a different API.
The benchmark extra brings the parser adapters, the Hugging Face client, and pyarrow for the manifest, and on Colab we add Tesseract with its script models through apt.We also pin the dataset to one commit, since the repository changes as parsers are added.
Printing the families shows the structure the benchmark rests on: present, order, and repeat tests form the text family; tablecell forms the tables family; and layoutkind forms the layout family.Copy CodeCopiedUse a different Browser@section("2.
How the scorer decides: one hand-built page, five test types, one change at a time") def scoreranatomy(): T = lambda i, tt, out, tags, args, st=None: {"id": i, "testtype": tt, "outputtype": out, "derivation": "authored", "tags": tags, "args": args, "settings": st or {}} exact = lambda s: {"text": s, "maxdiffs": 0} gold = [ T("title", "present", "html", ["heading"], {"content": exact("Quarterly Report")}), T("total", "present", "html", ["eng"], {"content": exact("Total due")}), T("growth", "present", "html", ["eng"], {"content": {"number": "-4.
8%"}}), T("amount", "present", "html", ["eng"], {"content": {"number": "1,240.
00"}}), T("eqratio", "present", "html", ["math"], {"content": {"latex": r"\alpha{1} + \beta"}}), T("eqhalf", "present", "html", ["math"], {"content": {"latex": r"\frac{1}{2} \to x"}}), T("order", "order", "html", ["eng"], {"before": exact("Introduction: this report covers the second quarter.
"), "after": exact("Conclusion: the plan holds.
")}), T("repeat", "repeat", "html", ["eng"], {"content": exact("Revenue")}, {"expectedcount": 2}), T("celltop", "tablecell", "html", ["table"], {"cell": exact("1,240"), "topheading": exact("2024")}), T("cellleft", "tablecell", "html", ["table"], {"cell": exact("1,240"), "leftheading": exact("Income")}), T("cellprice", "tablecell", "html", ["table"], {"cell": exact("9.
50"), "topheading": exact("Price"), "left": exact("Widget")}), T("blocktitle", "layoutkind", "blocks", ["heading"], {"content": dict(exact("Quarterly Report"), place=[[0.10, 0.04, 0.90, 0.
09]])}, {"kind": "heading"}), T("blocktotal", "layoutkind", "blocks", ["eng"], {"content": dict(exact("Total due"), place=[[0.10, 0.12, 0.90, 0.16]])}, {"kind": "text"}), ] goldfile = WORK / "fixture" / "gold" / "demo-p1.json" # a gold file is named after its page goldfile.parent.
mkdir(parents=True, existok=True) goldfile.writetext(json.dumps({"tests": gold}, indent=1)) page = data.Page(pageid="demo-p1", document="demo", suite="demo", docpath=WORK / "fixture" / "demo-p1.pdf", gtpath=goldfile, outputs=("blocks", "html")) tests = unittests.
gold(page) tablea = ("20232024Income1,0001,240" "Costs600700") tableb = "ProductPriceWidget9.50" mdtableb = "| Product | Price |\n|---|---|\n| Widget | 9.50 |" parts = {"title": "Quarterly Report
", "total": "Total due: 1,240.00 USD.
", "growth": "Growth was -4.8% year on year.
", "ratio": r"Ratio: 1+ holds.
", "half": r"Half: 12x in the model.
", "intro": "Introduction: this report covers the second quarter.
", "revenue": "Revenue is shown in thousands. Revenue grew in the second quarter.
", "tablea": tablea, "conclusion": "Conclusion: the plan holds.
", "tableb": tableb} blocks = [{"label": "heading", "bbox": [0.10, 0.04, 0.90, 0.09], "text": "Quarterly Report
Related
相關文章
PHP差點被遠程“開門”?OpenAI先發現,官方緊急補牆
編譯 | 黃菲 編輯 | 江宇 10月22日消息,昨日,美國AI公司OpenAI披露,其參與的安全研究工作協助發現了開源編程語言PHP中的兩項嚴重安全漏洞,即攻擊者在特定條件下無需身份驗證便可在受影響的服務器上執行代碼。目前,PHP項目已於10月21日發佈安全更新,修復這兩項漏洞。 此次漏洞排查由OpenAI發起的開源軟件安全項目Patch the Planet提供支持。該項目通過AI模型與安全工程手段,協助軟件維護者和安全研究人員發現、驗證並修復嚴重漏洞。
NVIDIA Nsight Python Tutorial: How to Profile GPU Kernels
In this tutorial, we implement on Nsight Python, NVIDIA’s open-source Python interface to its kernel profilers.Instead of running a script under the Nsight Compute command line and digging through a report afterward, we mark the code we care about with nsight.
榮耀掀桌電競手機!國補價2251元起,全系2K+185Hz、1萬mAh大電池
作者 | ZeR0 編輯 | 漠影 10月21日報道,今日,榮耀端出電競全家桶,一口氣發佈手機、平板、耳機、手柄、配件等多款電競新品。 榮耀WIN2和榮耀WIN RT2採用同款全新戰鬥美學設計,提供“指定贏”、“快開黑”、“紅藍Buff”三款配色,配備2K 185Hz雙芯綠洲屏與天王星超大風扇、LPDDR5X Ultra旗艦高速內存與UFS 4.1旗艦高速閃存。 該系列手機正面採用0.
人機跨界同框!破全馬記錄名將薩維、越野跑冠軍趙家駒與榮耀人形機器人“閃電”同臺競速
破全馬記錄名將薩維、越野跑冠軍趙家駒與榮耀人形機器人“閃電”同臺競速發布於AI新閒資訊時間 :Oct 20, 2026閱讀 :1分鐘10月20日,一場跨越人類極限與智能科技的特殊競速在線下震撼上演。榮耀全球首席跑步官、肯尼亞馬拉松名將薩巴斯蒂安·薩維,榮耀極限探索官、中國越野跑領軍人物趙家駒,與榮耀自研人形機器人“閃電”迎來了首次線下同框,並現場展開了同臺競速互動與跨賽道對話。
一張臉就能算出生死?AI 憑面部照片預測癌症患者存活率
AI 憑面部照片預測癌症患者存活率發布於AI新閒資訊時間 :Oct 20, 2026閱讀 :1分鐘據媒體報道,一支國際研究團隊近日拋出一款堪稱"讀臉斷生死"的 AI 工具——僅憑一張面部照片,就能推算癌症患者的生存機率。它並非要取代醫生,而是給臨床經驗當補充:在醫療資料匱乏、難以做全面評估的場景裡,尤顯價值。
全球首發:萬拿NOVA21靈巧手,拓展靈巧操作研究邊界
10月15日,在2026香港秋季電子產品展上,萬拿機器人全球首發NOVA21靈巧手。面向機器人科研與開發團隊,萬拿NOVA21採用21自由度全主動旋轉直驅設計,集靈巧、力量、精準與觸覺感知於一體,為多指協同、物品姿態調整與複雜操作策略研究提供執行與感知能力。21自由度全主動旋轉直驅,支持多指協同NOVA21採用擬人化佈局,整手尺寸為195×105×71mm,接近人手大小。拇指擁有5個主動自由度,其餘四指各擁有4個主動自由度。NOVA21的21個主動自由度均採用旋轉直驅,支持全手各指的主動控制與姿態調整。