Delores-Lin commited on
Commit
e841d2f
·
verified ·
1 Parent(s): 37963e0

Publish initial MDPBench leaderboard

Browse files
Files changed (8) hide show
  1. .gitignore +3 -0
  2. README.md +33 -4
  3. app.js +56 -0
  4. index.html +67 -17
  5. leaderboard.json +918 -0
  6. model_metadata.js +39 -0
  7. style.css +16 -28
  8. tools/sync_leaderboard.py +193 -0
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ .DS_Store
README.md CHANGED
@@ -1,10 +1,39 @@
1
  ---
2
  title: MDPBench Leaderboard
3
- emoji: 📊
4
- colorFrom: red
5
- colorTo: green
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: MDPBench Leaderboard
3
+ emoji: 📄
4
+ colorFrom: blue
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
+ # MDPBench Leaderboard
11
+
12
+ Static, official leaderboard for **MDPBench: A Benchmark for Multilingual
13
+ Document Parsing in Real-World Scenarios**.
14
+
15
+ The deployed page needs no server or API key. Update `leaderboard.json` to
16
+ publish a new verified result. The initial entries are the results in the
17
+ repository's main-results table; `source_name` keeps the original table label
18
+ where the displayed official release/API identifier is more specific. The
19
+ initial board contains all 31 models from that table.
20
+
21
+ Before publishing an updated result table, synchronize the data and verify the
22
+ result:
23
+
24
+ ```bash
25
+ python tools/sync_leaderboard.py --write
26
+ python tools/sync_leaderboard.py --check
27
+ ```
28
+
29
+ ## Deployment
30
+
31
+ Create a Hugging Face Space with the **Static** SDK and upload the contents of
32
+ this directory. Its `README.md` metadata configures the Space automatically.
33
+
34
+ ## Result policy
35
+
36
+ Public scores can be reproduced using the released evaluation set. Private
37
+ scores are evaluated by the MDPBench maintainers; a model is ranked by private
38
+ score only after that verification. See the benchmark README for the private-set
39
+ submission procedure.
app.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const state = { sort: "overall", query: "", type: "all" };
2
+ const languages = ["DE", "EN", "ES", "FR", "ID", "IT", "NL", "PT", "VI", "AR", "HI", "JP", "KO", "RU", "TH", "ZH", "ZH-T"];
3
+
4
+ function value(score) {
5
+ return Number.isFinite(score) ? score.toFixed(1) : "—";
6
+ }
7
+
8
+ function metadata(model) {
9
+ return MODEL_METADATA[model.name] || { label: model.name, url: null };
10
+ }
11
+
12
+ function makeDetail(model) {
13
+ const rows = languages.map((language) => `<span><b>${language}</b>${value(model.languages[language])}</span>`).join("");
14
+ const source = model.source_name ? `<p class="source-note">Benchmark table label: <code>${model.source_name}</code></p>` : "";
15
+ return `<tr class="detail-row"><td colspan="10"><div class="details"><div><p class="detail-title">Language-level public scores</p><div class="language-grid">${rows}</div></div>${source}</div></td></tr>`;
16
+ }
17
+
18
+ function render(data) {
19
+ const models = data.models
20
+ .filter((m) => state.type === "all" || m.type === state.type)
21
+ .filter((m) => `${m.name} ${m.source_name || ""}`.toLowerCase().includes(state.query))
22
+ .sort((a, b) => b[state.sort] - a[state.sort]);
23
+ const body = document.querySelector("#leaderboard-body");
24
+ body.innerHTML = models.map((model, index) => `
25
+ <tr class="model-row">
26
+ <td class="rank">${index + 1}</td><td><span class="model-name">${metadata(model).label}</span>${metadata(model).url ? `<a class="model-link" href="${metadata(model).url}" target="_blank" rel="noreferrer" aria-label="Open official model page for ${metadata(model).label}">↗</a>` : ""}</td>
27
+ <td><span class="type type-${model.type.toLowerCase().replaceAll(" ", "-")}">${model.type}</span></td>
28
+ <td class="score featured">${value(model.overall)}</td><td class="score">${value(model.digital)}</td><td class="score">${value(model.photo)}</td>
29
+ <td class="score">${value(model.latin)}</td><td class="score">${value(model.non_latin)}</td><td class="score private">${value(model.private)}</td>
30
+ <td><button class="expand" aria-label="Show language scores">+</button></td>
31
+ </tr>${makeDetail(model)}`).join("");
32
+ body.querySelectorAll(".model-row").forEach((row) => {
33
+ const toggle = () => {
34
+ const detail = row.nextElementSibling;
35
+ const open = detail.classList.toggle("show");
36
+ row.querySelector(".expand").textContent = open ? "−" : "+";
37
+ row.querySelector(".model-name").setAttribute("aria-expanded", String(open));
38
+ };
39
+ row.querySelector(".expand").addEventListener("click", toggle);
40
+ });
41
+ }
42
+
43
+ fetch("leaderboard.json")
44
+ .then((response) => response.json())
45
+ .then((data) => {
46
+ document.querySelector("#updated").textContent = `Last updated · ${data.benchmark.updated}`;
47
+ render(data);
48
+ document.querySelectorAll("[data-sort]").forEach((button) => button.addEventListener("click", () => {
49
+ state.sort = button.dataset.sort;
50
+ document.querySelectorAll("[data-sort]").forEach((item) => item.classList.toggle("active", item === button));
51
+ render(data);
52
+ }));
53
+ document.querySelector("#search").addEventListener("input", (event) => { state.query = event.target.value.toLowerCase().trim(); render(data); });
54
+ document.querySelector("#type-filter").addEventListener("change", (event) => { state.type = event.target.value; render(data); });
55
+ })
56
+ .catch(() => { document.querySelector("#leaderboard-body").innerHTML = '<tr><td colspan="10" class="error">Could not load leaderboard data.</td></tr>'; });
index.html CHANGED
@@ -1,19 +1,69 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>MDPBench Leaderboard</title>
7
+ <meta name="description" content="Official leaderboard for MDPBench, a benchmark for multilingual document parsing in real-world scenarios." />
8
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
+ <link href="https://fonts.googleapis.com/css2?family=DM+Mono&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
11
+ <link rel="stylesheet" href="style.css" />
12
+ </head>
13
+ <body>
14
+ <main class="shell">
15
+ <header class="hero">
16
+ <a class="brand" href="https://github.com/Yuliang-Liu/MultimodalOCR" target="_blank" rel="noreferrer">MDP<span>Bench</span></a>
17
+ <p class="eyebrow">Official leaderboard · Multilingual document parsing</p>
18
+ <h1>How well do models parse<br /><em>documents in the real world?</em></h1>
19
+ <p class="intro">A unified evaluation across 17 languages, native digital pages, and photographed documents. Scores are shown as percentages; higher is better.</p>
20
+ <div class="links">
21
+ <a href="https://arxiv.org/abs/2603.28130" target="_blank" rel="noreferrer">Paper ↗</a>
22
+ <a href="https://huggingface.co/datasets/Delores-Lin/MDPBench" target="_blank" rel="noreferrer">Dataset ↗</a>
23
+ <a href="https://github.com/Yuliang-Liu/MultimodalOCR" target="_blank" rel="noreferrer">GitHub ↗</a>
24
+ </div>
25
+ </header>
26
+
27
+ <section class="at-a-glance" aria-label="Benchmark facts">
28
+ <div><strong>3,400</strong><span>document images</span></div>
29
+ <div><strong>17</strong><span>languages</span></div>
30
+ <div><strong>3</strong><span>parsing tasks</span></div>
31
+ <div><strong>2</strong><span>evaluation splits</span></div>
32
+ </section>
33
+
34
+ <section class="board" aria-labelledby="board-title">
35
+ <div class="board-topline">
36
+ <div>
37
+ <p class="eyebrow">Verified results</p>
38
+ <h2 id="board-title">Leaderboard</h2>
39
+ </div>
40
+ <p id="updated" class="updated"></p>
41
+ </div>
42
+
43
+ <div class="controls">
44
+ <div class="rank-tabs" role="group" aria-label="Ranking score">
45
+ <button class="active" data-sort="overall">Public Overall</button>
46
+ <button data-sort="private">Private Overall</button>
47
+ </div>
48
+ <label class="search"><span class="sr-only">Search models</span><input id="search" type="search" placeholder="Search model" /></label>
49
+ <label class="select-label"><span>Model family</span><select id="type-filter"><option value="all">All types</option><option>General VLM</option><option>Specialized VLM</option><option>Pipeline Tool</option></select></label>
50
+ </div>
51
+
52
+ <div class="table-wrap">
53
+ <table>
54
+ <thead><tr><th>Rank</th><th>Model</th><th>Type</th><th>Overall</th><th>Digital</th><th>Photo</th><th>Latin</th><th>Non-Latin</th><th>Private</th><th aria-label="Details"></th></tr></thead>
55
+ <tbody id="leaderboard-body"></tbody>
56
+ </table>
57
+ </div>
58
+ </section>
59
+
60
+ <section class="methodology">
61
+ <div><p class="eyebrow">How to read this board</p><h2>One number, with the context still visible.</h2></div>
62
+ <div class="method-copy"><p>The public score is calculated over released samples. Private scores use the held-out split and are the basis for verified comparison. Digital and Photo expose the real-world robustness gap; Latin and Non-Latin avoid hiding language imbalance behind an average.</p><p>To add a model, run the released evaluation pipeline, then provide inference code, weights or API details, and predictions for official private-set evaluation.</p></div>
63
+ </section>
64
+ </main>
65
+ <footer>MDPBench · Results are maintained by the benchmark authors.</footer>
66
+ <script src="model_metadata.js"></script>
67
+ <script src="app.js"></script>
68
+ </body>
69
  </html>
