docling-project / docling-project/docling

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

Open
#4,163 0 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

`StandardPdfPipeline._release_page_resources()` drops a page's rendered image only when
`keep_images` is false:

```python
if not self.keep_images:
page._image_cache = {}
```

but `keep_images` is document-wide:

```python
self.keep_images = (
self.pipeline_options.generate_page_images
or self.pipeline_options.generate_picture_images
or self.pipeline_options.generate_table_images
)
```

So asking for picture crops on a document that contains a single figure keeps *every*
page's rendered image alive until `_assemble_document` runs, even though only the pages
carrying an element that step crops still need one. Memory then grows with the page
count for the whole conversion.

The decision could be made per page: 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`).

### Measurements

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

| | peak RSS growth |
| --- | --- |
| as-is | 5515 MB |
| releasing pages that carry no figure | 1372 MB |

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

On a different 2252-page manual the rendered page images were measured to be about 75%
of the peak: dropping `images_scale` from 2.0 to 1.0, which quarters the pixel area, cut
peak growth from 5702 MB to 2502 MB.

Possibly related: #4071.

### Steps to reproduce

Convert a long PDF that contains at least one picture, with
`PdfPipelineOptions(generate_picture_images=True)`, and watch RSS. Peak grows roughly
linearly with the number of pages converted, even though only a handful of pages hold a
figure. Inspecting `conv_res.pages[i]._image_cache` mid-conversion shows every page that
has passed the assemble stage still holding its image.

### Docling version

2.124.0

### Python version

3.13.15

Contributor guide

Open the contributing guide

Research direction

Start at StandardPdfPipeline._release_page_resources() and trace how _assemble_document uses page._image_cache with the generate_picture_images and generate_table_images options. Reproduce the long-PDF case using PdfPipelineOptions(generate_picture_images=True), then verify that only relevant pages retain images while extracted figures, text, and table counts remain unchanged and memory growth is reduced.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.