DEV Community

Alain Airom
Alain Airom

Posted on

Docling's new “SmolDocling-256M” Rocks

First impression of testing “SmolDocling-256M-preview” available on Hugging Face.

Image description

Introduction

SmolDocling (the latest from the Docling family) is a multimodal Image-Text-to-Text model designed for efficient document conversion. It retains Docling’s most popular features while ensuring full compatibility with Docling through seamless support for DoclingDocuments.

🚀 Features:

🏷️ DocTags for Efficient Tokenization — Introduces DocTags an efficient and minimal representation for documents that is fully compatible with DoclingDocuments.
🔍 OCR (Optical Character Recognition) — Extracts text accurately from images.
📐 Layout and Localization — Preserves document structure and document element bounding boxes.
💻 Code Recognition — Detects and formats code blocks including identation.
🔢 Formula Recognition — Identifies and processes mathematical expressions.
📊 Chart Recognition — Extracts and interprets chart data.
📑 Table Recognition — Supports column and row headers for structured table extraction.
🖼️ Figure Classification — Differentiates figures and graphical elements.
📝 Caption Correspondence — Links captions to relevant images and figures.
📜 List Grouping — Organizes and structures list elements correctly.
📄 Full-Page Conversion — Processes entire pages for comprehensive document conversion including all page elements (code, equations, tables, charts etc.)
🔲 OCR with Bounding Boxes — OCR regions using a bounding box.
📂 General Document Processing — Trained for both scientific and non-scientific documents.
🔄 Seamless Docling Integration — Import into Docling and export in multiple formats.
💨 Fast inference using VLLM — Avg of 0.35 secs per page on A100 GPU.

🚧 Coming soon!

📊 Better chart recognition 🛠️
📚 One shot multi-page inference ⏱️
🧪 Chemical Recognition
📙 Datasets

First hands-on experience with “Single page image inference using Transformer”

Testing the first code sample provided on the Hugging Face site on my Intel/CPU MacOS the thing went smoothly.

# Prerequisites:
# pip install torch
# pip install docling_core
# pip install transformers

import torch
from docling_core.types.doc import DoclingDocument
from docling_core.types.doc.document import DocTagsDocument
from transformers import AutoProcessor, AutoModelForVision2Seq
from transformers.image_utils import load_image

DEVICE = "cuda" if torch.cuda.is_available() else "cpu"

# Load images
#image = load_image("https://upload.wikimedia.org/wikipedia/commons/7/76/GazettedeFrance.jpg")
image = load_image("./image/GazettedeFrance.jpg")

# Initialize processor and model
processor = AutoProcessor.from_pretrained("ds4sd/SmolDocling-256M-preview")
model = AutoModelForVision2Seq.from_pretrained(
    "ds4sd/SmolDocling-256M-preview",
    torch_dtype=torch.bfloat16,
    _attn_implementation="flash_attention_2" if DEVICE == "cuda" else "eager",
).to(DEVICE)

# Create input messages
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image"},
            {"type": "text", "text": "Convert this page to docling."}
        ]
    },
]

# Prepare inputs
prompt = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(text=prompt, images=[image], return_tensors="pt")
inputs = inputs.to(DEVICE)

# Generate outputs
generated_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()

# Populate document
doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
print(doctags)
# create a docling document
doc = DoclingDocument(name="Document")
doc.load_from_doctags(doctags_doc)

# export as any format
# HTML
# doc.save_as_html(output_file)
# MD
print(doc.export_to_markdown())
Enter fullscreen mode Exit fullscreen mode

I did three things beforehand.

python3.12 -m venv smoldocling_env
source smoldocling_env/bin/activate
Enter fullscreen mode Exit fullscreen mode
  • Regarding my laptop configuration, I did the follwoing to be able to run the code sample.
pip install --upgrade pip
pip install torch
pip install docling_core
pip install transformers

pip uninstall numpy
pip install "numpy<2.0"
Enter fullscreen mode Exit fullscreen mode

Hereafter the application’s output!

