Run this model inference on single tenant GPU with unmatched speed and reliability at scale.
Get help setting up a custom Dedicated Endpoints.
Talk with our engineer to get a quote for reserved GPU instances with discounts.
README
License: apache-2.0Getting started
The easiest way to use this model is through the 🐥Docling library. It will automatically download this model and convert documents to various formats for you.
Install the latest version of docling through pip, then use the following CLI command:
sh
# Convert to HTML and Markdown:docling --to html --to md --pipeline vlm --vlm-model granite_docling "https://arxiv.org/pdf/2501.17887" # accepts files, urls or directories# Convert to HTML including layout visualization:docling --to html_split_page --show-layout --pipeline vlm --vlm-model granite_docling "https://arxiv.org/pdf/2501.17887"
python
from docling.datamodel import vlm_model_specsfrom docling.datamodel.base_models import InputFormatfrom docling.datamodel.pipeline_options import (VlmPipelineOptions,)from docling.document_converter import DocumentConverter, PdfFormatOptionfrom docling.pipeline.vlm_pipeline import VlmPipelinesource = "https://arxiv.org/pdf/2501.17887"###### USING SIMPLE DEFAULT VALUES# - GraniteDocling model# - Using the transformers frameworkconverter = DocumentConverter(format_options={InputFormat.PDF: PdfFormatOption(pipeline_cls=VlmPipeline,),})doc = converter.convert(source=source).documentprint(doc.export_to_markdown())###### USING MACOS MPS ACCELERATOR# For more options see the compare_vlm_models.py example.pipeline_options = VlmPipelineOptions(vlm_options=vlm_model_specs.GRANITEDOCLING_MLX,)converter = DocumentConverter(format_options={InputFormat.PDF: PdfFormatOption(pipeline_cls=VlmPipeline,pipeline_options=pipeline_options,),})doc = converter.convert(source=source).documentprint(doc.export_to_markdown())
Alternatively, you can use bare transformers, vllm, onnx or mlx-vlm to perform inference, and docling-core APIs to convert results to variety of output formats (md, html, etc.):
python
# Prerequisites:# pip install torch# pip install docling_core# pip install transformersimport torchfrom docling_core.types.doc import DoclingDocumentfrom docling_core.types.doc.document import DocTagsDocumentfrom transformers import AutoProcessor, AutoModelForVision2Seqfrom transformers.image_utils import load_imagefrom pathlib import PathDEVICE = "cuda" if torch.cuda.is_available() else "cpu"# Load imagesimage = load_image("https://huggingface.co/ibm-granite/granite-docling-258M/resolve/main/assets/new_arxiv.png")# Initialize processor and modelprocessor = AutoProcessor.from_pretrained("ibm-granite/granite-docling-258M")model = AutoModelForVision2Seq.from_pretrained("ibm-granite/granite-docling-258M",torch_dtype=torch.bfloat16,_attn_implementation="flash_attention_2" if DEVICE == "cuda" else "sdpa",).to(DEVICE)# Create input messagesmessages = [{"role": "user","content": [{"type": "image"},{"type": "text", "text": "Convert this page to docling."}]},]# Prepare inputsprompt = processor.apply_chat_template(messages, add_generation_prompt=True)inputs = processor(text=prompt, images=[image], return_tensors="pt")inputs = inputs.to(DEVICE)# Generate outputsgenerated_ids = model.generate(**inputs, max_new_tokens=8192)prompt_length = inputs.input_ids.shape[1]trimmed_generated_ids = generated_ids[:, prompt_length:]doctags = processor.batch_decode(trimmed_generated_ids,skip_special_tokens=False,)[0].lstrip()print(f"DocTags: \n{doctags}\n")# Populate documentdoctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])# create a docling documentdoc = DoclingDocument.load_from_doctags(doctags_doc, document_name="Document")print(f"Markdown:\n{doc.export_to_markdown()}\n")## export as any format.# Path("out/").mkdir(parents=True, exist_ok=True)# HTML:# output_path_html = Path("out/") / "example.html"# doc.save_as_html(output_path_html)# Markdown:# output_path_md = Path("out/") / "example.md"# doc.save_as_markdown(output_path_md)
python
# Prerequisites:# pip install vllm# pip install docling_core# place page images you want to convert into "img/" dirimport timeimport osfrom vllm import LLM, SamplingParamsfrom transformers import AutoProcessorfrom PIL import Imagefrom docling_core.types.doc import DoclingDocumentfrom docling_core.types.doc.document import DocTagsDocumentfrom pathlib import Path# ConfigurationMODEL_PATH = "ibm-granite/granite-docling-258M"IMAGE_DIR = "img/" # Place your page images hereOUTPUT_DIR = "out/"PROMPT_TEXT = "Convert this page to docling."messages = [{"role": "user","content": [{"type": "image"},{"type": "text", "text": PROMPT_TEXT},],},]# Ensure output directory existsos.makedirs(OUTPUT_DIR, exist_ok=True)# Initialize LLMllm = LLM(model=MODEL_PATH, revision="untied", limit_mm_per_prompt={"image": 1})processor = AutoProcessor.from_pretrained(MODEL_PATH)sampling_params = SamplingParams(temperature=0.0,max_tokens=8192,skip_special_tokens=False,)# Load and prepare all images and prompts up frontbatched_inputs = []image_names = []for img_file in sorted(os.listdir(IMAGE_DIR)):if img_file.lower().endswith((".png", ".jpg", ".jpeg")):img_path = os.path.join(IMAGE_DIR, img_file)with Image.open(img_path) as im:image = im.convert("RGB")prompt = processor.apply_chat_template(messages, add_generation_prompt=True)batched_inputs.append({"prompt": prompt, "multi_modal_data": {"image": image}})image_names.append(os.path.splitext(img_file)[0])# Run batch inferencestart_time = time.time()outputs = llm.generate(batched_inputs, sampling_params=sampling_params)# Postprocess all resultsfor img_fn, output, input_data in zip(image_names, outputs, batched_inputs):doctags = output.outputs[0].textoutput_path_dt = Path(OUTPUT_DIR) / f"{img_fn}.dt"output_path_md = Path(OUTPUT_DIR) / f"{img_fn}.md"with open(output_path_dt, "w", encoding="utf-8") as f:f.write(doctags)# Convert to DoclingDocument and save markdowndoctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [input_data["multi_modal_data"]["image"]])doc = DoclingDocument.load_from_doctags(doctags_doc, document_name="Document")doc.save_as_markdown(output_path_md)print(f"Total time: {time.time() - start_time:.2f} sec")
💻 Local inference on Apple Silicon with MLX: see here
ℹ️ If you see trouble running granite-docling with the codes above, check the troubleshooting section at the bottom ⬇️.
Intended Use
Granite-Docling is designed to complement the Docling library, not replace it. It integrates as a component within larger Docling library, consolidating the functions of multiple single-purpose models into a single, compact VLM. However, Granite-Docling is not intended for general image understanding. For tasks focused solely on image-text input, we recommend using Granite Vision models, which are purpose-built and optimized for image-text processing.
Evaluations
A comprehensive discussion of evaluation methods and findings has already been presented in our previous publication [citation]. As this model is an update, we refer readers to that work for additional details. The evaluation can be performed using the docling-eval framework for the document related tasks, and lmms-eval for MMStar and OCRBench.
💻 Local inference on Apple Silicon with MLX: see here
Supported Instructions
Model Architecture:
The architecture of granite-docling-258m consists of the following components:
(1) Vision encoder: siglip2-base-patch16-512.
(2) Vision-language connector: pixel shuffle projector (as in idefics3)
(3) Large language model: Granite 165M.
We built upon Idefics3 to train our model. We incorporated DocTags into our LLM’s supervised fine-tuning (SFT) data to help the model become familiar with the format, enabling faster convergence and mitigating issues previously observed with SmolDocling. The model was trained using the nanoVLM framework, which provides a lightweight and efficient training setup for vision-language models
Training Data: Our training corpus consists of two principal sources: (1) publicly available datasets and (2) internally constructed synthetic datasets designed to elicit specific document understanding capabilities.
In particular, we incorporate:
- SynthCodeNet — a large-scale collection of synthetically rendered code snippets spanning over 50 programming languages
- SynthFormulaNet — a dataset of synthetic mathematical expressions paired with ground-truth LaTeX representations
- SynthChartNet — synthetic chart images annotated with structured table outputs
- DoclingMatix — a curated corpus of real-world document pages sampled from diverse domains
Infrastructure: We train granite-docling-258m using IBM's super computing cluster, Blue Vela, which is outfitted with NVIDIA H100 GPUs. This cluster provides a scalable and efficient infrastructure for training our models over thousands of GPUs.
Responsible Use and Limitations Some use cases for Vision Language Models can trigger certain risks and ethical considerations, including but not limited to: bias and fairness, misinformation, and autonomous decision-making. Although our alignment processes include safety considerations, the model may in some cases produce inaccurate, biased, offensive or unwanted responses to user prompts. Additionally, whether smaller models may exhibit increased susceptibility to hallucination in generation scenarios due to their reduced sizes, which could limit their ability to generate coherent and contextually accurate responses, remains uncertain. This aspect is currently an active area of research, and we anticipate more rigorous exploration, comprehension, and mitigations in this domain. We urge the community to use granite-docling-258m in a responsible way and avoid any malicious utilization. We recommend using this model only as part of the Docling library. More general vision tasks may pose higher inherent risks of triggering unwanted output. To enhance safety, we recommend using granite-docling-258m alongside Granite Guardian. Granite Guardian is a fine-tuned instruct model designed to detect and flag risks in prompts and responses across key dimensions outlined in the IBM AI Risk Atlas. Its training, which includes both human-annotated and synthetic data informed by internal red-teaming, enables it to outperform similar open-source models on standard benchmarks, providing an additional layer of safety.
Resources
- ⭐️ Learn about the latest updates with Docling: https://docling-project.github.io/docling/#features
- 🚀 Get started with Docling concepts, integrations and tutorials: https://docling-project.github.io/docling/getting_started/
- 💡 Learn about the latest Granite learning resources: https://ibm.biz/granite-learning-resources
- 🖥️ Learn more about how to use Granite-Docling, explore the Docling library, and see what’s coming next for Docling in the release blog: https://ibm.com/new/announcements/granite-docling-end-to-end-document-conversion
Troubleshooting
Running with VLLM
-
You receive
AttributeError: 'LlamaModel' object has no attribute 'wte'when launching the model through VLLM.With current versions of VLLM (including 0.10.2), support for tied weights as used in granite-docling is limited and breaks. We provide a version with untied weights on the
untiedbranch of this model repo. To use the untied version, please pass therevisionargument to VLLM:sh
# Serve the model through VLLM$> vllm serve ibm-granite/granite-docling-258M --revision untiedpython
# If using the VLLM python SDK:from vllm import LLM...llm = LLM(model=MODEL_PATH, revision="untied", limit_mm_per_prompt={"image": 1}) -
The model outputs only exclamation marks (i.e. "!!!!!!!!!!!!!!!").
This is seen on older NVIDIA GPUs, such as the T4 GPU available in Google Colab, because it lacks support for
bfloat16format. You can work around it by setting thedtypetofloat32.sh
# Serve the model through VLLM$> vllm serve ibm-granite/granite-docling-258M --revision untied --dtype float32python
# If using the VLLM python SDK:from vllm import LLM...llm = LLM(model=MODEL_PATH, revision="untied", limit_mm_per_prompt={"image": 1}, dtype="float32")
Model provider
rahulrgadgimata
Model tree
Base
this model
Modalities
Input
Text, Image
Output
Text
Pricing
Dedicated Endpoints
View detailsSupported Functionality
Model APIs
Dedicated Endpoints
Container
More information