docling-project / docling-project/docling
TableFormer drift on long low-entropy tables: duplicate rows, missing rows, and state-column dropouts on 2-page tables (~150 rows)
- Dominant language
- Python
- Stars
- 66.4k
- Forks
- 4.8k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 84
Description
### Bug
TableFormer produces structurally corrupted output on tables that span 2 pages and contain ~150 rows with mostly low-entropy numeric content (zeros and small integers). The two do_cell_matching modes trade one symptom for another — neither produces correct output.
Failure mode A — do_cell_matching=True
On the continuation page, the leftmost (row label / State) column is silently emitted as empty for every row. The PDF text cells exist; the matcher fails to associate them with predicted grid positions on the continuation page only.
Failure mode B — do_cell_matching=False
The autoregressive seq2seq decoder drifts after roughly 190 cells of output. Symptoms in the affected region:
Duplicate row emissions — same (state, year) emitted 2× or 3×; sometimes identical values, sometimes one correct copy + one hallucinated zeros copy.
Missing rows — entire year-rows absent from the output (e.g. a state's 2025 row missing).
Year scrambling within a state's 3-row block — e.g. 2025 row emitted before that state's 2023 row.
Orphan rows — numeric row emitted with empty state label, often duplicating values from the preceding row.
**Sample output (do_cell_matching=False):**
Indiana 2023 0 0 0 0 0 0 0
Indiana 2024 0 0 0 0 0 0 0
Iowa 2025 0 12 0 0 0 0 12 <-- year out of order
Iowa 2023 0 0 0 0 0 0 0
Iowa 2024 0 0 0 0 0 0 0
Massachusetts 2025 0 2 0 0 0 0 2 <-- year out of order
Massachusetts 2023 0 0 0 0 0 0 0
Massachusetts 2023 0 0 0 0 0 0 0 <-- duplicate same-year same-values
Massachusetts 2025 1 4** 1 0 0 0 4 <-- duplicate same-year different values
Michigan 2023 0 0 0 0 0 0 0
Michigan 2024 0 0 0 0 0 0 0
Michigan 2025 2 0 0 0 0 2 <-- missing first column value
Minnesota 2025 2 1 0 0 0 0 3 <-- year out of order
Minnesota 2024 0 0 0 0 0 0 0 <-- wrong values
Minnesota 2024 0 2 0 0 0 0 2 <-- duplicate same-year correct values
2025 2 1 0 0 0 0 3 <-- orphan: empty state label
Missouri 2023 0 0 0 0 0 0 0
Missouri 2024 0 2 0 0 0 0 2
**Expected output:**
Indiana 2023 0 0 0 0 0 0 0
Indiana 2024 0 0 0 0 0 0 0
Indiana 2025 0 12 0 0 0 0 12
Iowa 2023 0 0 0 0 0 0 0
Iowa 2024 0 0 0 0 0 0 0
Iowa 2025 0 2 0 0 0 0 2
Massachusetts 2023 0 0 0 0 0 0 0
Massachusetts 2024 0 1 0 0 0 0 1
Massachusetts 2025 1 4** 1 0 0 0 4
Michigan 2023 0 0 0 0 0 0 0
Michigan 2024 0 2 0 0 0 0 2
Michigan 2025 2 1 0 0 0 0 3
Minnesota 2023 0 0 0 0 0 0 0
Minnesota 2024 0 2 0 0 0 0 2
Minnesota 2025 2 1 0 0 0 0 3
Missouri 2023 0 0 0 0 0 0 0
Missouri 2024 0 2 0 0 0 0 2
Missouri 2025 2 0 0 0 0 0 2
In the source PDF the State column is a merged cell with rowspan=3 (one State cell per 3 year rows). Total row count for the full table: 50 states × 3 = 150 rows.
Diagnosis. Counted state-name cell emissions from the raw TableFormer output: states 1–18 (alphabetical) emit exactly once each; from state 19 onward emission counts diverge (Massachusetts 2×, Michigan 2×, Minnesota 3×). Drift threshold is around cell #190 in the decoder's autoregressive sequence — consistent with attention losing positional anchor on long, low-entropy content.
15 configuration combinations tested, all reproduce: HERON / HERON_101 / EGRET_MEDIUM / LARGE / XLARGE layout; images_scale 1.0 and 2.0; force_full_page_ocr and force_backend_text on/off; RapidOCR / EasyOCR (lang=en, conf 0.3) / Tesseract (psm=6); DoclingParse v1/v2/v4 and PyPdfium backends; keep_empty_clusters on/off; TableFormerMode FAST and ACCURATE. Layout / OCR / backend choice does not affect the drift.
A synthetic reproducer PDF generator is attached (generate_reproducer.py) — produces a 2-page PDF with 50 fake state names, 3 year rows each, mostly-zero numeric content, and the State column rendered as a merged cell with rowspan=3 (state name centered vertically, lands at the middle/2024 row's y-coordinate). The original PDF is a confidential client document and cannot be shared publicly.
### Steps to reproduce
Run the attached generate_reproducer.py to produce synthetic_long_table.pdf (2 pages, 50 states × 3 year rows, merged State column).
Run the following script:
```
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions, TableFormerMode
opts = PdfPipelineOptions()
opts.do_table_structure = True
opts.table_structure_options.mode = TableFormerMode.ACCURATE
opts.table_structure_options.do_cell_matching = False # also reproduces with True (different symptom)
converter = DocumentConverter(
format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=opts)}
)
result = converter.convert("synthetic_long_table.pdf")
# Print every table row from every page
doc = result.document
for table in doc.tables:
df = table.export_to_dataframe()
print(df.to_string())
print("---")
```
Inspect the printed rows for the affected region (roughly state #19 onward). Observe:
Duplicated (state, year) rows
Missing year rows for some states
Years emitted out of order within a state's 3-row block
Rows with empty State column
Re-run with opts.table_structure_options.do_cell_matching = True to observe the alternate symptom (empty State column on the continuation page).
...
### Docling version
Docling version: 2.84.0
Docling Core version: 2.74.0
Docling IBM Models version: 3.13.0
Docling Parse version: 5.10.0
Python: cpython-311 (3.11.5)
...
### Python version
Python 3.11.5
[synthetic_long_table.pdf](https://github.com/user-attachments/files/27404809/synthetic_long_table.pdf)
...
Contributor guide
Assessment
This issue has not been assessed yet.