Pipeline Backend Processing Window#
Overview#
The processing window is the unit of batched model inference in MinerU's pipeline backend. Rather than processing one page at a time or loading an entire document into memory, the pipeline slices all input pages (across one or more documents) into fixed-size windows and runs each window through all model stages before advancing to the next. This is the primary mechanism by which memory consumption is bounded during large-document processing.
The entry point is doc_analyze_streaming() in pipeline_analyze.py, which drives the window loop.
Window Sizing and Loop Mechanics#
Window size is read from configuration via get_processing_window_size(default=64), making 64 pages the default per window. The env var MINERU_PROCESSING_WINDOW_SIZE overrides this.
The loop in doc_analyze_streaming():
- Fills the window by consuming pages sequentially from each document context until
window_sizepages are collected or all documents are exhausted . - Logs the batch with doc-slice details: batch number, pages in window, and which page ranges belong to which documents .
- Dispatches inference to
batch_image_analyze(), which runs the fullBatchAnalyzepipeline on the window. - Distributes results back to each document's
middle_jsonviaappend_batch_results_to_middle_json(). - Finalizes completed documents: if a document's last page was in this window,
_finalize_processing_window_context()is called immediately β it runs post-processing and fires theon_doc_readycallback .
A window can span multiple documents: pages are drawn from each doc_context in order until batch_capacity reaches zero . This allows concurrent multi-doc ingestion with a single batch.
What Happens Inside a Window: BatchAnalyze#
batch_image_analyze() instantiates BatchAnalyze and calls it with the window's images. The BatchAnalyze.__call__() method runs four sequential model stages on all pages in the window:
| Stage | Model | Batch size formula |
|---|---|---|
| Layout detection | pp-doclayout_v2 | min(8, batch_ratio Γ 1) |
| Formula recognition (MFR) | MFR model | batch_ratio Γ 16 |
| OCR detection | PaddleOCR text detector | batch_ratio Γ 8 |
| OCR recognition | PaddleOCR OCR | full batch per language |
The batch_ratio multiplier is auto-detected from VRAM in batch_image_analyze(): β₯32 GB β 16, β₯16 GB β 8, β₯8 GB β 4, β₯6 GB β 2, else 1. It can be overridden with MINERU_HYBRID_BATCH_RATIO.
Memory Management Between Stages#
After layout inference and after MFR inference, clean_vram(device, vram_threshold=8) is called to free cached GPU/NPU memory . A third clean_vram call follows OCR-det batch processing . clean_memory() is called after the entire window completes.
Important caveat: clean_vram only fires when total VRAM β€ 8 GB. On high-VRAM devices (β₯32 GB), this cleanup is skipped entirely unless MINERU_VIRTUAL_VRAM_SIZE=8 is set to spoof the threshold. See Large Document Memory Management for detail.
Peak memory per window scales with MINERU_API_MAX_CONCURRENT_REQUESTS Γ MINERU_PROCESSING_WINDOW_SIZE. The default (3 concurrent Γ 64-page window) targets ~32 GB RAM.
Error Handling#
The window loop uses a two-level try/finally pattern:
- Inner
finally: Always closes and clearsimages_listfor all documents in the current window, regardless of whetherbatch_image_analyze()succeeded or raised. This prevents PIL image objects from accumulating in memory across failures. - Outer
finally: Ensures allpdf_docpdfium document handles are closed if the loop exits for any reason (exception or normal completion).
If batch_image_analyze() raises, the window's images are still freed (inner finally), but the results are never written to middle_json and on_doc_ready is never called for affected documents. The exception propagates to the caller.
Within BatchAnalyze, individual model stages use try/except only for table orientation classification and table classification, logging warnings and continuing with a fallback rather than aborting . Layout, MFR, and OCR stages do not have stage-level exception handling β failures propagate immediately and abort the entire window.
Key Configuration#
| Variable | Default | Effect |
|---|---|---|
MINERU_PROCESSING_WINDOW_SIZE | 64 | Pages per inference window |
MINERU_HYBRID_BATCH_RATIO | Auto (VRAM-based) | Scales batch sizes for all model stages |
MINERU_VIRTUAL_VRAM_SIZE | β | Spoofs VRAM size to force clean_vram to fire |
MINERU_LMDEPLOY_DEVICE=corex | β | Disables OCR det batching; falls back to single-image inference |
Source Files#
mineru/backend/pipeline/pipeline_analyze.pyβ window loop (doc_analyze_streaming),batch_image_analyze,ModelSingletonmineru/backend/pipeline/batch_analyze.pyβBatchAnalyze.__call__, per-stage inference andclean_vramcall sitesmineru/utils/model_utils.pyβclean_vram,clean_memory,get_vram