VLM Extraction Pipeline#
Overview#
The VLM Extraction Pipeline is Docling's subsystem for pulling specific structured fields from document pages using a Vision-Language Model. It is distinct from VlmPipeline (which performs full document conversion) — this pipeline produces typed, schema-driven output rather than a converted document representation.
The entry point is DocumentExtractor in docling/document_extractor.py. It accepts PDF and IMAGE inputs only and exposes two public methods:
extract(source, template, ...)— single-document, returnsExtractionResultextract_all(source, template, ...)— batch, returnsIterator[ExtractionResult]
Pipeline instances are cached by (pipeline_class, options_hash), so repeated calls with the same configuration reuse the loaded model .
Install requirement:
pip install docling[vlm]
Configuration: VlmExtractionPipelineOptions#
VlmExtractionPipelineOptions in docling/datamodel/pipeline_options.py has two fields:
| Field | Type | Default | Notes |
|---|---|---|---|
vlm_options | InlineVlmOptions | NU_EXTRACT_2B_TRANSFORMERS | Which VLM to load |
extraction_prompt_style | ExtractionPromptStyle | ExtractionPromptStyle.NUEXTRACT | How the template is formatted |
The docstring explicitly lists the two supported model/style combinations :
NU_EXTRACT_2B_TRANSFORMERS+ExtractionPromptStyle.NUEXTRACT(default)GRANITE_VISION_4_1_TRANSFORMERS+ExtractionPromptStyle.GRANITE_VISION
Model Presets#
Both extraction-specific presets live in docling/datamodel/vlm_model_specs.py:
NU_EXTRACT_2B_TRANSFORMERS : numind/NuExtract-2.0-2B, pinned to a specific revision to avoid MPS issues; response_format=PLAINTEXT; prompt is empty (template is injected by the pipeline, not the model spec).
GRANITE_VISION_4_1_TRANSFORMERS : ibm-granite/granite-vision-4.1-4b; also pinned by revision; requires trust_remote_code=True; prompt is likewise empty.
Both use InferenceFramework.TRANSFORMERS, torch_dtype="bfloat16", and support CPU/CUDA/MPS/XPU .
Prompt Style: ExtractionPromptStyle#
ExtractionPromptStyle (in docling/datamodel/extraction_options.py) is a two-value enum:
NUEXTRACT— uses Qwen's chat template withqwen-vl-utilsvision processing and appliestorch.compile()at model initGRANITE_VISION— uses a standard HuggingFace chat format with an explicit system prompt that instructs the model to return valid JSON
The style must match the chosen model; mixing them (e.g., GRANITE_VISION_4_1_TRANSFORMERS + NUEXTRACT) will produce incorrect output.
ExtractionFormatOption and the Required backend Field#
ExtractionFormatOption wraps a pipeline_cls + pipeline_options pair. It inherits from BaseFormatOption, which declares backend: Type[AbstractDocumentBackend] as a required field with no default.
Common Pydantic validation error: Omitting backend when constructing ExtractionFormatOption raises:
pydantic_core._pydantic_core.ValidationError: 1 validation error for ExtractionFormatOption
backend
Field required [type=missing, ...]
The default helper _get_default_extraction_option() handles this automatically (PDF → PyPdfiumDocumentBackend, IMAGE → ImageDocumentBackend). When building a custom ExtractionFormatOption, always supply backend explicitly:
from docling.document_extractor import DocumentExtractor, ExtractionFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import VlmExtractionPipelineOptions
from docling.datamodel.vlm_model_specs import GRANITE_VISION_4_1_TRANSFORMERS
from docling.datamodel.extraction_options import ExtractionPromptStyle
from docling.pipeline.extraction_vlm_pipeline import ExtractionVlmPipeline
from docling.backend.pypdfium2_backend import PyPdfiumDocumentBackend
extractor = DocumentExtractor(
extraction_format_options={
InputFormat.PDF: ExtractionFormatOption(
pipeline_cls=ExtractionVlmPipeline,
pipeline_options=VlmExtractionPipelineOptions(
vlm_options=GRANITE_VISION_4_1_TRANSFORMERS,
extraction_prompt_style=ExtractionPromptStyle.GRANITE_VISION,
),
backend=PyPdfiumDocumentBackend, # required — no default
)
}
)
Template Serialization#
The pipeline's _serialize_template() converts the template argument passed to extract() into a JSON string for the VLM prompt. Four input forms are accepted:
| Input type | Serialization |
|---|---|
str | Used verbatim |
dict | json.dumps(template, indent=2) |
BaseModel instance | model.model_dump_json(indent=2) |
BaseModel class | Factory instance built from Field(examples=...) via polyfactory |
When passing a Pydantic class, populate Field(examples=[...]) on your fields so the generated schema hint is meaningful to the VLM.
Key Source Files#
| File | Purpose |
|---|---|
docling/document_extractor.py | DocumentExtractor, ExtractionFormatOption |
docling/datamodel/pipeline_options.py | VlmExtractionPipelineOptions |
docling/datamodel/vlm_model_specs.py | NU_EXTRACT_2B_TRANSFORMERS, GRANITE_VISION_4_1_TRANSFORMERS |
docling/datamodel/extraction_options.py | ExtractionPromptStyle enum |
docling/pipeline/extraction_vlm_pipeline.py | ExtractionVlmPipeline, _serialize_template() |
docling/datamodel/base_models.py | BaseFormatOption (defines required backend field) |
docs/examples/extraction.ipynb | End-to-end usage notebook |