Repository navigation
feat: add LightOnOCR-3 presets and grounded output parsing - #4789
PierreMesure wants to merge 7 commits into
Conversation
|
✅ DCO Check Passed Thanks @PierreMesure, all your commits are properly signed off. 🎉 |
1284c0e to
628935a
Compare
Merge Protections🟢 Merge protection satisfied — ready to merge. Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
AI triage (advisory)Checked commit The PR adds three LightOnOCR-3 presets ( CI safety: no concern found. A maintainer must still approve CI. 2 related pull request(s) in the same code
The |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Fixed the CI failure in 436888e. The VLM job had one failure: The fix adds the missing format to that list. The existing test still checks presets across all three stage types. All 11 new LightOnOCR-3 tests already passed in the core CI job. Local validation on Python 3.12:
Local Python 3.10 testing stopped at import because the locked SciPy wheel could not load on this Mac. Python 3.10 validation of the fix remains for Linux CI. No dependency or production-code changes were needed. |
There was a problem hiding this comment.
AI first review (advisory): blocker found
This review covers the full diff at 436888e88f. It read the code and did not run it.
docling/utils/lightonocr_utils.py imports marko at module level, but marko is only in the optional format-markdown extra. A docling-slim[models-vlm-inline] install fails on the first page with a bare ModuleNotFoundError. Check this dependency first. The parser logic and tests look consistent with the existing Chandra mapper.
A maintainer makes the merge decision. This review never approves the pull request.
| from collections.abc import Iterator | ||
| from pathlib import Path | ||
|
|
||
| import marko |
There was a problem hiding this comment.
blocker: marko is an optional dependency, but the new parser imports it with no guard
pyproject.toml lists marko only in the format-markdown extra. The models-vlm-inline extra does not include it. The lazy import in VlmPipeline._finalize_page_document (docling/pipeline/vlm_pipeline.py) runs this module on the first page.
Trigger: a docling-slim[models-vlm-inline] install, with no format-web or format-markdown, runs lightonocr3_*.
Result: inference runs on the page. Then parsing raises a bare ModuleNotFoundError: marko, and the conversion fails.
The repository already handles this case. MarkdownDocumentBackend raises an ImportError with an install hint. docling/utils/dots_utils.py:78-84 does the same.
Fix: import marko inside parse_lightonocr_markdown. On ImportError, raise a message that tells the user to run pip install 'docling-slim[format-markdown]'. You can also add format-markdown to the dependencies of models-vlm-inline. The full docling package is not affected, because it includes format-web.
There was a problem hiding this comment.
Confirmed and fixed in fa841f3.
The regression test blocks marko in a fresh interpreter, using the existing optional-dependency test helper. Before the fix, the parser import failed with ModuleNotFoundError. With the fix, the module imports successfully and a parsing call raises ImportError with pip install 'docling-slim[format-markdown]'. The original import error is preserved as the cause.
The import now runs inside parse_lightonocr_markdown, as suggested. The LightOnOCR-3 documentation also states the Markdown-extra requirement for slim installations. The dependency remains optional.
Validation on Python 3.12:
- Optional-dependency tests selected with
-k 'lightonocr or marko': 3 passed, including the new regression test. - LightOnOCR-3, Chandra, Unlimited OCR, VLM conversion, and streaming tests: 76 passed.
UV_NO_SYNC=1 make validate: all applicable hooks passed, including Ruff, ty, Tach, module coverage, and file-size checks.
Full Linux CI has not yet validated this commit.
There was a problem hiding this comment.
AI first review (advisory): no blocker found
This review covers the changes since 436888e88f at fa841f325b. It read the code and did not run it.
The earlier blocker (module-level marko import failing on docling-slim[models-vlm-inline] installs) is fixed: marko is now imported lazily inside parse_lightonocr_markdown and raises an ImportError with the correct install hint. The regression test and docs update look consistent. No new issues found in the incremental changes.
Earlier findings
- fixed (blocker):
markois an optional dependency but the new parser imports it with no guard
A maintainer makes the merge decision. This review never approves the pull request.
|
Fixed three parser defects in 493f6fa:
Added 16 test cases to Validation on Python 3.12:
The shared Chandra mapper and dependency declarations are unchanged. Full Linux CI has not yet validated this commit. |
|
Shared follow-up fixes are now tracked and implemented in focused PRs:
This PR now reuses the shared math renderer and delimiter normalizer in de76b6b. The HTML mapper correction is applied at the shared component, and the LightOn-only heading compensation has been removed. The shared implementations are identical to the corresponding follow-up PRs, so the math and heading logic need not remain duplicated in Validation of this refactor: 199 passed, 6 skipped across the VLM and related parser/pipeline tests, plus all applicable |
|
Kept the shared Markdown renderer and its tests identical to #4908 in ab79d5b. This addresses the confirmed GFM side effect reported on that PR: native inline parsing must preserve literal tildes and native block text. Full-page GFM parsing remains enabled for LightOn tables. The shared-parser and LightOn test suites pass: 36 passed, 1 skipped. |
Signed-off-by: Pierre Mesure <pierre.mesure@statskontoret.se>
Include LIGHTONOCR_MARKDOWN in the explicit valid-format list so the LightOnOCR-3 presets pass the cross-stage consistency check. Signed-off-by: Pierre Mesure <pierre@mesu.re>
Defer the marko import until parsing and report the format-markdown extra when it is missing. Add a cold-import regression test and document the requirement for slim installations. Signed-off-by: Pierre Mesure <pierre@mesu.re>
Keep LaTeX literal during Markdown parsing and store formulas without export delimiters. Preserve section heading levels using Docling's title-relative levels, and track fences that start on grounding-marker lines. Add regression cases for formula escapes and multiline content, heading exports and coordinates, inline math versus code, and both fence styles. Keep the shared Chandra mapper unchanged. Signed-off-by: Pierre Mesure <pierre@mesu.re>
Move Markdown math rendering and delimiter normalization into shared helpers. Correct heading depth in the shared HTML mapper and remove the LightOn-only compensation. Coordinate with parser issues docling-project#4902, docling-project#4903, and docling-project#4904. Signed-off-by: Pierre Mesure <pierre@mesu.re>
Signed-off-by: Pierre Mesure <pierre@mesu.re>
Signed-off-by: Pierre Mesure <pierre@mesu.re>
ab79d5b to
7173aab
Compare
|
Rebased onto current main ( Synced the shared renderer and its tests with #4908, including the currency-range review fix, while retaining full-page GFM tables. Updated the heading documentation and PR description. Validation: 193 passed, 2 skipped for the focused LightOn/shared/preset/optional-dependency suites; 267 passed, 1 skipped in a clean combined merge with #4908. @cau-git, it's ready to review! 😊 |
|
@PierreMesure Thanks, the integration follows the other VLM adapters well. Before merge:
Since docling-core#924 is merged, #4908 should become mergeable and then this one too. |
LightOnOCR-3 adds block grounding, image descriptions, and chart tables, but Docling currently only has a LightOnOCR-2 preset. This adds the official 0.8B, 1B, and 4B models as
lightonocr3_08b,lightonocr3_1b, andlightonocr3_4bpresets. The existinglightonocrpreset continues to use v2.The new presets use the
groundingprompt and a nativeLIGHTONOCR_MARKDOWNresponse format. The parser accepts markers on their own lines and inline with content, scales 0–1000 coordinates to the source page, and preserves Markdown text, HTML tables, image descriptions, and chart tables. It reuses the existing rich HTML fragment mapper. Empty-prompt transcription is also supported. Transformers decoding removes special tokens; local inference requires Transformers 5.5.4 or later.Boxes remain block-level: derived children and list items do not receive synthetic coordinates. Continuation labels keep their base class without merging blocks. Separate captions are not linked by proximity. No unverified MLX export is configured.
Rebased onto
mainat1ee1db0f648c4bd2d25146f5dd100d1b75d94d7dafter #4964 merged. This branch uses the upstream heading and formula helpers without changing them. The LightOn mapper records raw heading depths when the pipeline maps a page, and the pipeline normalizes the joined document once. Direct mapper calls normalize their page by default. Regression tests cover pages with and without a depth-1 section.The shared Markdown renderer and its tests remain identical to #4908. They include the currency-range fix:
Price $5-$10 and $x$.keeps the price as text and creates only thexformula. Native inline parsing preserves tildes, alert markers, pipe-table text, and bare URLs. Full-page GFM table parsing stays enabled for LightOn.Validation of current code on Python 3.12 with the locked docling-core 2.103.1:
UV_NO_SYNC=1 make validateand hooks on every file in this PR: passed.Earlier validation included real 0.8B CPU inference through
VlmConvertModel.process_imagesfor grounding and empty-prompt transcription on a synthetic lease page, using Transformers 5.18.0, bfloat16, eight CPU threads, and compilation disabled. This inference was not rerun for the rebase. The 1B and 4B checkpoints, GPU/MLX inference, API-server inference, and the full repository suite were not run locally.Fixes #4788.