Skip to content

fix: release page images for pages that carry no figure - #4166

Open
junkreef wants to merge 1 commit into
docling-project:mainfrom
junkreef:fix/release-page-images-without-figures
Open

junkreef wants to merge 1 commit into
docling-project:mainfrom
junkreef:fix/release-page-images-without-figures

Conversation

@junkreef

@junkreef junkreef commented Sep 4, 2026

Copy link
Copy Markdown

_release_page_resources() cleared a page's rendered image only when keep_images was
false, but keep_images is document-wide: it is true when any of
generate_page_images, generate_picture_images or generate_table_images is set. One
figure anywhere therefore pinned every page's image until _assemble_document ran, so
memory grew with the page count for the whole conversion.

The decision is now made per page. An image is kept when page images are part of the
requested output, or when the assembled page holds a FigureElement (with
generate_picture_images) or a Table (with generate_table_images). A page that has
not been assembled yet is kept, since what it holds is not yet known.

This is safe because _assemble_document maps those two element types one-to-one onto
the PictureItems and TableItems it crops, and the enrichment steps re-render through
the page backend, which keep_backend already preserves whenever they are enabled.

Verification

A 1356-page manual containing 9 figures, generate_picture_images=True,
images_scale=2.0, first 400 pages:

peak RSS growth
before 5515 MB
after 1372 MB

Per-page growth changes from a straight line (12.4 → 13.7 MB/page as the range grows) to
a curve that flattens (8.2 → 5.7 → 3.4 MB/page). The extracted figures are byte-identical
(SHA-256) and the text and table counts are unchanged.

tests/test_page_resource_release.py is new: it exercises _page_image_has_consumer and
_release_page_resources directly across the option combinations, with a stand-in that
carries only the pipeline options, so no model is loaded. Eight of its eleven tests fail
on v2.124.0.

One behaviour note for callers: a page without a figure now returns None from
conv_res.pages[i].image unless generate_page_images is set, which is the documented
way to ask for page images.

Issue resolved by this Pull Request:
Resolves #4163

Checklist:

  • Documentation has been updated, if necessary. (not necessary — no option or
    documented contract changes)
  • Examples have been added, if necessary. (not necessary)
  • Tests have been added, if necessary.

`_release_page_resources` cleared a page's rendered image only when
`keep_images` was false, and `keep_images` is document-wide: it is true when any
of `generate_page_images`, `generate_picture_images` or `generate_table_images`
is set. One figure anywhere in the document therefore pinned *every* page's
image until `_assemble_document` ran, even though only the pages carrying an
element that step crops actually need it. On a 1356-page manual holding nine
figures, that is the difference between growing ~14 MB per page and levelling
off; peak RSS for a 600-page conversion fell from 5.5 GB to 1.4 GB.

Decide per page instead: keep the image when page images are part of the
requested output, or when the assembled page holds a `FigureElement` (with
`generate_picture_images`) or a `Table` (with `generate_table_images`). A page
that has not been assembled yet is kept, since what it holds is not known.
`_assemble_document` maps those elements one-to-one onto the `PictureItem`s and
`TableItem`s it crops, and enrichment steps re-render through the page backend,
which `keep_backend` already preserves when they are enabled.

Note for callers reading `conv_res.pages[i].image` after a conversion: pages
without a figure now return None unless `generate_page_images` is set, which is
the documented way to ask for page images.

Signed-off-by: Junpei Kishi <junkreef@longarch.net>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

DCO Check Passed

Thanks @junkreef, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Page images are retained for every page when any image output is requested

1 participant