docling-project / docling-project/docling

`PaginatedPipeline._unload` prematurely unloads page backends, ignoring `keep_backend` flag

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

Description

Hello,

In the `docling` library, the `PaginatedPipeline._unload` method unconditionally unloads the `_backend` for each page in `conv_res.pages`. This occurs regardless of the `keep_backend` flag, which is intended to prevent this behavior.

This premature unloading of the page backends can cause `AttributeError` exceptions if the page backends are accessed after the pipeline has completed its execution, for example, to re-render page images at a different resolution (my use case).

**Docling version**
2.41.0

**To Reproduce**

1. Create a custom pipeline that inherits from `VlmPipeline`.
2. In the main script, after `doc_converter.convert()` is called, attempt to access `page._backend` for any page in the `ConversionResult.pages` list.
3. The `_backend` attribute will be `None`, and any attempt to call methods on it will result in an `AttributeError`.

**Expected Behavior**

When `keep_backend` is set to `True` in a `PaginatedPipeline`, the page backends should not be unloaded by the `_unload` method, and should remain accessible after the conversion process is complete.

**Analysis**

The issue is in `docling/pipeline/base_pipeline.py`, in the `PaginatedPipeline._unload` method:

```python
def _unload(self, conv_res: ConversionResult) -> ConversionResult:
for page in conv_res.pages:
if page._backend is not None:
page._backend.unload()

if conv_res.input._backend:
conv_res.input._backend.unload()

return conv_res
```

This method does not check the `self.keep_backend` flag before unloading the page backends.

**Workaround**

A temporary workaround is to create a custom pipeline that overrides the `_unload` method to prevent it from unloading the page backends:

```python
class CustomVlmPipeline(VlmPipeline):
# ... (other methods)

def _unload(self, conv_res: ConversionResult):
# We override this method to prevent the backends from being unloaded.
pass # Or only unload the main document backend
```

**Proposed Solution**

The `PaginatedPipeline._unload` method should be modified to respect the `keep_backend` flag:

```python
def _unload(self, conv_res: ConversionResult) -> ConversionResult:
if not self.keep_backend:
for page in conv_res.pages:
if page._backend is not None:
page._backend.unload()

if conv_res.input._backend:
conv_res.input._backend.unload()

return conv_res
```

This change would align the behavior of the `_unload` method with the intended purpose of the `keep_backend` flag and prevent unexpected errors when working with page backends after the conversion process.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.