PDF Document Pipeline#
StandardPdfPipeline is Docling's production PDF conversion pipeline . It extends ConvertPipeline and implements a multi-threaded stage topology where each stage runs in its own worker thread, enabling pipeline-level parallelism across pages. Models are initialized once at construction time and shared read-only across worker threads .
The pipeline is driven by ThreadedPdfPipelineOptions and is the entry point for all PDF conversion invoked through DocumentConverter with pdf_backend set to docling_parse, threaded_docling_parse, or equivalent.
Stage Topology#
Pages flow through five threaded stages wired in sequence, followed by sequential cross-page assembly :
A dedicated PageProducer thread feeds ThreadedItem envelopes into the first stage. Each stage pulls batches from its input queue, calls the model, and emits results to the next stage. The main thread drains the output queue and collects completed pages .
Key infrastructure types:
| Type | Purpose |
|---|---|
ThreadedQueue | Bounded, blocking queue with close() that propagates shutdown downstream |
ThreadedItem | Envelope carrying a Page, run_id, page_no, ConversionResult, and error state |
ThreadedPipelineStage | One worker thread; batches items by run_id for efficient model calls |
PreprocessThreadedStage | Variant that validates backends before calling the model |
RunContext | Wiring for a single execute call (stages, queues, timed-out run IDs) |
ProcessingResult | Aggregates successful pages + failed pages for a run |
Per-Stage Behavior#
1. Preprocess (PreprocessThreadedStage, batch size 1)#
PagePreprocessingModel validates the page backend and renders a page image at the configured images_scale. Invalid pages are marked failed before the model is invoked . Options: PagePreprocessingOptions(images_scale=...) .
2. OCR (ThreadedPipelineStage)#
Configured via PdfPipelineOptions.ocr_options; enabled only when do_ocr=True (default). The model is created through get_ocr_factory(), which supports pluggable engines: EasyOCR, Tesseract (CLI and Python), RapidOCR, OcrMac, Nemotron, and KServe v2 .
3. Layout (ThreadedPipelineStage)#
LayoutModel.predict_layout() batches page images through LayoutPredictor.predict_batch() from docling-ibm-models, then immediately runs LayoutPostprocessor.postprocess() on each page:
- Confidence thresholding per label
- Label remapping (e.g.,
TITLE→SECTION_HEADER) - Cell-to-cluster assignment: PDF/OCR text cells are spatially matched to layout clusters using an R-tree spatial index (
SpatialClusterIndex) to efficiently find candidate clusters that may overlap with table cells - Orphan cell recovery: unassigned cells become new
TEXTclusters - Overlap resolution: competing clusters are deduplicated by area/confidence ratios, with separate thresholds for regular, picture, and wrapper cluster types
The LayoutModel defines label sets used downstream by PageAssembleModel: TEXT_ELEM_LABELS, TABLE_LABELS, FIGURE_LABEL, and CONTAINER_LABELS .
4. Table Structure (ThreadedPipelineStage)#
Runs TableFormer V1, V2, or Granite Vision depending on table_structure_options, when do_table_structure=True.
5. Assemble (ThreadedPipelineStage, batch size 1, with postprocess hook)#
PageAssembleModel.__call__() iterates page.predictions.layout.clusters and converts each cluster to a typed element:
TEXT_ELEM_LABELS→TextElement— text is assembled from cells viasanitize_text(), which handles dehyphenation across lines, Unicode normalization, and ligature expansion (FB00–FB06 range)TABLE_LABELS→Table(frompage.predictions.tablestructure, or empty fallback)PICTURE→FigureElementFORM/KEY_VALUE_REGION→ContainerElement
Hyperlinks are resolved per-cluster via _match_hyperlink(), which requires ≥50% spatial overlap between a hyperlink annotation rect and the cluster bbox. The assembled result is stored in page.assembled .
After assemble, the _release_page_resources() postprocess hook frees the image cache and unloads the page backend (unless enrichment stages require them) .
Cross-Page Assembly (_assemble_document)#
After all pages are collected, _assemble_document() runs sequentially :
- Collects all
page.assembledelements into a singleAssembledUnit. ReadingOrderModel: converts assembled elements toReadingOrderPageElementobjects, callsReadingOrderPredictor.predict_reading_order()(fromdocling-ibm-models), then resolves caption/footnote attachments and text merges (soft-hyphen handling). Builds the finalDoclingDocument, assigningContentLayer.FURNITUREtoPAGE_HEADERandPAGE_FOOTER.HeadingHierarchyModel: infers heading levels; optionally uses PDF bookmarks extracted before pipeline stages start .enrichment_pipe: post-document enrichments (code/formula, picture classification/description, chart extraction) run fromBasePipeline._enrich_document().
Confidence scores are aggregated across pages: layout_score (mean), ocr_score (mean), table_score (mean), parse_score (10th percentile) .
Configuration Reference#
Options class: ThreadedPdfPipelineOptions .
| Option | Default | Effect |
|---|---|---|
ocr_batch_size, layout_batch_size, table_batch_size | varies | Batch sizes per stage |
queue_max_size | — | Back-pressure limit per inter-stage queue |
batch_polling_interval_seconds | — | How long a stage waits for a batch to fill |
document_timeout | None | Per-document timeout; breach sets PARTIAL_SUCCESS |
do_ocr | True | Enable OCR model |
do_table_structure | True | Enable table structure extraction |
do_code_enrichment, do_formula_enrichment | False | Enable post-assembly VLM enrichment |
heading_hierarchy_options.use_bookmarks | — | Extract PDF outline before pipeline starts |
generate_page_images / generate_picture_images | False | Attach rendered images to output items |
Key Source Files#
| File | Purpose |
|---|---|
docling/pipeline/standard_pdf_pipeline.py | Pipeline orchestration, stage wiring, _build_document, _assemble_document |
docling/models/stages/layout/layout_model.py | Layout predictor wrapper, label sets, batch prediction |
docling/utils/layout_postprocessor.py | Cell assignment, overlap resolution, orphan handling |
docling/models/stages/page_assemble/page_assemble_model.py | Cluster→element conversion, text sanitization, hyperlink matching |
docling/models/stages/reading_order/readingorder_model.py | Reading order prediction, DoclingDocument construction |
docling/models/stages/page_preprocessing/page_preprocessing_model.py | Page image rendering |
docling/pipeline/base_pipeline.py | _enrich_document() loop, ConvertPipeline base |
docling/datamodel/pipeline_options.py | ThreadedPdfPipelineOptions, all model options |