processor_config.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 68.0/68.0 [00:00<00:00, 84.7kB/s]
chat_template.json: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 430/430 [00:00<00:00, 2.17MB/s]
preprocessor_config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████| 486/486 [00:00<00:00, 2.84MB/s]
tokenizer_config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 27.4k/27.4k [00:00<00:00, 51.4MB/s]
vocab.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 801k/801k [00:00<00:00, 3.44MB/s]
merges.txt: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 466k/466k [00:00<00:00, 2.96MB/s]
tokenizer.json: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 3.55M/3.55M [00:00<00:00, 6.47MB/s]
added_tokens.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 3.67k/3.67k [00:00<00:00, 22.6MB/s]
special_tokens_map.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████| 1.07k/1.07k [00:00<00:00, 6.52MB/s]
config.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 3.79k/3.79k [00:00<00:00, 29.0MB/s]
model.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 513M/513M [00:51<00:00, 9.94MB/s]
generation_config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 141/141 [00:00<00:00, 865kB/s]
Truncation was not explicitly activated but `max_length` is provided a specific value, please use `truncation=True` to explicitly truncate examples to max length. Defaulting to 'longest_first' truncation strategy. If you encode pairs of sequences (GLUE-style) with the tokenizer you can select this strategy more precisely by providing a specific strategy to `truncation`.
<doctag><picture><loc_19><loc_3><loc_491><loc_65><logo></picture>
<section_header_level_1><loc_49><loc_67><loc_453><loc_109>GAZETTE DE FRANCE, Du Mardi 26 Decembre 1786.</section_header_level_1>
<picture><loc_10><loc_121><loc_492><loc_138><logo></picture>
<text><loc_10><loc_144><loc_231><loc_155>De Pitefourg, le 17 Novembre 1786.</text>
<text><loc_10><loc_158><loc_231><loc_215>LA navigation eft interrompue par les glaces; pluieurs Baimtens chargés de fuif & de marchandifes des manufactures An- glofies, fe trouvent pris dans la Newa dont la navigation n'a ete ouverte cette année que pendant 187 jours.</text>
<text><loc_10><loc_215><loc_210><loc_225>D'Upfal, le 20 Novembre 1786.</text>
<text><loc_10><loc_225><loc_231><loc_251>LE ROI & le Prince Royal continuent a fejourner dans cette ville, & a fréquenter les Cours académiques.</text>
<text><loc_10><loc_251><loc_231><loc_297>Hier, il y eut Cour chez le Roi; a cette occasion, le Baron de Juel, Envoyé extraoirinaire de Danemarche, remit à Sa Majelle I'Ordre de I'Elephant pour le Prince Royal, qui en fut décoreur le champ.</text>
<text><loc_10><loc_297><loc_231><loc_316>De Mridi, le 7 Decembre 1786. La Princeif des Afluries, que on infid-</text>
<text><loc_10><loc_316><loc_231><loc_365>poufit avoir empeclède d'accompagner le Roi à i n de l'Eciculari, elt revenu hier ici; elle n'a eprouvé au cune incom- modité de ce voyage, & elle continue de f et rouver beaucoup mieux.</text>
<text><loc_10><loc_364><loc_231><loc_399>Ce matin, Sa Majelle a affié la ceremonie des Chevalliers de l'Ordre de Charles III, qui a eu lieu dans la Chapelle du palais en la manière accoutumée.</text>
<text><loc_10><loc_399><loc_231><loc_470>O. apprend de Valladolid, que l'Aca- demie royle de Geographie & d'Hifboire etablie en cette ville, a tenu, le jour de la fête du Roi, fa fance publique d'ufage. Le Marquis de Gallegos, Directeur, lou- vrit par un Difcours, qui fut fuivi d'une Differtation par D. Benoit Verdefoto, fur la caufe du peu de découvertes que I'on fait en mathématiques, dans un temps où les fecours font il abondans. D. Manuel</text>
<text><loc_10><loc_470><loc_231><loc_500>Lopez termina la fiancee par une Differia-</text>
<text><loc_261><loc_144><loc_499><loc_189>tion fur les funefles conféquences que l'igno- rance de ce qui fait la veritable felicité des peuples, & les erreurs en matiere de legif- lation, produient dans le Gouvernement politique & economique des Nations.</text>
<text><loc_261><loc_189><loc_499><loc_207>De Vienne, le 8 Decembre 1786. L'ARCHIQUE FERDINAND & l'Archi-</text>
<text><loc_261><loc_207><loc_499><loc_244>ducheffe fon e poufe, après avoir affié le 3 de ce mois, à la fête de l'Ordre de la Toifon d'or, font partis le 4 avec touto leur fuite pour -retourner à Milan.</text>
<text><loc_261><loc_244><loc_499><loc_272>Le même jour, la Cour a pris un deuil de 8 jours pour la mort de la Princefle Amélie, tanute du Roi d'Angelterre.</text>
<text><loc_261><loc_272><loc_500><loc_326>L'Empereur a fait prefèrent à la Princefle Élifabeth de Wirtemberg , le jour de fête, de pluieurs parures garnies en diamans. Le même jour, il lui a remis l'Ordre de Sainte- Catharine, que l'Impréatrice Ruffie avoit envoyé pour cette Princeffe.</text>
<text><loc_261><loc_326><loc_500><loc_408>Des lettres de Roveredo en Tyrol, en date du 10 Novembre, portent qu'après des pluies & des neiges abondantes qui ont duré 7 jours, il y a eu une inondation qui a caufe beaucoup de domnages. Le routeau Lando grotil tenellement qui en detruit les édifices voifsins. Les travaux des mou- lins & des teintures furent fupendus , & on évalue la perte à 20,000 florins.</text>
<text><loc_261><loc_408><loc_500><loc_477>On a formé le projet de rétablir les anciennes fallines près de la ville de Schelan. Les États Autrichiens ont du fel en abondance; on y con- fompe par à 1,372,000 quattuqint de fel gemme, 1,363,480 de fel de foue, & 18, co de fe marin. L'exportation de cette déncerée à l'étranger, confièle en 3,000 quattunx de fel gemme, 601,225 de foue. La Stirie, la Carinthie & la Carniode tirent leur feil de Salzburg.</text>
<text><loc_261><loc_477><loc_499><loc_487>De Ffort, le 8 Decembre 1786.</text>
<text><loc_261><loc_487><loc_500><loc_500>On apprend de Buckebourg que la</text>
</doctag><end_of_utterance>
<!-- image -->

