说明文档
<div style="display: flex; align-items: center;"> <img src="https://huggingface.co/ds4sd/SmolDocling-256M-preview/resolve/main/assets/SmolDocling_doctags1.png" alt="SmolDocling" style="width: 200px; height: auto; margin-right: 20px;"> <div> <h3>SmolDocling-256M-preview</h3> <p>SmolDocling 是一个多模态图像-文本到文本模型,专为高效的文档转换而设计。它保留了 Docling 最受欢迎的功能,同时通过对 <strong>DoclingDocuments</strong> 的无缝支持确保与 Docling 的完全兼容性。</p> </div> </div>
该模型在论文 SmolDocling: An ultra-compact vision-language model for end-to-end multi-modal document conversion 中被提出。
🚀 特性:
- 🏷️ DocTags 高效分词 – 引入 DocTags,这是一种高效且简洁的文档表示方式,与 DoclingDocuments 完全兼容。
- 🔍 OCR(光学字符识别) – 准确从图像中提取文本。
- 📐 布局与定位 – 保留文档结构和文档元素边界框。
- 💻 代码识别 – 检测并格式化代码块,包括缩进。
- 🔢 公式识别 – 识别并处理数学表达式。
- 📊 图表识别 – 提取并解析图表数据。
- 📑 表格识别 – 支持列标题和行标题的结构化表格提取。
- 🖼️ 图片分类 – 区分图片和图形元素。
- 📝 标题对应 – 将标题与相关图片和图形关联。
- 📜 列表分组 – 正确组织和结构化列表元素。
- 📄 整页转换 – 处理整页以实现全面的文档转换,包括所有页面元素(代码、公式、表格、图表等)
- 🔲 带边界框的 OCR – 使用边界框进行 OCR 区域识别。
- 📂 通用文档处理 – 针对科学和非科学文档进行训练。
- 🔄 无缝 Docling 集成 – 导入 Docling 并以多种格式导出。
- 💨 使用 VLLM 快速推理 – 在 A100 GPU 上平均每页 0.35 秒。
🚧 即将推出!
- 📊 更好的图表识别 🛠️
- 📚 单次多页推理 ⏱️
- 🧪 化学式识别
- 📙 数据集
⌨️ 快速开始(代码示例)
您可以使用 transformers、vllm 或 onnx 进行推理,并使用 Docling 将结果转换为多种输出格式(md、html 等):
<details> <summary>📄 使用 Transformers 进行单页图像推理 🤖</summary>
# 前置条件:
# 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
from pathlib import Path
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# 加载图像
image = load_image("https://upload.wikimedia.org/wikipedia/commons/7/76/GazettedeFrance.jpg")
# 初始化处理器和模型
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)
# 创建输入消息
messages = [
{
"role": "user",
"content": [
{"type": "image"},
{"type": "text", "text": "Convert this page to docling."}
]
},
]
# 准备输入
prompt = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(text=prompt, images=[image], return_tensors="pt")
inputs = inputs.to(DEVICE)
# 生成输出
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()
# 填充文档
doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
print(doctags)
# 创建 docling 文档
doc = DoclingDocument(name="Document")
doc.load_from_doctags(doctags_doc)
# 导出为任意格式
# HTML
# output_path_html = Path("Out/") / "example.html"
# doc.save_as_html(output_filoutput_path_htmle_path)
# MD
print(doc.export_to_markdown())
</details>
<details> <summary> 🚀 使用 VLLM 进行快速批量推理</summary>
# 前置条件:
# pip install vllm
# pip install docling_core
# 将要转换的页面图像放入 "img/" 目录
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
from pathlib import Path
# 配置
MODEL_PATH = "ds4sd/SmolDocling-256M-preview"
IMAGE_DIR = "img/" # 将您的页面图像放在这里
OUTPUT_DIR = "out/"
PROMPT_TEXT = "Convert page to Docling."
# 确保输出目录存在
os.makedirs(OUTPUT_DIR, exist_ok=True)
# 初始化 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>
Assistant:"
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)
# 转换为 Docling Document、MD、HTML 等:
doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
doc = DoclingDocument(name="Document")
doc.load_from_doctags(doctags_doc)
# 导出为任意格式
# HTML
# output_path_html = Path(OUTPUT_DIR) / f"{img_fn}.html"
# doc.save_as_html(output_path_html)
# MD
output_path_md = Path(OUTPUT_DIR) / f"{img_fn}.md"
doc.save_as_markdown(output_path_md)
print(f"Total time: {time.time() - start_time:.2f} sec")
</details> <details> <summary> ONNX 推理</summary>
# 前置条件:
# pip install onnxruntime
# pip install onnxruntime-gpu
from transformers import AutoConfig, AutoProcessor
from transformers.image_utils import load_image
import onnxruntime
import numpy as np
import os
from docling_core.types.doc import DoclingDocument
from docling_core.types.doc.document import DocTagsDocument
os.environ["OMP_NUM_THREADS"] = "1"
# cuda
os.environ["ORT_CUDA_USE_MAX_WORKSPACE"] = "1"
# 1. 加载模型
## 加载配置和处理器
model_id = "ds4sd/SmolDocling-256M-preview"
config = AutoConfig.from_pretrained(model_id)
processor = AutoProcessor.from_pretrained(model_id)
## 加载会话
# !wget https://huggingface.co/ds4sd/SmolDocling-256M-preview/resolve/main/onnx/vision_encoder.onnx
# !wget https://huggingface.co/ds4sd/SmolDocling-256M-preview/resolve/main/onnx/embed_tokens.onnx
# !wget https://huggingface.co/ds4sd/SmolDocling-256M-preview/resolve/main/onnx/decoder_model_merged.onnx
# cpu
# vision_session = onnxruntime.InferenceSession("vision_encoder.onnx")
# embed_session = onnxruntime.InferenceSession("embed_tokens.onnx")
# decoder_session = onnxruntime.InferenceSession("decoder_model_merged.onnx")
# cuda
vision_session = onnxruntime.InferenceSession("vision_encoder.onnx", providers=["CUDAExecutionProvider"])
embed_session = onnxruntime.InferenceSession("embed_tokens.onnx", providers=["CUDAExecutionProvider"])
decoder_session = onnxruntime.InferenceSession("decoder_model_merged.onnx", providers=["CUDAExecutionProvider"])
## 设置配置值
num_key_value_heads = config.text_config.num_key_value_heads
head_dim = config.text_config.head_dim
num_hidden_layers = config.text_config.num_hidden_layers
eos_token_id = config.text_config.eos_token_id
image_token_id = config.image_token_id
end_of_utterance_id = processor.tokenizer.convert_tokens_to_ids("<end_of_utterance>")
# 2. 准备输入
## 创建输入消息
messages = [
{
"role": "user",
"content": [
{"type": "image"},
{"type": "text", "text": "Convert this page to docling."}
]
},
]
## 加载图像并应用处理器
image = load_image("https://ibm.biz/docling-page-with-table")
prompt = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(text=prompt, images=[image], return_tensors="np")
## 准备解码器输入
batch_size = inputs['input_ids'].shape[0]
past_key_values = {
f'past_key_values.{layer}.{kv}': np.zeros([batch_size, num_key_value_heads, 0, head_dim], dtype=np.float32)
for layer in range(num_hidden_layers)
for kv in ('key', 'value')
}
image_features = None
input_ids = inputs['input_ids']
attention_mask = inputs['attention_mask']
position_ids = np.cumsum(inputs['attention_mask'], axis=-1)
# 3. 生成循环
max_new_tokens = 8192
generated_tokens = np.array([[]], dtype=np.int64)
for i in range(max_new_tokens):
inputs_embeds = embed_session.run(None, {'input_ids': input_ids})[0]
if image_features is None:
## 仅在尚未计算时计算视觉特征
image_features = vision_session.run(
['image_features'], # 输出名称或索引列表
{
'pixel_values': inputs['pixel_values'],
'pixel_attention_mask': inputs['pixel_attention_mask'].astype(np.bool_)
}
)[0]
## 合并文本和视觉嵌入
inputs_embeds[inputs['input_ids'] == image_token_id] = image_features.reshape(-1, image_features.shape[-1])
logits, *present_key_values = decoder_session.run(None, dict(
inputs_embeds=inputs_embeds,
attention_mask=attention_mask,
position_ids=position_ids,
**past_key_values,
))
## 更新下一轮生成循环的值
input_ids = logits[:, -1].argmax(-1, keepdims=True)
attention_mask = np.ones_like(input_ids)
position_ids = position_ids[:, -1:] + 1
for j, key in enumerate(past_key_values):
past_key_values[key] = present_key_values[j]
generated_tokens = np.concatenate([generated_tokens, input_ids], axis=-1)
if (input_ids == eos_token_id).all() or (input_ids == end_of_utterance_id).all():
break # 停止预测
doctags = processor.batch_decode(
generated_tokens,
skip_special_tokens=False,
)[0].lstrip()
print(doctags)
doctags_doc = DocTagsDocument.from_doctags_and_image_pairs([doctags], [image])
print(doctags)
# 创建 docling 文档
doc = DoclingDocument(name="Document")
doc.load_from_doctags(doctags_doc)
print(doc.export_to_markdown())
</details>
💻 在 Apple Silicon 上使用 MLX 进行本地推理:参见此处
DocTags
<img src="https://huggingface.co/ds4sd/SmolDocling-256M-preview/resolve/main/assets/doctags_v2.png" width="800" height="auto" alt="Image description"> DocTags 创建了一套清晰且结构化的标签和规则系统,将文本与文档结构分离。这通过减少混淆使图像到序列模型的工作更加轻松。另一方面,直接转换为 HTML 或 Markdown 等格式可能会很混乱——这通常会丢失细节,无法清晰显示文档布局,并增加 token 数量,从而降低处理效率。 DocTags 与 Docling 集成,可导出为 HTML、Markdown 和 JSON。这些导出可以卸载到 CPU,从而减少 token 生成开销并提高效率。
支持的指令
<table> <tr> <td><b>描述</b></td> <td><b>指令</b></td> <td><b>备注</b></td> </tr> <tr> <td><b>完整转换</b></td> <td>Convert this page to docling.</td> <td>DocTags 表示</td> </tr> <tr> <td><b>图表</b></td> <td>Convert chart to table.</td> <td>(例如 <chart>)</td> </tr> <tr> <td><b>公式</b></td> <td>Convert formula to LaTeX.</td> <td>(例如 <formula>)</td> </tr> <tr> <td><b>代码</b></td> <td>Convert code to text.</td> <td>(例如 <code>)</td> </tr> <tr> <td><b>表格</b></td> <td>Convert table to OTSL.</td> <td>(例如 <otsl>) OTSL: <a href="https://arxiv.org/pdf/2305.03393">Lysak et al., 2023</a></td> </tr> <tr> <td rowspan=4><b>操作与流水线</b></td> <td>OCR the text in a specific location: <loc_155><loc_233><loc_206><loc_237></td> <td></td> </tr> <tr> <td>Identify element at: <loc_247><loc_482><10c_252><loc_486></td> <td></td> </tr> <tr> <td>Find all 'text' elements on the page, retrieve all section headers.</td> <td></td> </tr> <tr> <td>Detect footer elements on the page.</td> <td></td> </tr> </table>
模型摘要
- 开发者: Docling 团队,IBM 研究院
- 模型类型: 多模态模型(图像+文本)
- 语言: 英语
- 许可证: Apache 2.0
- 架构: 基于 Idefics3(参见技术摘要)
- 微调自模型: 基于 SmolVLM-256M-Instruct
代码库: Docling
论文: arXiv
项目页面: Hugging Face
引用:
@misc{nassar2025smoldoclingultracompactvisionlanguagemodel,
title={SmolDocling: An ultra-compact vision-language model for end-to-end multi-modal document conversion},
author={Ahmed Nassar and Andres Marafioti and Matteo Omenetti and Maksym Lysak and Nikolaos Livathinos and Christoph Auer and Lucas Morin and Rafael Teixeira de Lima and Yusik Kim and A. Said Gurbuz and Michele Dolfi and Miquel Farré and Peter W. J. Staar},
year={2025},
eprint={2503.11576},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2503.11576},
}
演示: HF Space
Compumacy/sm_doc
作者 Compumacy
创建时间: 2025-03-20 23:38:14+00:00
更新时间: 2025-03-20 23:38:15+00:00
在 Hugging Face 上查看