,

Docling and Multimodal Document Understanding on watsonx (IBM Gen AI Series, Part 18)

How IBM Docling and the Granite vision models turn PDFs, scans, and DOCX files into clean structured chunks for RAG on watsonx, and where a vision model is worth the cost.

IBM Gen AI Series · Part 18 of 24
Key takeaways: Docling is IBM’s open-source converter that turns a PDF, DOCX, or scanned image into one structured object you can chunk for RAG without losing tables, headings, or reading order. Granite-Docling-258M does that job as a 258M-parameter model small enough to run on a CPU. Reach for a larger vision model like Granite Vision 3.2 2B only when you need answers about a page, not just its structure. The expensive part of any ingestion pipeline is OCR on scanned documents, so size for that first.

Most RAG pipelines quietly throw away half of every document. A PDF goes in, a text extractor strips it to a wall of characters, and the table that held the actual answer becomes a run-on line with no rows, no columns, and no idea which number belonged to which quarter. The model then hallucinates a value because you handed it mush. Fix the ingestion step and a surprising number of retrieval bugs disappear. On watsonx, the tool that fixes it is Docling, and this part is about using it well.

Who this is for: You have followed this series through RAG on watsonx.data with Milvus (Part 9) and can build an index. You are comfortable running Python and calling a foundation model. You do not need any prior knowledge of document parsing, OCR, or vision models. Everything below defines its terms on first use.

What Docling actually does

Docling is an open-source toolkit, MIT licensed, that reads a document and produces a single structured representation of it. It parses PDF, DOCX, PPTX, XLSX, HTML, EPUB, images such as PNG and TIFF, and even audio formats, then normalizes all of them into one Python object called a DoclingDocument. That object is a Pydantic data type, which just means a typed, validated structure, and it holds the text, the tables as real rows and columns, the pictures, the document hierarchy of headings and sections, and the location of each element on the page.

Two specialized models do the heavy lifting inside it. Layout analysis, deciding what is a heading versus a paragraph versus a table, runs on a model trained on DocLayNet, IBM’s document layout dataset. Table structure recognition, working out the grid of a table even when the borders are invisible, runs on TableFormer. In December 2025 IBM added a faster layout model called Heron that speeds up PDF parsing without dropping accuracy. You do not call these models directly. You call Docling and it orchestrates them.

The output of a DoclingDocument exports to Markdown, JSON, HTML, or a format called DocTags. Markdown is what most people grab first because it looks clean. That is also the mistake, and it is worth its own section.

DocTags and why Markdown loses information

DocTags is a markup format from IBM Research that describes every element on a page, a chart, a table, a form field, a code block, an equation, a footnote, a caption, together with how they relate to each other and where they sit in the layout. Think of it as a structural transcript of the page rather than a flattened copy of the words. Markdown, by contrast, throws away the coordinates and most of the relationships. A merged table cell becomes ambiguous. A figure caption floats free of its figure. For a human reader that is fine. For a retrieval system that needs to answer which region had the highest churn, it is a slow leak of exactly the context that made the answer findable.

My take

Export to DocTags or JSON when the target is a RAG index, and keep Markdown only for a human preview. I have watched teams debug a retrieval problem for a week when the fix was that their chunker had been fed flattened Markdown and could no longer tell one table row from the next. Chunk on the structure, not on the prose.

How a page becomes a DoclingDocument

The pipeline branches on one early decision: is this document born digital, meaning the text is already embedded and selectable, or is it a scan, meaning the page is really an image of text. Born-digital files skip optical character recognition entirely and parse fast. Scans have to go through OCR, which reads pixels back into characters, and that step is where almost all of your processing time goes. Everything after the branch is shared: layout analysis, table recognition, then assembly into the DoclingDocument, then export.

flowchart LR
  A[PDF or DOCX] --> B{Born digital?}
  B -->|Yes| D[Layout DocLayNet]
  B -->|No| C[OCR pass]
  C --> D
  D --> E[Tables TableFormer]
  E --> F[Assemble DoclingDocument]
  F --> G[Export MD JSON DocTags]
  G --> H[Chunk to watsonx.data Milvus]
Figure 1. The Docling pipeline. Born-digital files skip the OCR pass, which is the slow branch. DocLayNet is the layout model, TableFormer reconstructs tables, and the assembled DoclingDocument feeds your vector index from Part 9.

