Views
No views yet
| smoldocling-256m-preview | granite-docling-258m | |
|---|---|---|
| Layout | ||
| MAP ↑ | 0.21 | 0.28 |
| F1 ↑ | 0.79 | 0.85 |
| Precision ↑ | 0.86 | 0.87 |
| Recall ↑ | 0.82 | 0.89 |
| Full Page OCR | ||
| Edit-distance ↓ | 0.48 (0.46) | 0.46 (0.44) |
| F1 ↑ | 0.80 (0.76) | 0.75 (0.78) |
| Precision ↑ | 0.89 (0.85) | 0.81 (0.85) |
| Recall ↑ | 0.79 (0.74) | 0.73 (0.77) |
| BLEU ↑ | 0.58 (0.54) | 0.56 (0.59) |
| Meteor ↑ | 0.67 (0.67) | 0.67 (0.70) |
| Code Recognition | ||
| Edit-distance ↓ | 0.114 | 0.013 |
| F1 ↑ | 0.915 | 0.988 |
| Precision ↑ | 0.94 | 0.99 |
| Recall ↑ | 0.909 | 0.988 |
| BLEU ↑ | 0.875 | 0.983 |
| Meteor ↑ | 0.889 | 0.986 |
| Equation Recognition | ||
| Edit-distance ↓ | 0.119 | 0.073 |
| F1 ↑ | 0.947 | 0.968 |
| Precision ↑ | 0.959 | 0.968 |
| Recall ↑ | 0.941 | 0.969 |
| BLEU ↑ | 0.824 | 0.893 |
| Meteor ↑ | 0.878 | 0.927 |
| Table Recognition (FinTabNet 150dpi) | ||
| TEDS (structure) ↑ | 0.82 | 0.97 |
| TEDS (w/content) ↑ | 0.76 | 0.96 |
| Other Benchmarks | ||
| MMStar ↑ | 0.17 | 0.3 |
| OCRBench ↑ | 338 | 500 |
1# Prerequisites:
2# pip install torch
3# pip install docling_core
4# pip install transformers
5
6import torch
7from docling_core.types.doc import DoclingDocument
8from docling_core.types.doc.document import DocTagsDocument
9from transformers import AutoProcessor, AutoModelForVision2Seq
10from transformers.image_utils import load_image
11from pathlib import Path
12
13DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
14
15# Load images
16image = load_image("https://upload.wikimedia.org/wikipedia/commons/7/76/GazettedeFrance.jpg")
17
18# Initialize processor and model
19processor = AutoProcessor.from_pretrained("ibm-granite/granite-docling-258M")
20model = AutoModelForVision2Seq.from_pretrained(
21 "ibm-granite/granite-docling-258M",
22 torch_dtype=torch.bfloat16,
23 _attn_implementation="flash_attention_2" if DEVICE == "cuda" else "eager",
24).to(DEVICE)
25
26# Create input messages
27messages = [
28 {
29 "role": "user",
30 "content": [
31 {"type": "image"},
32 {"type": "text", "text": "Convert this page to docling."}
33 ]
34 },
35]
36
37# Prepare inputs
38prompt = processor.apply_chat_template(messages, add_generation_prompt=True)
39inputs = processor(text=prompt, images=[image], return_tensors="pt")
40inputs = inputs.to(DEVICE)
41
42# Generate outputs
43generated_ids = model.generate(**inputs, max_new_tokens=8192)
44prompt_length = inputs.input_ids.shape[1]
45trimmed_generated_ids = generated_ids[:, prompt_length:]
46doctags = processor.batch_decode(
47 trimmed_generated_ids,
48 skip_special_tokens=False,
49)[0].lstrip()
50
51# Populate document
52doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
53print(doctags)
54# create a docling document
55doc = DoclingDocument.load_from_doctags(doctags_doc, document_name="Document")
56
57# export as any format
58# HTML
59# Path("Out/").mkdir(parents=True, exist_ok=True)
60# output_path_html = Path("Out/") / "example.html"
61# doc.save_as_html(output_path_html)
62# MD
63print(doc.export_to_markdown())1# Prerequisites:
2# pip install vllm
3# pip install docling_core
4# place page images you want to convert into "img/" dir
5
6import time
7import os
8from vllm import LLM, SamplingParams
9from PIL import Image
10from docling_core.types.doc import DoclingDocument
11from docling_core.types.doc.document import DocTagsDocument
12from pathlib import Path
13
14# Configuration
15MODEL_PATH = "ibm-granite/granite-docling-258M"
16IMAGE_DIR = "img/" # Place your page images here
17OUTPUT_DIR = "out/"
18PROMPT_TEXT = "Convert page to docling."
19
20# Ensure output directory exists
21os.makedirs(OUTPUT_DIR, exist_ok=True)
22
23# Initialize LLM
24llm = LLM(model=MODEL_PATH, limit_mm_per_prompt={"image": 1})
25
26sampling_params = SamplingParams(
27 temperature=0.0,
28 max_tokens=8192
29)
30
31# Load and prepare all images and prompts up front
32batched_inputs = []
33image_names = []
34
35for img_file in sorted(os.listdir(IMAGE_DIR)):
36 if img_file.lower().endswith((".png", ".jpg", ".jpeg")):
37 img_path = os.path.join(IMAGE_DIR, img_file)
38 with Image.open(img_path) as im:
39 image = im.convert("RGB")
40
41 prompt = (
42 f"<|start_of_role|>user<|end_of_role|><image>{PROMPT_TEXT}<|end_of_text|>\n"
43 f"<|start_of_role|>assistant<|end_of_role|>"
44 )
45 batched_inputs.append({"prompt": prompt, "multi_modal_data": {"image": image}})
46 image_names.append(os.path.splitext(img_file)[0])
47
48# Run batch inference
49start_time = time.time()
50outputs = llm.generate(batched_inputs, sampling_params=sampling_params)
51
52# Postprocess all results
53for img_fn, output, input_data in zip(image_names, outputs, batched_inputs):
54 doctags = output.outputs[0].text
55 output_path_dt = Path(OUTPUT_DIR) / f"{img_fn}.dt"
56 output_path_md = Path(OUTPUT_DIR) / f"{img_fn}.md"
57
58 with open(output_path_dt, "w", encoding="utf-8") as f:
59 f.write(doctags)
60
61 # Convert to DoclingDocument and save markdown
62 doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [input_data["multi_modal_data"]["image"]])
63 doc = DoclingDocument.load_from_doctags(doctags_doc, document_name="Document")
64 doc.save_as_markdown(output_path_md)
65
66print(f"Total time: {time.time() - start_time:.2f} sec")
67| Description | Instruction | Short Instruction |
|---|---|---|
| Full conversion | Convert this page to docling. | - |
| Chart | Convert chart to table. | <chart> |
| Formula | Convert formula to LaTeX. | <formula> |
| Code | Convert code to text. | <code> |
| Table | Convert table to OTSL. (Lysak et al., 2023) | <otsl> |
| Actions and Pipelines | OCR the text in a specific location: <loc_155><loc_233><loc_206><loc_237> | - |
| Identify element at: <loc_247><loc_482><10c_252><loc_486> | - | |
| Find all 'text' elements on the page, retrieve all section headers. | - | |
| Detect footer elements on the page. | - |