VLM Picture Description#
Docling's picture description feature uses Vision Language Models (VLMs) to generate natural-language captions for PictureItem elements extracted during document conversion. Descriptions are stored in PictureItem.meta.description as a DescriptionMetaField. It is activated by setting do_picture_description=True on PdfPipelineOptions.
The implementation is split across three layers:
PictureDescriptionBaseModel— shared enrichment loop, area-threshold gating, classification filtering, and output writing- Options classes in
pipeline_options.py— backend-specific configuration - Model specs / presets in
stage_model_specs.py— named, pre-wired model+engine combinations
Built-in Presets#
The recommended entry point is PictureDescriptionVlmEngineOptions.from_preset(preset_id). Four presets are registered out of the box:
| Preset ID | Model | HuggingFace repo | Size |
|---|---|---|---|
smolvlm | SmolVLM-256M-Instruct | HuggingFaceTB/SmolVLM-256M-Instruct | 256M |
granite_vision | Granite-Vision-3.3-2B | ibm-granite/granite-vision-3.3-2b | 2B |
pixtral | Pixtral-12B | mistral-community/pixtral-12b | 12B |
qwen | Qwen2.5-VL-3B-Instruct | Qwen/Qwen2.5-VL-3B-Instruct | 3B |
All four default to AUTO_INLINE engine type and a picture_area_threshold of 0.05 . VLM models are not included in the default docling-tools models download set and must be explicitly downloaded .
You can also define and register a custom preset via PictureDescriptionVlmEngineOptions.register_preset(StageModelPreset(...)) .
Backend / Engine Support#
All presets go through the unified VLM inference engine layer. The backend is selected via engine_options on from_preset():
| Backend | Class | Notes |
|---|---|---|
AUTO_INLINE | AutoInlineVlmEngineOptions | Default; selects MLX on Apple Silicon, Transformers otherwise |
TRANSFORMERS | TransformersVlmEngineOptions | HuggingFace; supports CUDA, CPU, XPU (not MPS) |
MLX | MlxVlmEngineOptions | Apple Silicon only; requires MLX export declared in model spec |
VLLM | VllmVlmEngineOptions | High-throughput serving; selectable via prefer_vllm=True |
API* | ApiVlmEngineOptions | OpenAI-compatible endpoint (also Ollama, LM Studio variants) |
AUTO_INLINE on Apple Silicon with MLX: SmolVLM uses moot20/SmolVLM-256M-Instruct-MLX; Pixtral uses mlx-community/pixtral-12b-bf16; Qwen uses mlx-community/Qwen2.5-VL-3B-Instruct-bf16 . Granite Vision 3.3-2B does not have an MLX export and falls back to CPU Transformers on Apple Silicon .
The API backend requires enable_remote_services=True and an OpenAI-compatible chat/completions endpoint .
Output Quality Configuration#
Generation parameters (VlmModelSpec)#
VlmModelSpec — embedded inside every preset — controls generation directly :
| Field | Default | Effect |
|---|---|---|
prompt | preset-specific | Text prompt sent to the model |
max_new_tokens | 4096 | Maximum tokens generated per image |
temperature | 0.0 | Sampling temperature (0 = greedy) |
stop_strings | [] | Early-stop triggers |
extra_generation_config | {} | Pass-through to the engine |
Override these at from_preset() time by mutating the returned object or by passing overrides as keyword args:
opts = PictureDescriptionVlmEngineOptions.from_preset(
"smolvlm",
prompt="Describe this chart for a blind reader.",
)
opts.model_spec.max_new_tokens = 512
opts.model_spec.temperature = 0.3
Known issue (fixed in ≥ 2.105.0 + PRs #3279 / #3322): In earlier releases
generation_configonPictureDescriptionVlmEngineOptionswas defined but silently ignored, causingmax_new_tokensto be hardcoded to 200 and temperature to be fixed at a default value. These PRs forwardmax_new_tokens,temperature, andextra_generation_configfromVlmModelSpecinto the engine'sVlmEngineInputvia a newget_runtime_input_extra_config()method .
Image resolution#
scale on the preset (default 2.0) multiplies base image resolution before the VLM sees it . Higher values increase detail but use more memory and time. picture_area_threshold (default 0.05) skips pictures whose bounding box is less than 5% of the page area .
Legacy option:
PictureDescriptionVlmOptions(deprecated) uses a plaingeneration_configdict defaulting to{"max_new_tokens": 200, "do_sample": False}. PreferPictureDescriptionVlmEngineOptionsfor new code.
Classification-Based Filtering#
Before making any VLM call, PictureDescriptionBaseModel checks three filter fields inherited by all options classes from PictureDescriptionBaseOptions:
| Field | Default | Purpose |
|---|---|---|
classification_allow | None | Only describe pictures in this label list |
classification_deny | None | Skip pictures in this label list |
classification_min_confidence | 0.0 | Minimum confidence score to count a prediction |
The filter is implemented in _passes_classification() and called after the area check but before image rendering . Requires do_picture_classification=True on pipeline options to populate PictureItem.meta.classification; if classification hasn't run, pictures pass when allow=None and are blocked when an allow-list is set .
Available labels come from PictureClassificationLabel in docling-core (25 labels covering charts, photographs, barcodes, engineering drawings, etc.).
Example — describe only charts with ≥ 70% confidence:
from docling.datamodel.pipeline_options import PdfPipelineOptions, PictureDescriptionVlmEngineOptions
from docling_core.types.doc import PictureClassificationLabel
opts = PdfPipelineOptions(
do_picture_classification=True,
do_picture_description=True,
picture_description_options=PictureDescriptionVlmEngineOptions.from_preset(
"smolvlm",
classification_allow=[
PictureClassificationLabel.BAR_CHART,
PictureClassificationLabel.LINE_CHART,
],
classification_min_confidence=0.7,
),
)
Key Source Files#
| File | Role |
|---|---|
pipeline_options.py | PictureDescriptionBaseOptions, PictureDescriptionVlmEngineOptions, PictureDescriptionApiOptions |
picture_description_base_model.py | Shared enrichment loop, area + classification gating |
stage_model_specs.py | Built-in presets (smolvlm, granite_vision, pixtral, qwen), VlmModelSpec, StageModelPreset |
docling/models/inference_engines/vlm/ | Backend implementations (Transformers, MLX, vLLM, API) |
docling_core/.../labels.py | PictureClassificationLabel enum |