VLM Pipeline#
VlmPipeline is Docling's holistic page-understanding pipeline — it runs a single Vision Language Model over each page image rather than composing results from separate layout, OCR, and table-structure models. It is selected via --pipeline vlm on the CLI or by passing VlmPipelineOptions to DocumentConverter.
VlmPipeline inherits from PaginatedPipeline and lives in docling/pipeline/vlm_pipeline.py. Its constructor branches on the type of vlm_options:
- New path (recommended):
VlmConvertOptions→ usesVlmConvertModel, the preset-based runtime system. - Legacy path (deprecated):
InlineVlmOptionsorApiVlmOptions→ wires up one ofHuggingFaceTransformersVlmModel,HuggingFaceMlxModel,VllmVlmModel, orApiVlmModel. ADeprecationWarningis raised; migrate toVlmConvertOptions.from_preset(...).
VlmPipelineOptions sets generate_page_images = True by default and exposes a force_backend_text flag: when enabled (DOCTAGS format only), bounding boxes from the VLM are used for PDF text extraction, replacing model-predicted text with the native PDF layer.
Processing Flow#
initialize_page → build_pipe (VlmConvertModel) → _assemble_document → enrichment_pipe
-
initialize_page— loads the page backend, reads page size, and (ifforce_backend_text) fetches a segmented page for later text override. -
VlmConvertModel.__call__— the solebuild_pipestage. For each page it scales the page image (get_image(scale, max_size)), fetches the model's prompt template, buildsVlmEngineInputobjects, and callsengine.predict_batch(). The raw model text is stored inpage.predictions.vlm_response. -
_assemble_document— readsresponse_formatfrommodel_spec(or legacyvlm_options) and dispatches to the appropriate parser (see Response Format Parsers). After assembly,generate_picture_imagestriggers per-picture image cropping from the page image. -
enrichment_pipe— currently empty; reserved for future post-assembly enrichment stages. -
_determine_status— overrides the base pipeline's status logic to detectVlmStopReason.LENGTH(truncated output) orCONTENT_FILTERED, both of which downgrade the result toPARTIAL_SUCCESSand append anErrorItem.
Note:
ThreadedDoclingParseDocumentBackendis explicitly unsupported —VlmPipelinerequires ordered/random page access viaload_page(). UseStandardPdfPipelineif you need streamed page delivery.
Response Format Parsers#
ResponseFormat is a str enum in pipeline_options_vlm_model.py. _assemble_document switches on its value:
ResponseFormat | Parser method | Mechanism |
|---|---|---|
DOCTAGS | _turn_dt_into_doc | DocTagsDocument.from_doctags_and_image_pairs → DoclingDocument.load_from_doctags |
DOCLANG | _turn_doclang_into_doc | Per-page DocLangDocDeserializer.deserialize_str → DoclingDocument.concatenate |
MARKDOWN | _convert_text_with_backend | MarkdownDocumentBackend |
HTML | _convert_text_with_backend | HTMLDocumentBackend |
DEEPSEEKOCR_MARKDOWN | _parse_deepseekocr_markdown | docling.utils.deepseekocr_utils.parse_deepseekocr_markdown — parses label[[x1,y1,x2,y2]] spatial annotation format |
CHANDRA_HTML | _parse_chandra_html | docling.utils.chandra_utils.parse_chandra_html |
DOTS_JSON | _parse_dots_json | docling.utils.dots_utils.parse_dots_json with Qwen2VL image-size normalization |
DOCTAGS specifics: DocTags is the XML-like token format (<title>, <text>, <loc_N> bounding-box tokens) emitted by models such as SmolDocling and Granite-Docling. The pipeline assembles all pages as (tokens_str, PIL.Image) pairs, then delegates to DoclingDocument.load_from_doctags in docling-core. When force_backend_text=True, every TextItem's text is overwritten with the string extracted from the native PDF backend at the predicted bounding box.
DOCLANG specifics: Each page's raw VLM text is scanned for a <doclang>…</doclang> fragment via _extract_doclang_fragment. Missing or malformed fragments produce an empty stub page and a PARTIAL_SUCCESS status instead of a hard failure.
Markdown / HTML specifics: The pipeline strips triple-backtick code fences (via _extract_code_block) before passing the text to the backend. Provenance bounding boxes are faked as (0,0,0,0) since these formats carry no spatial coordinates.
Document Assembly#
All parsers produce per-page DoclingDocument instances. The shared helper _add_page_metadata_and_concatenate attaches the page image and size metadata to each per-page doc, then calls DoclingDocument.concatenate(docs=page_docs) to merge them into a single document with renumbered pages. (The DOCTAGS path bypasses this helper and calls DoclingDocument.load_from_doctags directly, which handles multi-page concatenation internally.)
For DOCLANG, deserialization is fault-tolerant: exceptions during deserializer.deserialize_str() produce an empty DoclingDocument for that page rather than aborting the whole document.
The Markdown/HTML assembly iterates items with included_content_layers=set(ContentLayer) (all layers), ensuring no content is silently dropped before the final document is returned to the caller.
Model Presets#
VlmConvertOptions uses the preset system from stage_model_specs.py. Call VlmConvertOptions.from_preset("<name>") to configure a model. The default for VlmPipelineOptions is granite_docling.
| Preset | Response Format | Notes |
|---|---|---|
smoldocling | DOCTAGS | SmolDocling-256M, structural + bboxes |
granite_docling | DOCTAGS | IBM Granite-Docling-258M, pipeline default |
deepseek_ocr | DEEPSEEKOCR_MARKDOWN | Via Ollama/LM Studio API |
granite_vision | MARKDOWN | Granite-Vision-3.3-2B |
pixtral | MARKDOWN | Mistral Pixtral-12B |
phi4 | MARKDOWN | Microsoft Phi-4 multimodal |
qwen | MARKDOWN | Qwen2.5-VL-3B |
chandra_ocr2 | CHANDRA_HTML | 5.3B model with bounding-box HTML |
dots_ocr / dots_mocr | DOTS_JSON | dots.ocr / dots.mocr 3B JSON output |
Additional presets include got_ocr, nanonets_ocr2, gemma_12b, gemma_27b, dolphin, glm_ocr, falcon_ocr, lightonocr.
Engine can be overridden independently of the preset:
from docling.datamodel.pipeline_options import VlmConvertOptions, VlmPipelineOptions
from docling.datamodel.vlm_engine_options import ApiVlmEngineOptions
options = VlmPipelineOptions(
vlm_options=VlmConvertOptions.from_preset(
"smoldocling",
engine_options=ApiVlmEngineOptions(url="http://localhost:11434"),
)
)
Key Files#
| File | Purpose |
|---|---|
docling/pipeline/vlm_pipeline.py | VlmPipeline — orchestration, response format dispatch, document assembly helpers |
docling/datamodel/pipeline_options.py | VlmPipelineOptions, VlmConvertOptions |
docling/datamodel/pipeline_options_vlm_model.py | ResponseFormat enum, InlineVlmOptions, ApiVlmOptions (legacy) |
docling/models/stages/vlm_convert/vlm_convert_model.py | VlmConvertModel — page-image inference stage |
docling/datamodel/stage_model_specs.py | All VlmConvertOptions preset definitions |
docling/utils/deepseekocr_utils.py | parse_deepseekocr_markdown — spatial annotation parser |
docling/utils/chandra_utils.py | parse_chandra_html — Chandra-OCR-2 HTML parser |
docling/utils/dots_utils.py | parse_dots_json — dots.ocr/mocr JSON parser |
Related topics: VLM Inference Engine (backend abstraction) · VLM Formula and Code Extraction (post-assembly enrichment stage) · DocLang Format · DoclingDocument Builder API