Granite-Docling versus the bigger vision models

There are two distinct jobs here and the industry keeps confusing them. The first is conversion: turn a page into faithful structure. The second is understanding: answer a question about what the page means. Docling with its default models handles conversion. IBM also ships Granite-Docling-258M, a vision-language model, meaning it reads image and text together, that does end-to-end conversion in a single 258M-parameter model under an Apache 2.0 license. At that size it runs on a CPU or a small GPU, and IBM reports its accuracy rivals systems several times larger. It added experimental support for Arabic, Chinese, and Japanese, with a roadmap toward larger variants around 900M parameters.

When the task shifts to understanding, you want a bigger vision model. Granite Vision 3.2 2B was IBM’s first official Granite vision-language model, built specifically for document understanding, and on the standard enterprise benchmarks DocVQA, ChartQA, AI2D, and OCRBench it matches models roughly five times its size such as Llama 3.2 11B and Pixtral 12B. IBM trained it by running Docling over 85 million PDFs and generating 26 million synthetic question-answer pairs, so the toolkit and the model are two ends of the same effort. Granite 4.0 3B Vision, released in 2026, goes further on structured extraction, chart, table, and semantic key-value pair pulling, and ships as a LoRA adapter on top of Granite 4.0 Micro so one deployment serves both text-only and multimodal traffic.

Parameters versus document-benchmark parity
Billions of parameters. The three Granite models on the left match the two on the right on document tasks.
0369120.26241112GraniteDoclingVision3.2 2B4.0 3BVisionLlama 3.211BPixtral12B
Figure 2. Red bars are IBM models, pink bars are the larger open models they match on DocVQA, ChartQA, AI2D, and OCRBench. Smaller here is cheaper to run, not weaker on the task.

Which extractor for which document?

ModelSizeBest atRuns whereWhen not
Docling defaultDocLayNet + TableFormerFast conversion of born-digital filesLocal, CPUHeavy handwriting or noisy scans
Granite-Docling-258M258MEnd-to-end structure to DocTags, equations, codeLocal CPU or small GPUYou need answers, not structure
Granite Vision 3.2 2B2BVisual Q&A over charts and infographicswatsonx.ai hostedPlain conversion (overkill and slower)
Granite 4.0 3B Vision3.5B + 0.5B LoRAChart, table, and key-value extractionHugging Face; watsonx hostingSimple digital PDFs with clean tables

Read that table as a ladder. Start at the top. Move down only when the row above cannot do the job. Most enterprise corpora are 80 percent born-digital PDFs where the default Docling path is enough, and paying for a 2B or 4B vision model on every page is money set on fire. Save the vision models for the pages that actually need reading: a scanned form, a dense chart, a photographed receipt.

Converting a real PDF and keeping its tables

Here is the smallest useful Docling program. It converts a file, exports both a structural DocTags view and a human Markdown view, and pulls each table out as a dataframe so you can validate the grid before it ever reaches your index. Install with pip install docling.

from docling.document_converter import DocumentConverter

converter = DocumentConverter()
result = converter.convert('quarterly-report.pdf')
doc = result.document

# Structure for the index, prose for humans
doctags = doc.export_to_doctags()
markdown = doc.export_to_markdown()

print('tables found:', len(doc.tables))
for i, t in enumerate(doc.tables):
    df = t.export_to_dataframe()
    print('table', i, 'shape', df.shape)

Expected output on a clean four-table report:

tables found: 4
table 0 shape (12, 5)
table 1 shape (8, 3)
table 2 shape (20, 6)
table 3 shape (5, 4)

Gotcha

If that same script prints tables found: 0 on a document you know has tables, the file is almost certainly a scan and no OCR engine is active. Docling ships with OCR backends such as EasyOCR, Tesseract, and RapidOCR, but you have to enable OCR in the pipeline options for image-only PDFs. A born-digital file needs no OCR and runs far faster, so check the document type before you blame the code.

Chunking on structure, not character counts

Getting a clean DoclingDocument is half the win. The other half is how you cut it into chunks for the vector index, because a chunk is the smallest thing your retriever can return, and a bad cut destroys good structure just as thoroughly as a bad parse did. The naive approach splits on a fixed character count, say every 1,000 characters, which happily slices a table in two or severs a heading from the paragraph it introduces. You end up retrieving half a table and the model fills in the rest from imagination.

