docling-project / docling-project/docling
`PaginatedPipeline._unload` prematurely unloads page backends, ignoring `keep_backend` flag
- 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
Assessment
This issue has not been assessed yet.