## GAZETTE DE FRANCE, Du Mardi 26 Decembre 1786.

<!-- image -->

De Pitefourg, le 17 Novembre 1786.

LA navigation eft interrompue par les glaces; pluieurs Baimtens chargés de fuif &amp; de marchandifes des manufactures An- glofies, fe trouvent pris dans la Newa dont la navigation n'a ete ouverte cette année que pendant 187 jours.

D'Upfal, le 20 Novembre 1786.

LE ROI &amp; le Prince Royal continuent a fejourner dans cette ville, &amp; a fréquenter les Cours académiques.

Hier, il y eut Cour chez le Roi; a cette occasion, le Baron de Juel, Envoyé extraoirinaire de Danemarche, remit à Sa Majelle I'Ordre de I'Elephant pour le Prince Royal, qui en fut décoreur le champ.

De Mridi, le 7 Decembre 1786. La Princeif des Afluries, que on infid-

poufit avoir empeclède d'accompagner le Roi à i n de l'Eciculari, elt revenu hier ici; elle n'a eprouvé au cune incom- modité de ce voyage, &amp; elle continue de f et rouver beaucoup mieux.

Ce matin, Sa Majelle a affié la ceremonie des Chevalliers de l'Ordre de Charles III, qui a eu lieu dans la Chapelle du palais en la manière accoutumée.

O. apprend de Valladolid, que l'Aca- demie royle de Geographie &amp; d'Hifboire etablie en cette ville, a tenu, le jour de la fête du Roi, fa fance publique d'ufage. Le Marquis de Gallegos, Directeur, lou- vrit par un Difcours, qui fut fuivi d'une Differtation par D. Benoit Verdefoto, fur la caufe du peu de découvertes que I'on fait en mathématiques, dans un temps où les fecours font il abondans. D. Manuel

Lopez termina la fiancee par une Differia-

tion fur les funefles conféquences que l'igno- rance de ce qui fait la veritable felicité des peuples, &amp; les erreurs en matiere de legif- lation, produient dans le Gouvernement politique &amp; economique des Nations.

De Vienne, le 8 Decembre 1786. L'ARCHIQUE FERDINAND &amp; l'Archi-

ducheffe fon e poufe, après avoir affié le 3 de ce mois, à la fête de l'Ordre de la Toifon d'or, font partis le 4 avec touto leur fuite pour -retourner à Milan.