leaderboard.json ADDED
@@ -0,0 +1,918 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "benchmark": {
3
+ "name": "MDPBench",
4
+ "version": "Initial official results",
5
+ "updated": "2026-07-20",
6
+ "metric": "Page-level mean of available text, formula, and table task scores (×100)",
7
+ "private_policy": "Private scores are run and verified by the MDPBench maintainers."
8
+ },
9
+ "models": [
10
+ {
11
+ "type": "General VLM",
12
+ "name": "gemini-3-pro-preview",
13
+ "overall": 86.4,
14
+ "digital": 90.4,
15
+ "photo": 85.1,
16
+ "latin": 88.4,
17
+ "non_latin": 84.1,
18
+ "private": 89.8,
19
+ "languages": {
20
+ "DE": 91.2,
21
+ "EN": 90.6,
22
+ "ES": 83.4,
23
+ "FR": 82.7,
24
+ "ID": 91.5,
25
+ "IT": 91.6,
26
+ "NL": 87.7,
27
+ "PT": 91.4,
28
+ "VI": 85.9,
29
+ "AR": 89.4,
30
+ "HI": 90.4,
31
+ "JP": 74.8,
32
+ "KO": 85.5,
33
+ "RU": 84.9,
34
+ "TH": 80.6,
35
+ "ZH": 85.1,
36
+ "ZH-T": 82.1
37
+ },
38
+ "source_name": "Gemini-3-pro-preview"
39
+ },
40
+ {
41
+ "type": "General VLM",
42
+ "name": "kimi-k2.5",
43
+ "overall": 77.5,
44
+ "digital": 85.0,
45
+ "photo": 75.0,
46
+ "latin": 81.6,
47
+ "non_latin": 72.9,
48
+ "private": 81.2,
49
+ "languages": {
50
+ "DE": 85.9,
51
+ "EN": 86.2,
52
+ "ES": 72.7,
53
+ "FR": 71.0,
54
+ "ID": 80.6,
55
+ "IT": 86.6,
56
+ "NL": 77.4,
57
+ "PT": 87.6,
58
+ "VI": 86.2,
59
+ "AR": 75.8,
60
+ "HI": 74.5,
61
+ "JP": 72.5,
62
+ "KO": 70.9,
63
+ "RU": 61.8,
64
+ "TH": 67.0,
65
+ "ZH": 81.7,
66
+ "ZH-T": 78.6
67
+ },
68
+ "source_name": "kimi-K2.5"
69
+ },
70
+ {
71
+ "type": "General VLM",
72
+ "name": "doubao-seed-2-0-pro-260215",
73
+ "overall": 74.2,
74
+ "digital": 78.9,
75
+ "photo": 72.8,
76
+ "latin": 75.7,
77
+ "non_latin": 72.5,
78
+ "private": 79.5,
79
+ "languages": {
80
+ "DE": 82.8,
81
+ "EN": 74.4,
82
+ "ES": 69.0,
83
+ "FR": 70.0,
84
+ "ID": 73.3,
85
+ "IT": 82.0,
86
+ "NL": 69.9,
87
+ "PT": 83.4,
88
+ "VI": 76.5,
89
+ "AR": 81.3,
90
+ "HI": 75.7,
91
+ "JP": 65.8,
92
+ "KO": 74.7,
93
+ "RU": 63.3,
94
+ "TH": 71.9,
95
+ "ZH": 71.9,
96
+ "ZH-T": 75.2
97
+ },
98
+ "source_name": "Doubao-2.0-pro"
99
+ },
100
+ {
101
+ "type": "General VLM",
102
+ "name": "claude-sonnet-4-6",
103
+ "overall": 73.1,
104
+ "digital": 85.0,
105
+ "photo": 69.3,
106
+ "latin": 79.2,
107
+ "non_latin": 66.2,
108
+ "private": 77.6,
109
+ "languages": {
110
+ "DE": 79.8,
111
+ "EN": 80.6,
112
+ "ES": 72.8,
113
+ "FR": 66.5,
114
+ "ID": 82.3,
115
+ "IT": 83.3,
116
+ "NL": 76.7,
117
+ "PT": 88.0,
118
+ "VI": 83.1,
119
+ "AR": 67.8,
120
+ "HI": 71.7,
121
+ "JP": 63.4,
122
+ "KO": 64.3,
123
+ "RU": 70.8,
124
+ "TH": 65.2,
125
+ "ZH": 61.3,
126
+ "ZH-T": 65.1
127
+ },
128
+ "source_name": "Claude-Sonnet-4.6"
129
+ },
130
+ {
131
+ "type": "General VLM",
132
+ "name": "gpt-5.2-2025-12-11",
133
+ "overall": 68.6,
134
+ "digital": 85.6,
135
+ "photo": 63.0,
136
+ "latin": 75.2,
137
+ "non_latin": 61.1,
138
+ "private": 74.0,
139
+ "languages": {
140
+ "DE": 70.8,
141
+ "EN": 79.4,
142
+ "ES": 71.4,
143
+ "FR": 60.0,
144
+ "ID": 77.7,
145
+ "IT": 78.5,
146
+ "NL": 71.6,
147
+ "PT": 85.0,
148
+ "VI": 82.1,
149
+ "AR": 64.9,
150
+ "HI": 63.4,
151
+ "JP": 55.8,
152
+ "KO": 65.4,
153
+ "RU": 60.7,
154
+ "TH": 63.8,
155
+ "ZH": 56.3,
156
+ "ZH-T": 58.7
157
+ },
158
+ "source_name": "ChatGPT-5.2-2025-12-11"
159
+ },
160
+ {
161
+ "type": "General VLM",
162
+ "name": "Qwen3-VL-8B-Instruct",
163
+ "overall": 68.3,
164
+ "digital": 78.4,
165
+ "photo": 65.0,
166
+ "latin": 73.6,
167
+ "non_latin": 62.5,
168
+ "private": 70.8,
169
+ "languages": {
170
+ "DE": 73.7,
171
+ "EN": 71.4,
172
+ "ES": 69.3,
173
+ "FR": 66.2,
174
+ "ID": 68.5,
175
+ "IT": 79.1,
176
+ "NL": 78.3,
177
+ "PT": 82.2,
178
+ "VI": 73.4,
179
+ "AR": 63.1,
180
+ "HI": 58.4,
181
+ "JP": 59.9,
182
+ "KO": 61.9,
183
+ "RU": 57.9,
184
+ "TH": 62.0,
185
+ "ZH": 62.6,
186
+ "ZH-T": 73.8
187
+ },
188
+ "source_name": "Qwen3-VL-Instruct-8b"
189
+ },
190
+ {
191
+ "type": "General VLM",
192
+ "name": "Qwen3.5-Instruct-9B",
193
+ "overall": 65.7,
194
+ "digital": 74.8,
195
+ "photo": 62.7,
196
+ "latin": 72.5,
197
+ "non_latin": 58.2,
198
+ "private": 68.9,
199
+ "languages": {
200
+ "DE": 72.8,
201
+ "EN": 72.0,
202
+ "ES": 72.0,
203
+ "FR": 64.4,
204
+ "ID": 66.2,
205
+ "IT": 77.6,
206
+ "NL": 74.5,
207
+ "PT": 79.1,
208
+ "VI": 74.0,
209
+ "AR": 53.4,
210
+ "HI": 56.2,
211
+ "JP": 55.7,
212
+ "KO": 60.3,
213
+ "RU": 54.7,
214
+ "TH": 56.7,
215
+ "ZH": 60.8,
216
+ "ZH-T": 67.5
217
+ }
218
+ },
219
+ {
220
+ "type": "General VLM",
221
+ "name": "InternVL3_5-8B",
222
+ "overall": 42.7,
223
+ "digital": 59.7,
224
+ "photo": 37.0,
225
+ "latin": 53.4,
226
+ "non_latin": 30.6,
227
+ "private": 45.3,
228
+ "languages": {
229
+ "DE": 39.8,
230
+ "EN": 64.2,
231
+ "ES": 47.5,
232
+ "FR": 42.7,
233
+ "ID": 53.8,
234
+ "IT": 60.6,
235
+ "NL": 52.2,
236
+ "PT": 63.2,
237
+ "VI": 57.0,
238
+ "AR": 8.2,
239
+ "HI": 9.0,
240
+ "JP": 45.6,
241
+ "KO": 30.3,
242
+ "RU": 26.1,
243
+ "TH": 10.8,
244
+ "ZH": 55.3,
245
+ "ZH-T": 59.3
246
+ },
247
+ "source_name": "InternVL-3.5-8B"
248
+ },
249
+ {
250
+ "type": "Specialized VLM",
251
+ "name": "MonkeyOCRv2-B-Parsing",
252
+ "overall": 83.3,
253
+ "digital": 88.1,
254
+ "photo": 81.7,
255
+ "latin": 84.2,
256
+ "non_latin": 82.1,
257
+ "private": 84.7,
258
+ "languages": {
259
+ "DE": 87.7,
260
+ "EN": 84.5,
261
+ "ES": 75.2,
262
+ "FR": 78.4,
263
+ "ID": 86.5,
264
+ "IT": 88.6,
265
+ "NL": 86.1,
266
+ "PT": 87.9,
267
+ "VI": 83.2,
268
+ "AR": 90.7,
269
+ "HI": 87.2,
270
+ "JP": 71.9,
271
+ "KO": 87.6,
272
+ "RU": 80.1,
273
+ "TH": 80.8,
274
+ "ZH": 83.6,
275
+ "ZH-T": 75.3
276
+ }
277
+ },
278
+ {
279
+ "type": "Specialized VLM",
280
+ "name": "MonkeyOCRv2-S-Parsing",
281
+ "overall": 82.5,
282
+ "digital": 87.9,
283
+ "photo": 80.7,
284
+ "latin": 83.2,
285
+ "non_latin": 81.7,
286
+ "private": 84.0,
287
+ "languages": {
288
+ "DE": 87.3,
289
+ "EN": 83.6,
290
+ "ES": 76.8,
291
+ "FR": 73.6,
292
+ "ID": 85.4,
293
+ "IT": 87.2,
294
+ "NL": 85.5,
295
+ "PT": 87.4,
296
+ "VI": 81.9,
297
+ "AR": 91.2,
298
+ "HI": 87.1,
299
+ "JP": 69.9,
300
+ "KO": 88.7,
301
+ "RU": 78.0,
302
+ "TH": 79.8,
303
+ "ZH": 84.4,
304
+ "ZH-T": 74.7
305
+ }
306
+ },
307
+ {
308
+ "type": "Specialized VLM",
309
+ "name": "dots.mocr",
310
+ "overall": 80.5,
311
+ "digital": 90.5,
312
+ "photo": 77.2,
313
+ "latin": 81.7,
314
+ "non_latin": 79.2,
315
+ "private": 82.8,
316
+ "languages": {
317
+ "DE": 82.6,
318
+ "EN": 87.4,
319
+ "ES": 71.3,
320
+ "FR": 70.1,
321
+ "ID": 84.5,
322
+ "IT": 89.3,
323
+ "NL": 83.2,
324
+ "PT": 86.8,
325
+ "VI": 79.9,
326
+ "AR": 83.3,
327
+ "HI": 83.6,
328
+ "JP": 75.0,
329
+ "KO": 78.7,
330
+ "RU": 71.2,
331
+ "TH": 77.9,
332
+ "ZH": 84.6,
333
+ "ZH-T": 79.6
334
+ }
335
+ },
336
+ {
337
+ "type": "Specialized VLM",
338
+ "name": "chandra-ocr-2",
339
+ "overall": 79.7,
340
+ "digital": 87.8,
341
+ "photo": 77.1,
342
+ "latin": 82.7,
343
+ "non_latin": 76.4,
344
+ "private": 82.4,
345
+ "languages": {
346
+ "DE": 86.6,
347
+ "EN": 86.5,
348
+ "ES": 69.7,
349
+ "FR": 70.3,
350
+ "ID": 84.6,
351
+ "IT": 87.4,
352
+ "NL": 82.7,
353
+ "PT": 90.7,
354
+ "VI": 85.6,
355
+ "AR": 78.2,
356
+ "HI": 81.1,
357
+ "JP": 68.8,
358
+ "KO": 80.3,
359
+ "RU": 74.0,
360
+ "TH": 78.5,
361
+ "ZH": 73.8,
362
+ "ZH-T": 76.3
363
+ }
364
+ },
365
+ {
366
+ "type": "Specialized VLM",
367
+ "name": "PaddleOCR-VL-1.5",
368
+ "overall": 78.3,
369
+ "digital": 87.4,
370
+ "photo": 75.2,
371
+ "latin": 81.2,
372
+ "non_latin": 74.9,
373
+ "private": 80.7,
374
+ "languages": {
375
+ "DE": 84.8,
376
+ "EN": 83.0,
377
+ "ES": 75.7,
378
+ "FR": 78.1,
379
+ "ID": 83.9,
380
+ "IT": 85.2,
381
+ "NL": 80.6,
382
+ "PT": 80.2,
383
+ "VI": 78.9,
384
+ "AR": 71.3,
385
+ "HI": 67.7,
386
+ "JP": 69.5,
387
+ "KO": 86.0,
388
+ "RU": 76.0,
389
+ "TH": 68.4,
390
+ "ZH": 84.8,
391
+ "ZH-T": 75.7
392
+ }
393
+ },
394
+ {
395
+ "type": "Specialized VLM",
396
+ "name": "HunyuanOCR-1.5",
397
+ "overall": 76.8,
398
+ "digital": 86.2,
399
+ "photo": 73.6,
400
+ "latin": 79.7,
401
+ "non_latin": 73.5,
402
+ "private": 81.2,
403
+ "languages": {
404
+ "DE": 79.6,
405
+ "EN": 80.4,
406
+ "ES": 74.2,
407
+ "FR": 70.0,
408
+ "ID": 81.5,
409
+ "IT": 84.5,
410
+ "NL": 78.4,
411
+ "PT": 86.4,
412
+ "VI": 82.4,
413
+ "AR": 71.8,
414
+ "HI": 71.6,
415
+ "JP": 65.5,
416
+ "KO": 75.7,
417
+ "RU": 67.4,
418
+ "TH": 77.7,
419
+ "ZH": 80.8,
420
+ "ZH-T": 77.2
421
+ }
422
+ },
423
+ {
424
+ "type": "Specialized VLM",
425
+ "name": "dots.ocr",
426
+ "overall": 76.5,
427
+ "digital": 88.8,
428
+ "photo": 72.3,
429
+ "latin": 79.1,
430
+ "non_latin": 73.5,
431
+ "private": 79.7,
432
+ "languages": {
433
+ "DE": 79.7,
434
+ "EN": 81.2,
435
+ "ES": 69.2,
436
+ "FR": 67.1,
437
+ "ID": 82.5,
438
+ "IT": 87.8,
439
+ "NL": 78.8,
440
+ "PT": 86.9,
441
+ "VI": 79.1,
442
+ "AR": 75.9,
443
+ "HI": 77.3,
444
+ "JP": 70.6,
445
+ "KO": 68.5,
446
+ "RU": 66.8,
447
+ "TH": 73.3,
448
+ "ZH": 79.1,
449
+ "ZH-T": 76.2
450
+ }
451
+ },
452
+ {
453
+ "type": "Specialized VLM",
454
+ "name": "PaddleOCR-VL-1.6",
455
+ "overall": 75.0,
456
+ "digital": 82.8,
457
+ "photo": 72.6,
458
+ "latin": 78.0,
459
+ "non_latin": 71.6,
460
+ "private": 77.0,
461
+ "languages": {
462
+ "DE": 84.1,
463
+ "EN": 79.7,
464
+ "ES": 69.2,
465
+ "FR": 74.8,
466
+ "ID": 81.6,
467
+ "IT": 82.0,
468
+ "NL": 74.7,
469
+ "PT": 76.4,
470
+ "VI": 79.3,
471
+ "AR": 69.4,
472
+ "HI": 65.6,
473
+ "JP": 68.7,
474
+ "KO": 82.5,
475
+ "RU": 70.7,
476
+ "TH": 62.3,
477
+ "ZH": 78.0,
478
+ "ZH-T": 75.7
479
+ }
480
+ },
481
+ {
482
+ "type": "Specialized VLM",
483
+ "name": "MinerU-2.5-Pro-1.2B",
484
+ "overall": 71.0,
485
+ "digital": 86.2,
486
+ "photo": 66.1,
487
+ "latin": 74.6,
488
+ "non_latin": 67.0,
489
+ "private": 74.3,
490
+ "languages": {
491
+ "DE": 78.3,
492
+ "EN": 79.5,
493
+ "ES": 63.4,
494
+ "FR": 67.4,
495
+ "ID": 78.0,
496
+ "IT": 79.7,
497
+ "NL": 72.1,
498
+ "PT": 78.6,
499
+ "VI": 74.2,
500
+ "AR": 56.6,
501
+ "HI": 72.2,
502
+ "JP": 59.1,
503
+ "KO": 77.6,
504
+ "RU": 62.6,
505
+ "TH": 61.8,
506
+ "ZH": 76.5,
507
+ "ZH-T": 69.7
508
+ }
509
+ },
510
+ {
511
+ "type": "Specialized VLM",
512
+ "name": "olmOCR2",
513
+ "overall": 70.4,
514
+ "digital": 79.9,
515
+ "photo": 67.2,
516
+ "latin": 76.7,
517
+ "non_latin": 63.3,
518
+ "private": 76.1,
519
+ "languages": {
520
+ "DE": 75.7,
521
+ "EN": 77.3,
522
+ "ES": 72.5,
523
+ "FR": 68.9,
524
+ "ID": 70.6,
525
+ "IT": 81.0,
526
+ "NL": 72.0,
527
+ "PT": 88.0,
528
+ "VI": 84.0,
529
+ "AR": 59.0,
530
+ "HI": 60.8,
531
+ "JP": 59.4,
532
+ "KO": 70.6,
533
+ "RU": 65.8,
534
+ "TH": 59.2,
535
+ "ZH": 68.6,
536
+ "ZH-T": 63.4
537
+ }
538
+ },
539
+ {
540
+ "type": "Specialized VLM",
541
+ "name": "PaddleOCR-VL",
542
+ "overall": 69.6,
543
+ "digital": 87.6,
544
+ "photo": 63.6,
545
+ "latin": 72.1,
546
+ "non_latin": 66.7,
547
+ "private": 70.9,
548
+ "languages": {
549
+ "DE": 78.2,
550
+ "EN": 79.3,
551
+ "ES": 62.9,
552
+ "FR": 66.0,
553
+ "ID": 77.4,
554
+ "IT": 78.4,
555
+ "NL": 67.9,
556
+ "PT": 72.0,
557
+ "VI": 66.6,
558
+ "AR": 65.8,
559
+ "HI": 68.4,
560
+ "JP": 59.9,
561
+ "KO": 77.8,
562
+ "RU": 56.9,
563
+ "TH": 57.8,
564
+ "ZH": 78.2,
565
+ "ZH-T": 68.5
566
+ }
567
+ },
568
+ {
569
+ "type": "Specialized VLM",
570
+ "name": "HunyuanOCR",
571
+ "overall": 68.3,
572
+ "digital": 80.2,
573
+ "photo": 64.3,
574
+ "latin": 72.4,
575
+ "non_latin": 63.7,
576
+ "private": 68.6,
577
+ "languages": {
578
+ "DE": 75.0,
579
+ "EN": 73.1,
580
+ "ES": 63.0,
581
+ "FR": 66.1,
582
+ "ID": 69.9,
583
+ "IT": 80.3,
584
+ "NL": 61.4,
585
+ "PT": 81.9,
586
+ "VI": 80.6,
587
+ "AR": 68.3,
588
+ "HI": 73.1,
589
+ "JP": 55.6,
590
+ "KO": 68.9,
591
+ "RU": 52.2,
592
+ "TH": 60.7,
593
+ "ZH": 66.8,
594
+ "ZH-T": 64.2
595
+ }
596
+ },
597
+ {
598
+ "type": "Specialized VLM",
599
+ "name": "GLM-OCR",
600
+ "overall": 67.3,
601
+ "digital": 77.9,
602
+ "photo": 63.7,
603
+ "latin": 78.7,
604
+ "non_latin": 54.3,
605
+ "private": 68.8,
606
+ "languages": {
607
+ "DE": 82.7,
608
+ "EN": 84.5,
609
+ "ES": 75.8,
610
+ "FR": 76.2,
611
+ "ID": 79.7,
612
+ "IT": 82.8,
613
+ "NL": 80.2,
614
+ "PT": 77.4,
615
+ "VI": 69.2,
616
+ "AR": 21.7,
617
+ "HI": 39.6,
618
+ "JP": 65.5,
619
+ "KO": 61.2,
620
+ "RU": 64.2,
621
+ "TH": 27.4,
622
+ "ZH": 78.5,
623
+ "ZH-T": 76.7
624
+ }
625
+ },
626
+ {
627
+ "type": "Specialized VLM",
628
+ "name": "MonkeyOCRv1.5",
629
+ "overall": 65.0,
630
+ "digital": 84.3,
631
+ "photo": 58.6,
632
+ "latin": 67.4,
633
+ "non_latin": 62.4,
634
+ "private": 69.0,
635
+ "languages": {
636
+ "DE": 70.8,
637
+ "EN": 74.9,
638
+ "ES": 55.6,
639
+ "FR": 60.3,
640
+ "ID": 73.8,
641
+ "IT": 75.9,
642
+ "NL": 66.3,
643
+ "PT": 67.2,
644
+ "VI": 61.4,
645
+ "AR": 60.1,
646
+ "HI": 56.8,
647
+ "JP": 57.0,
648
+ "KO": 78.9,
649
+ "RU": 51.7,
650
+ "TH": 55.6,
651
+ "ZH": 74.8,
652
+ "ZH-T": 64.1
653
+ }
654
+ },
655
+ {
656
+ "type": "Specialized VLM",
657
+ "name": "Nanonets-OCR2-3B",
658
+ "overall": 64.2,
659
+ "digital": 79.2,
660
+ "photo": 59.3,
661
+ "latin": 71.4,
662
+ "non_latin": 56.2,
663
+ "private": 67.6,
664
+ "languages": {
665
+ "DE": 76.7,
666
+ "EN": 76.4,
667
+ "ES": 61.8,
668
+ "FR": 66.1,
669
+ "ID": 68.4,
670
+ "IT": 78.5,
671
+ "NL": 74.1,
672
+ "PT": 74.2,
673
+ "VI": 66.0,
674
+ "AR": 60.2,
675
+ "HI": 59.2,
676
+ "JP": 52.1,
677
+ "KO": 54.7,
678
+ "RU": 45.5,
679
+ "TH": 44.6,
680
+ "ZH": 68.3,
681
+ "ZH-T": 65.1
682
+ },
683
+ "source_name": "Nanonets-ocr2-3B"
684
+ },
685
+ {
686
+ "type": "Specialized VLM",
687
+ "name": "LightOnOCR-2-1B",
688
+ "overall": 63.9,
689
+ "digital": 80.2,
690
+ "photo": 58.5,
691
+ "latin": 73.7,
692
+ "non_latin": 52.8,
693
+ "private": 68.1,
694
+ "languages": {
695
+ "DE": 72.4,
696
+ "EN": 79.1,
697
+ "ES": 65.0,
698
+ "FR": 62.1,
699
+ "ID": 72.9,
700
+ "IT": 82.9,
701
+ "NL": 70.2,
702
+ "PT": 83.8,
703
+ "VI": 74.9,
704
+ "AR": 64.2,
705
+ "HI": 59.0,
706
+ "JP": 50.5,
707
+ "KO": 41.9,
708
+ "RU": 54.3,
709
+ "TH": 51.4,
710
+ "ZH": 46.6,
711
+ "ZH-T": 54.7
712
+ }
713
+ },
714
+ {
715
+ "type": "Specialized VLM",
716
+ "name": "Nanonets-OCR-s",
717
+ "overall": 63.7,
718
+ "digital": 78.8,
719
+ "photo": 58.7,
720
+ "latin": 71.3,
721
+ "non_latin": 55.0,
722
+ "private": 66.6,
723
+ "languages": {
724
+ "DE": 75.1,
725
+ "EN": 78.5,
726
+ "ES": 61.2,
727
+ "FR": 62.5,
728
+ "ID": 70.3,
729
+ "IT": 81.0,
730
+ "NL": 69.6,
731
+ "PT": 75.9,
732
+ "VI": 67.5,
733
+ "AR": 59.5,
734
+ "HI": 61.8,
735
+ "JP": 55.9,
736
+ "KO": 51.2,
737
+ "RU": 43.5,
738
+ "TH": 39.5,
739
+ "ZH": 67.4,
740
+ "ZH-T": 61.5
741
+ }
742
+ },
743
+ {
744
+ "type": "Specialized VLM",
745
+ "name": "FalconOCR",
746
+ "overall": 56.3,
747
+ "digital": 72.4,
748
+ "photo": 51.1,
749
+ "latin": 69.3,
750
+ "non_latin": 41.6,
751
+ "private": 58.5,
752
+ "languages": {
753
+ "DE": 72.4,
754
+ "EN": 75.0,
755
+ "ES": 60.9,
756
+ "FR": 61.8,
757
+ "ID": 69.6,
758
+ "IT": 74.7,
759
+ "NL": 71.6,
760
+ "PT": 70.3,
761
+ "VI": 67.8,
762
+ "AR": 37.9,
763
+ "HI": 61.3,
764
+ "JP": 39.6,
765
+ "KO": 29.6,
766
+ "RU": 54.0,
767
+ "TH": 24.8,
768
+ "ZH": 39.7,
769
+ "ZH-T": 45.6
770
+ }
771
+ },
772
+ {
773
+ "type": "Specialized VLM",
774
+ "name": "MonkeyOCR-pro-3B",
775
+ "overall": 52.2,
776
+ "digital": 68.0,
777
+ "photo": 47.0,
778
+ "latin": 65.1,
779
+ "non_latin": 37.6,
780
+ "private": 53.6,
781
+ "languages": {
782
+ "DE": 71.7,
783
+ "EN": 77.9,
784
+ "ES": 55.9,
785
+ "FR": 62.1,
786
+ "ID": 66.2,
787
+ "IT": 74.5,
788
+ "NL": 66.3,
789
+ "PT": 71.1,
790
+ "VI": 40.2,
791
+ "AR": 4.6,
792
+ "HI": 4.2,
793
+ "JP": 55.2,
794
+ "KO": 60.5,
795
+ "RU": 42.6,
796
+ "TH": 9.1,
797
+ "ZH": 72.2,
798
+ "ZH-T": 52.4
799
+ }
800
+ },
801
+ {
802
+ "type": "Specialized VLM",
803
+ "name": "DeepSeek-OCR",
804
+ "overall": 51.8,
805
+ "digital": 80.7,
806
+ "photo": 42.2,
807
+ "latin": 54.5,
808
+ "non_latin": 48.9,
809
+ "private": 54.5,
810
+ "languages": {
811
+ "DE": 55.0,
812
+ "EN": 58.3,
813
+ "ES": 44.1,
814
+ "FR": 43.2,
815
+ "ID": 60.9,
816
+ "IT": 69.3,
817
+ "NL": 52.4,
818
+ "PT": 53.0,
819
+ "VI": 54.1,
820
+ "AR": 56.9,
821
+ "HI": 52.2,
822
+ "JP": 49.1,
823
+ "KO": 28.2,
824
+ "RU": 36.2,
825
+ "TH": 49.4,
826
+ "ZH": 59.7,
827
+ "ZH-T": 59.2
828
+ }
829
+ },
830
+ {
831
+ "type": "Specialized VLM",
832
+ "name": "MinerU-2.5-VLM",
833
+ "overall": 46.3,
834
+ "digital": 61.9,
835
+ "photo": 40.8,
836
+ "latin": 63.0,
837
+ "non_latin": 27.4,
838
+ "private": 48.7,
839
+ "languages": {
840
+ "DE": 68.8,
841
+ "EN": 78.4,
842
+ "ES": 54.7,
843
+ "FR": 57.3,
844
+ "ID": 67.5,
845
+ "IT": 75.2,
846
+ "NL": 60.4,
847
+ "PT": 58.8,
848
+ "VI": 46.0,
849
+ "AR": 1.3,
850
+ "HI": 9.0,
851
+ "JP": 39.1,
852
+ "KO": 14.7,
853
+ "RU": 8.6,
854
+ "TH": 11.3,
855
+ "ZH": 72.9,
856
+ "ZH-T": 62.2
857
+ }
858
+ },
859
+ {
860
+ "type": "Pipeline Tool",
861
+ "name": "PP-StructureV3",
862
+ "overall": 45.4,
863
+ "digital": 56.2,
864
+ "photo": 41.7,
865
+ "latin": 59.8,
866
+ "non_latin": 28.9,
867
+ "private": 49.6,
868
+ "languages": {
869
+ "DE": 60.4,
870
+ "EN": 68.7,
871
+ "ES": 54.4,
872
+ "FR": 49.8,
873
+ "ID": 69.6,
874
+ "IT": 68.9,
875
+ "NL": 55.5,
876
+ "PT": 58.4,
877
+ "VI": 52.7,
878
+ "AR": 1.0,
879
+ "HI": 7.7,
880
+ "JP": 56.2,
881
+ "KO": 15.4,
882
+ "RU": 7.5,
883
+ "TH": 11.9,
884
+ "ZH": 72.2,
885
+ "ZH-T": 59.1
886
+ }
887
+ },
888
+ {
889
+ "type": "Pipeline Tool",
890
+ "name": "MinerU-2.5-pipeline",
891
+ "overall": 33.5,
892
+ "digital": 57.6,
893
+ "photo": 25.4,
894
+ "latin": 46.5,
895
+ "non_latin": 18.7,
896
+ "private": 36.2,
897
+ "languages": {
898
+ "DE": 54.3,
899
+ "EN": 58.3,
900
+ "ES": 38.4,
901
+ "FR": 43.6,
902
+ "ID": 51.9,
903
+ "IT": 56.5,
904
+ "NL": 43.9,
905
+ "PT": 44.0,
906
+ "VI": 27.6,
907
+ "AR": 1.2,
908
+ "HI": 5.3,
909
+ "JP": 24.5,
910
+ "KO": 6.8,
911
+ "RU": 4.2,
912
+ "TH": 6.4,
913
+ "ZH": 53.9,
914
+ "ZH-T": 47.2
915
+ }
916
+ }
917
+ ]
918
+ }
model_metadata.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Display names and first-party destinations for the initial MDPBench results.
3
+ * `name` is the evaluation identifier preserved in leaderboard.json; `label`
4
+ * is what readers see. Entries using a project page (rather than a versioned
5
+ * checkpoint) retain their exact evaluation identifier as the label.
6
+ */
7
+ const MODEL_METADATA = {
8
+ "gemini-3-pro-preview": { label: "Gemini 3 Pro Preview", url: "https://ai.google.dev/gemini-api/docs/models/gemini-3-pro-preview" },
9
+ "kimi-k2.5": { label: "Kimi K2.5", url: "https://www.kimi.com/" },
10
+ "doubao-seed-2-0-pro-260215": { label: "Doubao-Seed-2.0-Pro (260215)", url: "https://api.volcengine.com/api-explorer/?action=ListFoundationModelVersions&groupName=%E5%9F%BA%E7%A1%80%E6%A8%A1%E5%9E%8B&serviceCode=ark&version=2024-01-01" },
11
+ "claude-sonnet-4-6": { label: "Claude Sonnet 4.6", url: "https://docs.anthropic.com/en/docs/about-claude/models/overview" },
12
+ "gpt-5.2-2025-12-11": { label: "GPT-5.2 (2025-12-11)", url: "https://platform.openai.com/docs/models" },
13
+ "Qwen3-VL-8B-Instruct": { label: "Qwen3-VL-8B-Instruct", url: "https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct" },
14
+ "Qwen3.5-Instruct-9B": { label: "Qwen3.5-Instruct-9B", url: "https://qwen.ai/" },
15
+ "InternVL3_5-8B": { label: "InternVL3_5-8B", url: "https://huggingface.co/OpenGVLab/InternVL3_5-8B" },
16
+ "MonkeyOCRv2-B-Parsing": { label: "MonkeyOCRv2-B-Parsing", url: "https://github.com/Yuliang-Liu/MonkeyOCR" },
17
+ "MonkeyOCRv2-S-Parsing": { label: "MonkeyOCRv2-S-Parsing", url: "https://github.com/Yuliang-Liu/MonkeyOCR" },
18
+ "dots.mocr": { label: "dots.mocr", url: "https://huggingface.co/rednote-hilab/dots.mocr" },
19
+ "chandra-ocr-2": { label: "Chandra OCR 2", url: "https://huggingface.co/datalab-to/chandra-ocr-2" },
20
+ "PaddleOCR-VL-1.5": { label: "PaddleOCR-VL-1.5", url: "https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.5" },
21
+ "HunyuanOCR-1.5": { label: "HunyuanOCR-1.5", url: "https://huggingface.co/tencent/HunyuanOCR" },
22
+ "dots.ocr": { label: "dots.ocr", url: "https://huggingface.co/rednote-hilab/dots.ocr" },
23
+ "PaddleOCR-VL-1.6": { label: "PaddleOCR-VL-1.6", url: "https://github.com/PaddlePaddle/PaddleOCR/blob/main/docs/version3.x/pipeline_usage/PaddleOCR-VL.md" },
24
+ "MinerU-2.5-Pro-1.2B": { label: "MinerU2.5-Pro-1.2B", url: "https://github.com/opendatalab/MinerU" },
25
+ "olmOCR2": { label: "olmOCR 2", url: "https://huggingface.co/allenai/olmOCR-2-7B-1025-FP8" },
26
+ "PaddleOCR-VL": { label: "PaddleOCR-VL-0.9B", url: "https://github.com/PaddlePaddle/PaddleOCR" },
27
+ "HunyuanOCR": { label: "HunyuanOCR", url: "https://huggingface.co/tencent/HunyuanOCR" },
28
+ "GLM-OCR": { label: "GLM-OCR", url: "https://huggingface.co/zai-org/GLM-OCR" },
29
+ "MonkeyOCRv1.5": { label: "MonkeyOCR v1.5", url: "https://github.com/Yuliang-Liu/MonkeyOCR" },
30
+ "Nanonets-OCR2-3B": { label: "Nanonets-OCR2-3B", url: "https://huggingface.co/nanonets" },
31
+ "LightOnOCR-2-1B": { label: "LightOnOCR-2-1B", url: "https://huggingface.co/lightonai/LightOnOCR-2-1B" },
32
+ "Nanonets-OCR-s": { label: "Nanonets-OCR-s", url: "https://huggingface.co/nanonets/Nanonets-OCR-s" },
33
+ "FalconOCR": { label: "Falcon-OCR", url: "https://huggingface.co/tiiuae/Falcon-OCR" },
34
+ "MonkeyOCR-pro-3B": { label: "MonkeyOCR-pro-3B", url: "https://github.com/Yuliang-Liu/MonkeyOCR" },
35
+ "DeepSeek-OCR": { label: "DeepSeek-OCR", url: "https://github.com/deepseek-ai/DeepSeek-OCR" },
36
+ "MinerU-2.5-VLM": { label: "MinerU2.5-VLM", url: "https://github.com/opendatalab/MinerU" },
37
+ "PP-StructureV3": { label: "PP-StructureV3", url: "https://github.com/PaddlePaddle/PaddleOCR" },
38
+ "MinerU-2.5-pipeline": { label: "MinerU2.5-pipeline", url: "https://github.com/opendatalab/MinerU" }
39
+ };
style.css CHANGED
@@ -1,28 +1,16 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
1
+ :root { --ink: #18251e; --muted: #65716a; --line: #d9ddd4; --paper: #f7f7f2; --lime: #d7fa4a; --blue: #1269db; }
2
+ * { box-sizing: border-box; }
3
+ body { margin: 0; color: var(--ink); background: var(--paper); font-family: Manrope, Arial, sans-serif; }
4
+ .shell { max-width: 1320px; margin: 0 auto; padding: 32px 42px 68px; }
5
+ .hero { padding: 16px 0 54px; max-width: 880px; }
6
+ .brand { display: inline-block; margin-bottom: 67px; color: var(--ink); font-family: "DM Mono", monospace; font-size: 19px; font-weight: 700; letter-spacing: -.08em; text-decoration: none; }.brand span { color: var(--blue); }
7
+ .eyebrow { margin: 0 0 10px; color: var(--blue); font-family: "DM Mono", monospace; font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
8
+ h1, h2, p { margin-top: 0; } h1 { margin-bottom: 20px; font-size: clamp(39px, 5vw, 70px); font-weight: 800; letter-spacing: -.065em; line-height: .99; } h1 em { color: var(--blue); font-style: normal; }
9
+ .intro { max-width: 660px; color: var(--muted); font-size: 16px; line-height: 1.7; }.links { display: flex; gap: 24px; margin-top: 27px; }.links a { color: var(--ink); font-family: "DM Mono", monospace; font-size: 12px; font-weight: 700; text-underline-offset: 4px; }
10
+ .at-a-glance { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink); margin-bottom: 73px; }.at-a-glance div { padding: 20px 20px 18px 0; border-right: 1px solid var(--line); }.at-a-glance div+div { padding-left: 20px; }.at-a-glance div:last-child { border: 0; }.at-a-glance strong, .at-a-glance span { display: block; }.at-a-glance strong { font-size: 25px; letter-spacing: -.05em; }.at-a-glance span { margin-top: 3px; color: var(--muted); font-family: "DM Mono", monospace; font-size: 10px; text-transform: uppercase; }
11
+ .board { background: white; border: 1px solid var(--ink); box-shadow: 7px 7px 0 var(--lime); padding: 27px; }.board-topline { display: flex; align-items: end; justify-content: space-between; gap: 16px; }.board h2, .methodology h2 { margin: 0; font-size: 31px; letter-spacing: -.055em; }.updated { margin: 0; color: var(--muted); font-family: "DM Mono", monospace; font-size: 10px; }
12
+ .controls { display: flex; align-items: center; gap: 11px; margin: 27px 0 20px; }.expand, .model-name { cursor: pointer; font: inherit; }.search { margin-left: auto; }.search input, select { border: 1px solid var(--line); border-radius: 0; padding: 10px 12px; color: var(--ink); background: white; font: 12px "DM Mono", monospace; }.search input { width: 155px; }.select-label { display: flex; align-items: center; gap: 8px; color: var(--muted); font: 10px "DM Mono", monospace; text-transform: uppercase; }
13
+ .table-wrap { overflow-x: auto; } table { width: 100%; min-width: 720px; border-collapse: collapse; text-align: left; } th { padding: 10px 8px; border-bottom: 1px solid var(--ink); color: var(--muted); font: 10px "DM Mono", monospace; text-transform: uppercase; } td { padding: 13px 8px; border-bottom: 1px solid #e7e9e5; font-size: 12px; } .rank { color: var(--muted); font-family: "DM Mono", monospace; }.model-name { padding: 0; border: 0; background: none; color: var(--ink); font-size: 12px; font-weight: 800; text-align: left; }.score { font-family: "DM Mono", monospace; }.featured { color: var(--blue); font-weight: 800; }.type { display: inline-block; color: var(--muted); font-family: "DM Mono", monospace; font-size: 9px; }.type-general-vlm { color: #7a4b00; }.type-specialized-vlm { color: #1269db; }.type-pipeline-tool { color: #72766f; }.expand { width: 24px; height: 24px; border: 1px solid var(--line); background: white; color: var(--blue); font-size: 17px; line-height: 1; }.detail-row { display: none; background: #f3f8eb; }.detail-row.show { display: table-row; }.detail-row td { padding: 17px 20px 20px; }.details { display: flex; justify-content: space-between; gap: 28px; }.detail-title { margin: 15px 0 10px; font: 10px "DM Mono", monospace; text-transform: uppercase; }.detail-title:first-child { margin-top: 0; }.group-scores { display: flex; gap: 22px; }.group-scores span { display: flex; gap: 6px; font: 11px "DM Mono", monospace; }.group-scores b { color: var(--muted); font-weight: 400; }.language-grid { display: grid; grid-template-columns: repeat(9, 1fr); gap: 7px 18px; }.language-grid span { display: flex; gap: 6px; font: 11px "DM Mono", monospace; }.language-grid b { color: var(--muted); font-weight: 400; }.source-note { margin: 0; color: var(--muted); font-size: 11px; }.source-note code { color: var(--ink); }.methodology { display: grid; grid-template-columns: 1fr 1.3fr; gap: 90px; padding: 80px 0 4px; }.method-copy { color: var(--muted); font-size: 14px; line-height: 1.7; }.method-copy p+ p { margin-top: 16px; }footer { padding: 24px 42px; border-top: 1px solid var(--line); color: var(--muted); font: 10px "DM Mono", monospace; }.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
14
+ .rank-tabs { display: flex; background: #edf0ea; padding: 3px; }.rank-tabs button { border: 0; background: transparent; padding: 9px 12px; color: var(--muted); cursor: pointer; font: 700 11px "DM Mono", monospace; }.rank-tabs button.active { background: var(--ink); color: white; }.private { font-weight: 700; } table { min-width: 940px; }
15
+ .model-link { display: inline-block; margin-left: 7px; color: var(--blue); font-family: "DM Mono", monospace; font-size: 12px; font-weight: 800; text-decoration: none; }.model-link:hover { text-decoration: underline; }
16
+ @media (max-width: 720px) { .shell { padding: 22px 18px 44px; }.brand { margin-bottom: 46px; }.hero { padding-bottom: 38px; }.at-a-glance { grid-template-columns: repeat(2, 1fr); margin-bottom: 45px; }.at-a-glance div:nth-child(2) { border-right: 0; }.at-a-glance div:nth-child(n+3) { border-top: 1px solid var(--line); }.board { padding: 17px; box-shadow: 4px 4px 0 var(--lime); }.board-topline, .controls, .methodology { display: block; }.updated { margin-top: 10px; }.controls > * { margin: 10px 0 0; }.search { display: block; }.search input { width: 100%; }.select-label { justify-content: space-between; }.methodology { padding-top: 54px; }.method-copy { margin-top: 22px; }.language-grid { grid-template-columns: repeat(3, 1fr); }.details { display: block; }.source-note { margin-top: 16px; } footer { padding: 20px 18px; } }
 
 
 
 
 
 
 
 
 
 
 
 
tools/sync_leaderboard.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Synchronize the static leaderboard data from MDPBench's README table.
3
+
4
+ The README is the source of truth for the initial official results. This tool
5
+ parses its HTML table without third-party dependencies and preserves the stable
6
+ evaluation identifiers already present in leaderboard.json.
7
+
8
+ Examples:
9
+ python tools/sync_leaderboard.py --check
10
+ python tools/sync_leaderboard.py --write
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import json
17
+ import re
18
+ import sys
19
+ from datetime import date
20
+ from html.parser import HTMLParser
21
+ from pathlib import Path
22
+ from typing import Any
23
+
24
+
25
+ LANGUAGES = [
26
+ "DE", "EN", "ES", "FR", "ID", "IT", "NL", "PT", "VI",
27
+ "AR", "HI", "JP", "KO", "RU", "TH", "ZH", "ZH-T",
28
+ ]
29
+ SCORE_KEYS = ["overall", "digital", "photo", "latin", "non_latin", "private"]
30
+
31
+
32
+ class ResultsTableParser(HTMLParser):
33
+ """Collect table rows and ``rowspan`` values from an HTML README table."""
34
+
35
+ def __init__(self) -> None:
36
+ super().__init__()
37
+ self.rows: list[list[tuple[str, int]]] = []
38
+ self._row: list[tuple[str, int]] | None = None
39
+ self._cell_text: list[str] | None = None
40
+ self._cell_rowspan = 1
41
+
42
+ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
43
+ if tag == "tr":
44
+ self._row = []
45
+ elif tag in {"td", "th"} and self._row is not None:
46
+ self._cell_text = []
47
+ attrs_dict = dict(attrs)
48
+ self._cell_rowspan = int(attrs_dict.get("rowspan") or 1)
49
+
50
+ def handle_data(self, data: str) -> None:
51
+ if self._cell_text is not None:
52
+ self._cell_text.append(data)
53
+
54
+ def handle_endtag(self, tag: str) -> None:
55
+ if tag in {"td", "th"} and self._cell_text is not None and self._row is not None:
56
+ text = " ".join("".join(self._cell_text).split())
57
+ self._row.append((text, self._cell_rowspan))
58
+ self._cell_text = None
59
+ elif tag == "tr" and self._row:
60
+ self.rows.append(self._row)
61
+ self._row = None
62
+
63
+
64
+ def parse_number(value: str, *, model_name: str) -> float:
65
+ try:
66
+ return float(value)
67
+ except ValueError as exc:
68
+ raise ValueError(f"{model_name}: expected a numeric score, got {value!r}") from exc
69
+
70
+
71
+ def parse_results(readme: Path) -> list[dict[str, Any]]:
72
+ parser = ResultsTableParser()
73
+ parser.feed(readme.read_text(encoding="utf-8"))
74
+
75
+ current_type: str | None = None
76
+ parsed: list[dict[str, Any]] = []
77
+ for row in parser.rows:
78
+ cells = [text for text, _ in row]
79
+ if not cells or cells[0] in {"Model Type", "All"}:
80
+ continue
81
+
82
+ # A category row has model type, model name, and 23 scores. Subsequent
83
+ # rows have the model name and the same 23 scores.
84
+ if len(cells) == 25:
85
+ current_type = re.sub(r"\s+", " ", cells[0])
86
+ model_name, score_values = cells[1], cells[2:]
87
+ elif len(cells) == 24 and current_type is not None:
88
+ model_name, score_values = cells[0], cells[1:]
89
+ else:
90
+ continue
91
+
92
+ if len(score_values) != 23:
93
+ raise ValueError(
94
+ f"{model_name}: expected 23 score columns from the README table, "
95
+ f"found {len(score_values)}"
96
+ )
97
+
98
+ numeric = [parse_number(value, model_name=model_name) for value in score_values]
99
+ latin_languages = numeric[4:13]
100
+ non_latin_languages = numeric[14:22]
101
+ parsed.append(
102
+ {
103
+ "type": current_type,
104
+ "source_name": model_name,
105
+ "overall": numeric[0],
106
+ "digital": numeric[1],
107
+ "photo": numeric[2],
108
+ "latin": numeric[3],
109
+ "non_latin": numeric[13],
110
+ "private": numeric[22],
111
+ "languages": dict(zip(LANGUAGES, latin_languages + non_latin_languages, strict=True)),
112
+ }
113
+ )
114
+
115
+ if not parsed:
116
+ raise ValueError("No Main Results rows were found in the README.")
117
+ return parsed
118
+
119
+
120
+ def type_label(value: str) -> str:
121
+ compact = value.replace(" ", "")
122
+ return {
123
+ "GeneralVLMs": "General VLM",
124
+ "SpecializedVLMs": "Specialized VLM",
125
+ "PipelineTools": "Pipeline Tool",
126
+ }[compact]
127
+
128
+
129
+ def build_document(source_rows: list[dict[str, Any]], existing: dict[str, Any]) -> dict[str, Any]:
130
+ existing_models = existing.get("models", [])
131
+ identifiers = {
132
+ model.get("source_name", model["name"]): model["name"]
133
+ for model in existing_models
134
+ }
135
+ source_names = {model.get("source_name") for model in existing_models if model.get("source_name")}
136
+ models = []
137
+
138
+ for source in source_rows:
139
+ source_name = source["source_name"]
140
+ model: dict[str, Any] = {
141
+ "type": type_label(source["type"]),
142
+ "name": identifiers.get(source_name, source_name),
143
+ "overall": source["overall"],
144
+ "digital": source["digital"],
145
+ "photo": source["photo"],
146
+ "latin": source["latin"],
147
+ "non_latin": source["non_latin"],
148
+ "private": source["private"],
149
+ "languages": source["languages"],
150
+ }
151
+ if source_name in source_names:
152
+ model["source_name"] = source_name
153
+ models.append(model)
154
+
155
+ missing = set(identifiers) - {row["source_name"] for row in source_rows}
156
+ if missing:
157
+ raise ValueError("Models in leaderboard.json absent from README: " + ", ".join(sorted(missing)))
158
+
159
+ benchmark = dict(existing.get("benchmark", {}))
160
+ benchmark["updated"] = date.today().isoformat()
161
+ return {"benchmark": benchmark, "models": models}
162
+
163
+
164
+ def main() -> int:
165
+ root = Path(__file__).resolve().parents[1]
166
+ parser = argparse.ArgumentParser(description="Sync leaderboard.json from the MDPBench README results table.")
167
+ parser.add_argument("--readme", type=Path, default=root.parent / "README.md")
168
+ parser.add_argument("--output", type=Path, default=root / "leaderboard.json")
169
+ action = parser.add_mutually_exclusive_group(required=True)
170
+ action.add_argument("--check", action="store_true", help="Fail if the generated data differs from the current JSON.")
171
+ action.add_argument("--write", action="store_true", help="Write the generated data to leaderboard.json.")
172
+ args = parser.parse_args()
173
+
174
+ existing = json.loads(args.output.read_text(encoding="utf-8"))
175
+ generated = build_document(parse_results(args.readme), existing)
176
+ current = json.dumps(existing, ensure_ascii=False, sort_keys=True)
177
+ candidate = json.dumps(generated, ensure_ascii=False, sort_keys=True)
178
+ changed = current != candidate
179
+
180
+ if args.check:
181
+ if changed:
182
+ print("Leaderboard JSON is out of sync with README. Run with --write to update it.", file=sys.stderr)
183
+ return 1
184
+ print(f"In sync: {len(generated['models'])} models, {len(LANGUAGES)} language scores each.")
185
+ return 0
186
+
187
+ args.output.write_text(json.dumps(generated, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
188
+ print(f"Wrote {len(generated['models'])} models to {args.output}")
189
+ return 0
190
+
191
+
192
+ if __name__ == "__main__":
193
+ raise SystemExit(main())