前言
去年底 (2024/11) IBM 最新開源 Docling 工具 (Python 套件),可以讀取一些常見的文件格式(PDF、DOCX、PPTX、XLSX、圖片、HTML、Markdown…)並匯出成 JSON、Markdown、HTML,以及對 PDF 裡的頁面佈局、表格、公式、程式碼…等等有較好的理解,而且也支援 OCR 辨識。
我還沒有做太多測試、比較,只是做個簡單的紀錄。
安裝套件
安裝很簡單,透過 pip 安裝:
* 本文使用 Docling 版本為:v2.17.0
使用教學 & 範例程式碼
簡單三步驟:設定來源、轉換文件、輸出結果
設定文件來源
Docling 支援多種格式:PDF、DOCX、PPTX、XLSX、Image、HTML、Markdown、AsciiDoc
參考:https://ds4sd.github.io/docling/supported_formats/
輸入可以是網址或本地檔案路徑:
1
2
3
| source = "https://arxiv.org/pdf/2412.16720" # PDF path or URL
source = "./docs/測試用.pdf"
source = "./docs/測試用2.docx"
|
轉換文件
將文件轉換成它定義的 DolingDocument 格式,就會包含文件的像是檔名、文字、表格、圖片…等等資訊。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| # 簡單快速使用
converter = DocumentConverter()
# 也可以限制轉換格式
# converter = DocumentConverter(
# allowed_formats=[InputFormat.PDF, InputFormat.IMAGE, InputFormat.DOCX, InputFormat.PPTX, InputFormat.MD, InputFormat.HTML, InputFormat.ASCIIDOC],
# format_options={
# InputFormat.PDF: PdfFormatOption(
# pipeline_cls=StandardPdfPipeline, backend=PyPdfiumDocumentBackend
# ),
# InputFormat.DOCX: WordFormatOption(
# pipeline_cls=SimplePipeline # , backend=MsWordDocumentBackend
# ),
# },
# )
# 預測模型會在首次使用時自動下載,也可以指定事先下載好的資料夾路徑
# 在離線環境方便使用
# 模型可能是這邊下載:https://huggingface.co/ds4sd/docling-models
# 我也不太確定
# pipeline_options = PdfPipelineOptions(artifacts_path="your location")
# converter = DocumentConverter(
# format_options={
# InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
# }
# )
# pipeline
# https://ds4sd.github.io/docling/usage/#adjust-pipeline-features
# 開始轉換文件
result = converter.convert(source)
# 也可以限制文件頁數和大小
# result = converter.convert(source, max_num_pages=10, max_file_size=20971520)
|
輸出結果
將轉換後的文件輸出成不同的格式,像是純文字、HTML、Markdown 和 JSON:
1
2
3
4
5
6
7
| print(result.document.export_to_text())
print(result.document.export_to_dict()) # json
print(result.document.export_to_html())
print(result.document.export_to_markdown())
print(result.document.export_to_document_tokens())
# print(result.document.print_element_tree())
# print(result.document._export_to_indented_text(max_text_len=16))
|
也可以直接儲存成檔案:
1
2
3
4
5
6
7
| from pathlib import Path
result.document.save_as_markdown(filename=Path("./docs/test.md"))
result.document.save_as_html(filename=Path("./docs/test.html"))
result.document.save_as_json(filename=Path("./docs/test.json"))
result.document.save_as_document_tokens(filename=Path("./docs/test.tokens"))
result.document.save_as_yaml(filename=Path("./docs/test.yaml"))
|
完整範例程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| import json
from pathlib import Path
from docling_core.types import DoclingDocument
from docling.datamodel.base_models import InputFormat
from docling.document_converter import (
DocumentConverter,
PdfFormatOption,
WordFormatOption,
)
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.pipeline.simple_pipeline import SimplePipeline
from docling.pipeline.standard_pdf_pipeline import StandardPdfPipeline
from docling.backend.pypdfium2_backend import PyPdfiumDocumentBackend
# source = "https://arxiv.org/pdf/2408.09869" # PDF path or URL
# source = "./docs/OpenAIo1SystemCard.pdf.pdf"
source = "./docs/測試文件.docx"
converter = DocumentConverter()
# # 可以限制轉換格式
# converter = DocumentConverter(
# allowed_formats=[InputFormat.PDF, InputFormat.IMAGE, InputFormat.DOCX, InputFormat.PPTX, InputFormat.MD, InputFormat.HTML, InputFormat.ASCIIDOC],
# format_options={
# InputFormat.PDF: PdfFormatOption(
# pipeline_cls=StandardPdfPipeline, backend=PyPdfiumDocumentBackend
# ),
# InputFormat.DOCX: WordFormatOption(
# pipeline_cls=SimplePipeline # , backend=MsWordDocumentBackend
# ),
# },
# )
# 開始轉換文件
result = converter.convert(source)
# 也可以限制文件頁數和大小
# result = converter.convert(source, max_num_pages=10, max_file_size=20971520)
# 輸出結果
# print(result.document.export_to_text())
print(result.document.export_to_dict())
# print(result.document.export_to_html())
# print(result.document.export_to_markdown())
# print(result.document.export_to_document_tokens())
# print(result.document.print_element_tree())
# print(result.document._export_to_indented_text(max_text_len=16))
# 直接儲存成檔案
# result.document.save_as_markdown(filename=Path("./docs/test.md"))
# result.document.save_as_html(filename=Path("./docs/test.html"))
# result.document.save_as_json(filename=Path("./docs/test.json"))
# result.document.save_as_document_tokens(filename=Path("./docs/test.tokens"))
# result.document.save_as_yaml(filename=Path("./docs/test.yaml"))
# 另一種方法,儲存與讀取
# # Save to disk
# with open('./docs/test.json', 'w', encoding='utf-8') as fp:
# json.dump(doc.export_to_dict(), fp, ensure_ascii=False) # use `export_to_dict` to ensure consistency
# # Load from disk
# with open('./docs/test.json', 'r', encoding='utf-8') as f:
# doc_dict = json.load(f)
# doc = DoclingDocument.model_validate(doc_dict) # use standard pydantic API to populate doc
|
切割 chunk
另外 Docling 也內建切 chunk 的函式,在做 RAG 時會使用到:https://ds4sd.github.io/docling/examples/hybrid_chunking/
1
2
3
4
5
6
7
8
| # 切 chunk
from docling.document_converter import DocumentConverter
from docling_core.transforms.chunker import HierarchicalChunker # 分層分塊器
conv_res = DocumentConverter().convert("https://arxiv.org/pdf/2206.01062")
doc = conv_res.document
chunks = list(HierarchicalChunker().chunk(doc))
print(chunks[30])
|
其他
官方文件內有示範多種範例,可以探索還有哪些使用方法:https://ds4sd.github.io/docling/examples/
結語
除了 Docling,其他類似功能的套件還有像是 unstructured、MarkItDown、
PyMuPDF4LLM、MinerU…,我有空應該也會找時間來試試看。
參考:
Docling 官方文件
Docling GitHub
ds4sd/docling-models | Hugging Face
Embrace the unknown and embrace change. That’s where true breakthroughs happen.
擁抱未知,擁抱變化。那才是真正的突破所在!
—— 黃仁勳 (NVIDIA 共同創辦人暨執行長)
🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~