Le même jour, la Cour a pris un deuil de 8 jours pour la mort de la Princefle Amélie, tanute du Roi d'Angelterre.

L'Empereur a fait prefèrent à la Princefle Élifabeth de Wirtemberg , le jour de fête, de pluieurs parures garnies en diamans. Le même jour, il lui a remis l'Ordre de Sainte- Catharine, que l'Impréatrice Ruffie avoit envoyé pour cette Princeffe.

Des lettres de Roveredo en Tyrol, en date du 10 Novembre, portent qu'après des pluies &amp; des neiges abondantes qui ont duré 7 jours, il y a eu une inondation qui a caufe beaucoup de domnages. Le routeau Lando grotil tenellement qui en detruit les édifices voifsins. Les travaux des mou- lins &amp; des teintures furent fupendus , &amp; on évalue la perte à 20,000 florins.

On a formé le projet de rétablir les anciennes fallines près de la ville de Schelan. Les États Autrichiens ont du fel en abondance; on y con- fompe par à 1,372,000 quattuqint de fel gemme, 1,363,480 de fel de foue, &amp; 18, co de fe marin. L'exportation de cette déncerée à l'étranger, confièle en 3,000 quattunx de fel gemme, 601,225 de foue. La Stirie, la Carinthie &amp; la Carniode tirent leur feil de Salzburg.

De Ffort, le 8 Decembre 1786.

On apprend de Buckebourg que la...
Enter fullscreen mode Exit fullscreen mode

Awesome 😎🎉

Second example: 🚀 Fast Batch Inference Using VLLM

The sample code (the same on the site) is the following;

# Prerequisites:
# pip install vllm
# pip install docling_core
# place page images you want to convert into "img/" dir

import time
import os
from vllm import LLM, SamplingParams
from PIL import Image
from docling_core.types.doc import DoclingDocument
from docling_core.types.doc.document import DocTagsDocument

# Configuration
MODEL_PATH = "ds4sd/SmolDocling-256M-preview"
IMAGE_DIR = "img/"  # Place your page images here
OUTPUT_DIR = "out/"
PROMPT_TEXT = "Convert page to Docling."

# Ensure output directory exists
os.makedirs(OUTPUT_DIR, exist_ok=True)

# Initialize LLM
llm = LLM(model=MODEL_PATH, limit_mm_per_prompt={"image": 1})

sampling_params = SamplingParams(
    temperature=0.0,
    max_tokens=8192)

chat_template = f"<|im_start|>User:<image>{PROMPT_TEXT}<end_of_utterance>\nAssistant:"

image_files = sorted([f for f in os.listdir(IMAGE_DIR) if f.lower().endswith((".png", ".jpg", ".jpeg"))])

start_time = time.time()
total_tokens = 0

for idx, img_file in enumerate(image_files, 1):
    img_path = os.path.join(IMAGE_DIR, img_file)
    image = Image.open(img_path).convert("RGB")

    llm_input = {"prompt": chat_template, "multi_modal_data": {"image": image}}
    output = llm.generate([llm_input], sampling_params=sampling_params)[0]

    doctags = output.outputs[0].text
    img_fn = os.path.splitext(img_file)[0]
    output_filename = img_fn + ".dt"
    output_path = os.path.join(OUTPUT_DIR, output_filename)

    with open(output_path, "w", encoding="utf-8") as f:
        f.write(doctags)

    # To convert to Docling Document, MD, HTML, etc.:
    doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
    doc = DoclingDocument(name="Document")
    doc.load_from_doctags(doctags_doc)
    # export as any format
    # HTML
    # doc.save_as_html(output_file)
    # MD
    output_filename_md = img_fn + ".md"
    output_path_md = os.path.join(OUTPUT_DIR, output_filename_md)
    doc.save_as_markdown(output_path_md)

print(f"Total time: {time.time() - start_time:.2f} sec")
Enter fullscreen mode Exit fullscreen mode

This sample uses vLLM which is challenging to run on a configuration like mine. I’ll test it very shortly in a GPU based configuration and will provide updates.

Till then… stay tuned 😎

Conclusion

Multimodal Image-Text-to-Text models are completing the already amazing Docling family and enriching with great features.

Links

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)