Close top ParseBench content-faithfulness drivers at the root (multi-column order, prose-as-table grids, unmapped-font text layers) - #5
Merged
Conversation
Diagnosis (new scripts/parsebench_content_fasteval.py, official scorer,
per-rule diagnostics over all 506 text_content pages; baseline CF 68.3):
the loss concentrates in three mechanisms — multi-column reading order
(order component 52.3, worst on OCR pages), prose mis-inferred as tables
(render-boundary block replacement + duplication), and unreadable
(cid:NN) text layers.
Front-end (pdf_plumber_parser):
- Column-buffer flush now requires a word that genuinely bridges a gutter
(or a page-wide band break) instead of any overlap; a hyphenated
overhang no longer degenerates narrow-gutter pages to row-major
interleave.
- The OCR path runs the same conservative multi-column prose routing as
the text path (scanned newspapers/newsletters used to interleave).
- 3+-column layouts use a relaxed words-per-line floor guarded by a new
line-pitch-regularity gate; word density is CJK-aware (~2 chars/word).
- Unmapped-glyph markers ("(cid:NN)") are stripped; fully-unmapped pages
collapse to sparse and route to OCR via the existing detector.
OCR (ocr_parser):
- Det boxes are trimmed horizontally to compensate the detector's unclip
dilation (the vertical counterpart was always compensated via
OCR_FONT_RATIO), so word geometry stops bleeding into gutters.
- WARP_OCR_DPI / WARP_OCR_MAX_SIDE_LEN / WARP_OCR_DET_LIMIT env knobs;
measured sweep kept stock defaults (DPI 300 hurts the PP-OCR models).
Table engine:
- _looks_prose_grid rejects inferred (unruled) grids whose non-empty
cells are >=50% sentence-length: side-by-side flowing prose (2-column
bodies, pull-quotes, scanned newsletters) is never a data table, and
emitting it replaced real prose blocks with fake page-wide grids.
Full ParseBench Tables fasteval holds at 56.93 GriTS.
Guards: new tests/test_multicolumn_routing.py + prose-grid unit tests;
full repo suite green; hetero-100 golden aggregate improves on every
floored metric (baseline regenerated per the sanctioned re-floor policy);
legal-100 / S-1 / OC / docsling / semunit untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Db2HoocctVP1XZpmNmEsM
…ents A long cell that is digit-dense (a merged TOC run "3.1 Our company 11 3.2 ...", a wide numeric data row) is not flowing prose — count only mostly-alphabetic >=6-word cells toward the prose-grid rejection, so TOC/data grids survive while multi-column prose grids stay rejected. Recovers the one large gate-induced regression (tableOfContent8col +14.7, back to its prior score) with zero collateral across the 45 re-checked regressed/winner pages; full ParseBench Tables fasteval 56.95 GriTS (unchanged). Final full-dataset measurement (official evaluator, 506 text_content pages): Content Faithfulness 68.33 -> 70.81 (+2.48); correctness 75.97 -> 77.24; order 52.34 -> 57.30. 112 pages improved / 27 regressed. Design doc updated with the numbers and the accepted-regression notes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Db2HoocctVP1XZpmNmEsM
JSv4
added a commit
that referenced
this pull request
Jul 7, 2026
Full official faithful run from the v2.0.1 merge commit (native table engine, OCR extra installed, VG scored in-run via the fork fix): Tables 57.45 / Charts 7.04 / Content 70.81 / Sem.Format 45.81 / Visual 20.71 -> Overall 40.36 (+1.39 vs the 2026-07-02 baseline, from PR #5's content-faithfulness root fixes). A back-to-back rerun after PR #6's ablation removal reproduced every dimension to within 0.04, confirming the removal is score-neutral. Also corrects the stale claim that the 42 image-only layout failures pad the VG headline (padding is product-type-scoped and never reaches avg_layout_element_rule_pass_rate). User-authorized direct push to main (docs-only change). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of the change
Diagnoses and root-cause-fixes the top three drivers of Warp's ParseBench Content Faithfulness losses. Final measured result (official evaluator, all 506
text_contentpages): 68.33 → 70.81 (+2.48) — correctness 75.97 → 77.24, reading-order 52.34 → 57.30; 112 pages improved / 27 regressed. Engine/front-end fixes only, no benchmark-boundary post-processing.Diagnosis tooling. New
scripts/parsebench_content_fasteval.py(mirrors the table/format fastevals; officialParseEvaluator, zero scoring re-implemented) scores every text_content page and dumps per-rule failure diagnostics. Every worst page was traced through the pipeline (front-end XHTML stream → engine blocks → rendered Markdown) to attribute its loss to the stage that caused it. Baseline loss pools:text_ocr53.2 CF-units,text_multicolumns34.8,text_simple23.1,text_multilang21.4.Driver 1 — multi-column reading order (order component 52.3 overall; 30.7 on OCR pages):
_group_words_into_lines_columns: a row now flushes the column buffers only when a word genuinely bridges a gutter (fully crosses it or sits inside it) or at a page-wide band break — a hyphenated overhang no longer degenerates narrow-gutter pages to row-major interleave._trim_det_box— the vertical counterpart was always compensated viaOCR_FONT_RATIO), so word geometry stops bleeding into gutters.Driver 2 — prose mis-inferred as tables (
table_engine._looks_prose_grid): the alignment-band proposer sees two book-justified columns as one huge aligned band and inferred page-wide "grids" of sentence-length cells, which then replaced real, correctly-ordered prose blocks at the render boundary (scanned pages lost 15–20% of their words to sparse noise-grids; duplication + sentence fragmentation everywhere). An inferred (unruled) grid whose non-empty cells are ≥50% prose cells (≥6 words, mostly alphabetic — digit-dense TOC runs / numeric rows don't count) is now rejected. Structural token shape only; ruled grids untouched. Full ParseBench Tables fasteval (503 pages) holds at 56.95 GriTS (was 56.93).Driver 3 — unreadable text layers (
_strip_cid_words): fonts with no usable ToUnicode CMap made pdfminer emit literal(cid:NN)markers per glyph — 16 pages (incl. 6 of the 7 worsttext_simplepages) "had text" that was thousands of garbage tokens. The markers are stripped (they are unextractable glyphs, not content); a fully-unmapped page collapses to ~0 words and the existing sparse-page detector routes it to OCR, which recovers the real text from pixels.OCR quality knobs, measured and kept stock:
WARP_OCR_DPI/WARP_OCR_MAX_SIDE_LEN/WARP_OCR_DET_LIMITare now env-tunable; a 4-config sweep showed DPI 300 hurts the PP-OCR mobile models andmax_side_len=3000is marginal with outlier regressions, so defaults are unchanged.Largest wins: the multi-column class (mckinsey +47.8, 3colpres +43.0, 3colceo +41.4, forword2cols +40.1, visa +39.5) and the cid class (staffrepport +44.6, contract +23.3). Two accepted regressions remain (coorp −7.8, scanbook −15.7) where the removed fake provider-grid had been papering over engine-level fusion of infographic labels / book-spread scans — documented as deferred engine work in the design doc:
docs/superpowers/specs/2026-07-06-parsebench-content-faithfulness-gap-closure-design.md.Type of change
Related issues
Checklists
Development
black --check+isort --check)tests/test_multicolumn_routing.py,tests/test_table_engine.py::TestLooksProseGrid)Code review
🤖 Generated with Claude Code
https://claude.ai/code/session_018Db2HoocctVP1XZpmNmEsM