docling-project / docling-project/docling

Table rows/cells get misaligned on CJK PDFs with a partial/unreliable native text layer since the layout-driven OCR pipeline (v2.116.0, #3710)

Open
#4,083 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
66.4k
Forks
4.8k
Avg merge
2d 21h
Merged PRs (30d)
84

Description

## Bug

Since v2.116.0 (the layout-driven OCR pipeline refactor in #3710), table extraction can misalign row labels and numeric values on PDFs where the embedded native PDF text layer is only partially reliable — common for auto-generated Chinese/Japanese/Korean regulatory filings, where some table cells carry real native PDF text and others are effectively garbled or image-backed and need OCR.

## What we observed

Bisected on a real-world document (a Chinese company disclosure filing, containing a consolidated cash-flow statement table with many line items and several empty cells):

- docling 2.115.0: table extracts correctly — every row label sits on its own row, numeric values aligned to the correct line item.
- docling 2.116.0: same document, same `do_ocr=True` + default `RapidOcrOptions()` (nothing else changed) — row labels start merging into single cells (e.g. two distinct line items concatenated into one cell), and numeric values shift onto the wrong row.

We bisected the entire 2.113.0 → 2.123.0 range in isolation, holding `docling-core`, `docling-parse`, and `docling-ibm-models` fixed while only varying `docling`/`docling-slim`. The corruption is attributable specifically to the `docling` package version — each of the other three packages was tested independently (bumped alone, others held at the 2.115.0-era baseline) and produced byte-identical output to the clean baseline on this document.

We also retested against 2.122.0/2.123.0 (docling-parse forced to 7.16.0 per the version floor introduced in 2.123.0): the *specific* misalignment we originally found is now fixed, but a *new* misalignment of the same kind appears elsewhere in the same table (a different line item loses its numeric value, which shifts onto the following row instead), and a separate table in the same document (a list of regulatory announcement references) is *more* broken than at 2.116.0 (a row now splits into several fragments and loses its announcement reference number). The extracted text-item count on this document has stayed roughly stable across the whole 2.116–2.123 range (284–287) and consistently higher than the pre-2.116 baseline (200), suggesting the underlying cell segmentation is still unstable rather than converging toward the old behavior.

## Hypothesis

We suspect this relates to the new default `OcrMode.PDF_AWARE_LAYOUT_REGIONS` + `PDF_FIRST` cell-merge priority from #3710: on a page where the native PDF text layer is present but unreliable (not a scanned image, not fully absent), the "eliminate layout regions that overlap with all-text PDF cells" heuristic may retain low-quality/misplaced PDF-native cells that the pre-2.116 behavior would simply have overridden with OCR output. We have not root-caused this to a specific line inside `layout_postprocessing_model.py` / `base_ocr_model.py` — filing to report the reproducible regression and the precise version boundary, in case it's useful to someone more familiar with the new pipeline's internals.

## Reproduction

The document is a public Chinese listed-company disclosure (extraordinary/annual general meeting minutes + financial statements), still hosted live at its original public source:

**https://www.xgd.com/static/upload/file/20220726/1658803467765795.pdf**

(verified live and byte-identical to our copy at time of filing)

Steps:
1. Download the PDF from the URL above.
2. Convert with `do_ocr=True`, default `RapidOcrOptions()` (default `mode=OcrMode.DEFAULT` → `PDF_AWARE_LAYOUT_REGIONS`).
3. Look at the consolidated cash-flow statement table (section "7、合并年初到报告期末现金流量表") in the exported markdown/JSON.
4. Compare docling 2.115.0 vs 2.116.0+: row labels/numeric values shift between cells.

CJK content in particular seems to trigger this more — possibly because CJK text layers from certain generator/encoding setups are more likely to be "present but unreliable" rather than cleanly absent, landing in the ambiguous zone the new heuristic handles differently from the old one.

## Environment
- docling 2.113.0 (clean) through 2.123.0 (still reproduces, different location)
- docling-core 2.92.0, docling-parse 7.15.0/7.16.0, docling-ibm-models 3.14.0 (isolated as not responsible via independent version bisection)
- `do_ocr=True`, default `RapidOcrOptions`
- Python 3.12

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the CJK PDF conversion with do_ocr=True and default RapidOcrOptions, comparing docling 2.115.0 with a current version. Read layout_postprocessing_model.py and base_ocr_model.py, focusing on PDF-aware layout regions and native-text cell merging. Done means table row labels and numeric values remain aligned, with a regression test covering the supplied document or equivalent behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-vision, data
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.