Docling ships chunkers that respect the structure it worked so hard to recover. The HierarchicalChunker walks the document tree and keeps each element, a table, a section, a list, intact as its own chunk, carrying the heading path along as metadata so a retrieved row still knows which section and which document it came from. The HybridChunker layers a tokenizer on top of that: it keeps the structural boundaries but also merges tiny neighbouring chunks and splits any element that overflows your embedding model’s token window, so nothing silently gets truncated at index time. For most watsonx.data indexes the HybridChunker tuned to your embedding model’s context length is the right default, and it is a two-line change from the naive splitter.

The payoff shows up at query time in a way that is easy to measure. Keep the heading path and page provenance on every chunk and your retrieval can filter by section before it ever scores similarity, which cuts false hits on documents with repetitive boilerplate such as contracts or compliance filings. It also means a citation back to the user can name the page and section, not just paste a paragraph, and that traceability is exactly what the evaluation harness from Part 17 needs to score groundedness honestly. Chunk carelessly and even a perfect parse degrades into the same soup you started with.

Sizing an ingestion pipeline

The single number that decides your compute bill is the share of scanned documents, because OCR is the slow path. IBM reports Docling running up to roughly 30 times faster on born-digital parsing than traditional OCR-based methods. Treat that as a ratio, not a promise, and the sizing falls out cleanly. Suppose a corpus of 50,000 documents at an average of 12 pages each, and 30 percent of them are scans.

SegmentDocumentsPagesRelative cost per pageTime units
Born-digital35,000420,0001420,000
Scanned + OCR15,000180,000305,400,000
Total50,000600,000mixed5,820,000

Worked example

The scanned 30 percent of documents consume 5,400,000 of 5,820,000 time units, about 93 percent of the whole job, while producing under a third of the pages. The lesson: benchmark your OCR throughput on real scans, provision GPUs for that branch, and let the born-digital majority ride on cheap CPU workers. If you can push even a slice of the scans through a cleaner source, the bill drops far more than any model swap would give you.

Where the compute time goes
Relative time units per segment, from the table above.
01.5M3.0M4.5M420k born-digital5.4M scanned + OCR
Figure 3. The scanned minority dominates the wall clock. Size the OCR branch first and the rest of the pipeline is cheap.

Where Docling stops and a vision model starts

Docling gives you faithful structure. It does not reason about content. If the question is what does this contract clause mean or which line in this chart is trending down, structure alone will not answer it, and that is the handoff point to a vision model like Granite Vision 3.2 2B on watsonx.ai. A practical split works well: run Docling on the whole corpus to produce clean chunks, index them as you did in Part 9, and route only the pages your retrieval flags as image-heavy or chart-heavy to the vision model at query time. You pay the vision premium on a fraction of pages instead of all of them. This is the same instinct behind Amazon Bedrock Data Automation on the AWS side, and comparing the two managed approaches is worth an afternoon if you run both clouds.

One governance note before the next part. Everything Docling extracts becomes training-adjacent data the moment it lands in an index, so the provenance fields in a DoclingDocument, which page and which coordinates a chunk came from, are not a nicety. They are your audit trail. The next part, on watsonx.governance, is where those trails get formalized into risk records and factsheets, and clean provenance from ingestion is what makes that step painless instead of a reconstruction project. Granite models were themselves partly trained on Docling-processed corpora, and IBM has said DocTags terms are being folded into the Granite tokenizer, so the format you export today is the format the models increasingly expect. For the model lineage behind all this, see Part 3 on the Granite family.

Docling for structure, a vision model only for the hard pages

If you build one thing from this part, make it a Docling front-end on your ingestion, exporting DocTags or JSON rather than Markdown, feeding the same watsonx.data index you already run. That single change recovers the tables and reading order most pipelines lose, and it costs almost nothing on born-digital files. Add a vision model only where a page genuinely needs reading, and size your hardware around the scanned minority because that is where the time and money actually go. Convert everything, understand selectively.

Next, take a document you already tried to index and run the small script above on it. Count the tables it recovers that your old extractor flattened. That number is your case for switching.

IBM Gen AI Series · Part 18 of 24
« Previous: Part 17  |  Guide  |  Next: Part 19 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading