项目简介
Docling 可解析 PDF、DOCX、PPTX、HTML、图片及音频等多种格式,统一为结构化文档表示。它具备版面分析、阅读顺序、表格、代码与公式识别等高级 PDF 理解能力,可导出 Markdown、HTML 和无损 JSON,支持扫描件 OCR,并与 LangChain、LlamaIndex 等 AI 框架无缝集成。
README 预览
\n \n \n \n\n\n# Docling\n\n\n \n\n\n[](https://arxiv.org/abs/2408.09869)\n[](https://docling-project.github.io/docling/)\n[](https://pypi.org/project/docling/)\n[](https://pypi.org/project/docling/)\n[](https://github.com/astral-sh/uv)\n[](https://github.com/astral-sh/ruff)\n[](https://pydantic.dev)\n[](https://pypi.org/project/prek/)\n[](https://opensource.org/licenses/MIT)\n[](https://pepy.tech/projects/docling)\n[](https://apify.com/vancura/docling)\n[](https://app.dosu.dev/097760a8-135e-4789-8234-90c8837d7f1c/ask?utm_source=github)\n[](https://docling.ai/discord)\n[](https://www.bestpractices.dev/projects/10101)\n[](https://lfaidata.foundation/projects/)\n\n## What is Docling ?\n\nDocling simplifies document processing by parsing diverse formats — including advanced PDF understanding — and providing seamless integrations with the generative AI ecosystem.\n\n## Features\n\n- 🗂️ Parsing of [multiple document formats][supported_formats] including PDF, DOCX, PPTX, XLSX, HTML, EPUB, Apple Pages, WAV, MP3, WebVTT, Box Notes, email formats (EML, MSG), images (PNG, TIFF, JPEG, ...), LaTeX, DocLang, plain text, and more\n- 📑 Advanced PDF understanding incl. page layout, reading order, table structure, code, formulas, image classification, and more\n- 🧬 A unified, expressive [DoclingDocument][docling_document] representation format\n- ↪️ Various [export formats][supported_formats] and options, including Markdown, HTML, WebVTT, DocLang, [DocTags](https://arxiv.org/abs/2503.11576) and lossless JSON\n- 📜 Support for several application-specific XML schemas including [DocLang](https://doclang.ai), [USPTO](https://www.uspto.gov/patents) patents, [JATS](https://jats.nlm.nih.gov/) articles, and [XBRL](https://www.xbrl.org/) financial reports.\n- 🔒 Local execution capabilities for sensitive data and air-gapped environments\n- 🤖 Plug-and-play [integrations][integrations] incl. LangChain, LlamaIndex, Crew AI & Haystack for agentic AI\n- 🔍 Extensive OCR support for sca
常见问题 (5)
故障排除## Root cause: alpha channel handling
Transparent PNGs are stored as RGBA (or LA, or palette with transparency). Vision models used in Docling's enrichment steps — the picture classifier, VLMs for `do_picture_description`, and chart extraction models — expect 3-channel RGB input. Somewhere in the path from "extracted image" to "model input," the alpha channel gets **dropped** instead of **composited**.
The classic culprit is a naive conversion like:
```python
image.convert("RGB") # PIL: discards alpha, does NOT blend
```
## Why black specifically
This is the subtle part: in a PNG, fully transparent pixels still carry RGB values, and encoders typically store them as `(0, 0, 0)` — because those values are supposed to be invisible after alpha compositing, so the cheapest value (zero) is used. When you drop the alpha channel without blending, those hidden raw values become visible: every transparent pixel renders as solid black. Semi-transparent pixels come out as dark, muddy colors.
If the pixels had been stored as `(255, 255, 255)`, they'd turn white instead — it's encoder-dependent, but black is overwhelmingly common.
## Why it hits enrichment hard
- **Classifier / chart extraction**: trained on images with white or natural backgrounds; a black background shifts the input distribution and degrades accuracy.
- **Picture description (VLM)**: dark diagrams, text, or line art on transparency become nearly invisible against black, so the model describes "a black image" or hallucinates.
A related wrinkle: if Docling extracts the **raw embedded image** from a PDF rather than the rendered page region, transparency isn't composited against the page background the way a PDF viewer would do it (PDF transparency is often stored as a separate `SMask`).
## Fix
Composite onto an opaque background **before** the image reaches the model:
```python
from PIL import Image
def flatten_alpha(image: Image.Image) -> Image.Image:
if image.mode in ("RGBA", "LA") or (image.mode == "P" and "transparency" in image.info):
image = image.convert("RGBA")
background = Image.new("RGBA", image.size, (255, 255, 255, 255))
return Image.alpha_composite(background, image).convert("RGB")
return image.convert("RGB")
```
Key points:
- Use `Image.alpha_composite` or `background.paste(image, mask=image.split()[3])` — never bare `convert("RGB")` on RGBA.
- White is usually the right background, since it matches the page background of the source document.
- If you're calling Docling programmatically, apply this in a preprocessing step (or by overriding how picture images are provided to the enrichment model), since the default conversion path doesn't alpha-blend.
If you're hitting this through the standard pipeline without custom code, it's worth reporting on the Docling GitHub issue tracker — alpha-flattening in the enrichment preprocessing is a known gap rather than intended behavior.
Docling 的增强模型使用 PIL 的 convert("RGB") 来转换 RGBA 图像,这会保留存储在 alpha 通道下的颜色(通常是黑色),因此透明区域会变成黑色而不是白色。这会影响 document_picture_classifier.py:167、picture_description_base_model.py:106 和 inference_engines/vlm/_utils.py:131。修复方法:将这三处的 convert("RGB") 替换为 docling/backend/image_backend.py 中的 _to_rgb(在 #4511 中添加),它会将图像展平到白色背景上。作为你自己代码中的临时解决方案,可以在将图像传递给模型之前,先将 RGBA 合成到白色背景上,例如 bg = Image.new("RGB", img.size, (255,255,255)); bg.paste(img, mask=img.split()[3])。请注意,页面图像已经经过 _to_rgb 处理;只有通过 prepare_element 嵌入到 DOCX/HTML/PPTX 中的图片才会走到这个有问题的路径。
故障排除为什么 Docling 在转换包含数千个小形状的 PDF 时会无限期挂起,并忽略 document_timeout?
这是 Docling 2.132–2.134(提交 42de1e2)中的一个回归问题:阅读顺序模型会生成数量不受限制的页面分隔符候选(例如,对于一个音乐厅平面图,每个座位都是一个方块,候选数量约为 195K),而候选合并的复杂度是平方级的,因此转换实际上永远无法完成。此外,document_timeout 预算在这一阶段内部也没有被检查,导致流水线永久阻塞。
修复方法:升级到包含 PR #4633 的 Docling 版本。该修复(1)将每页的分隔符候选上限设为 5,000——超过上限的页面会跳过分隔符提取并发出警告,回退到默认阅读顺序——并且(2)当剩余的 document_timeout 预算耗尽时,候选循环和合并现在会中止,记录一个 TIMEOUT 错误,使转换以 PARTIAL_SUCCESS 状态返回,而不是挂起。
如果无法升级,临时解决方法是:使用 pip install docling==2.124 固定到未受影响的最后一个版本。
故障排除如何修复在并行对多个 PDF 运行 tesserocr OCR 时出现的 Docling 段错误 (SIGSEGV)?
根本原因:Docling 的 TesseractOcrModel 会为每个 pipeline 缓存一个 tesserocr PyTessBaseAPI 读取器,而 tesserocr 并非线程安全。当转换并发执行时(settings.perf.doc_batch_concurrency > 1,或者一个 DocumentConverter 被多个线程调用),同时进行的 SetImage/SetRectangle/GetUTF8Text 调用会相互破坏彼此的状态。随后进程会以 SIGSEGV(退出码 139)终止,抛出 cysignals.signals.SignalError: Segmentation fault,或者静默返回状态 success 但 OCR 文本缺失。
解决方法:
1. 在转换前强制使用顺序批处理转换:
from docling.datamodel.settings import settings
settings.perf.doc_batch_concurrency = 1
2. 如果你从自己的线程中调用 Docling,不要共享同一个 DocumentConverter。要么为每个线程创建单独的 DocumentConverter(每个都会构建自己的 pipeline 和 tesserocr 读取器),要么使用 threading.Lock 将所有 convert()/convert_all() 调用串行化。
3. 将 docling 升级到最新版本,并查看 issue #4940 以了解上游修复的进展状态。
注意:Python 无法捕获 SIGSEGV,因此一个文档崩溃会导致该进程中的所有转换全部终止——在线程安全的修复发布之前,请将并发数保持为 1。
故障排除如何在存在 pillow<13 依赖冲突的情况下安装 Docling 与 Pillow 13?
Docling(截至 2.141.0 版本)在四个软件包中将依赖固定为 pillow>=10.0.0,<13.0.0:docling-slim、docling-core、docling-parse 和 docling-ibm-models。这会阻止安装 Pillow 13.0.0,而该版本修复了 pip-audit 标记的 8 个 CVE(CVE-2026-112895、CVE-2026-112400、CVE-2026-112397、CVE-2026-112896、CVE-2026-112897、CVE-2026-112395、CVE-2026-112404、CVE-2026-112899)。
临时解决方案:通过依赖覆盖强制使用 Pillow 13。使用 uv 时,可以向项目添加覆盖配置,或使用 overrides 文件:
uv pip install docling --overrides overrides.txt # overrides.txt 包含:pillow==13.0.0或者在 pyproject.toml 中:
[tool.uv]
override-dependencies = ["pillow>=13.0.0"]兼容性已在 Python 3.12 环境下通过 docling 2.132.0 验证:PDF、扫描版 PDF、PNG 和 JPEG 均可成功转换,Markdown 导出结果、页数/表格数量以及页面图像尺寸与 Pillow 12.3.0 完全一致。TableFormer 运行正常。源代码审计确认 docling、docling-core、docling-parse 和 docling-ibm-models 未使用任何在 Pillow 13 中已移除的 API(
Image._show、get_child_images、ImageCmsProfile.product_name/product_info、ExifTags.IFD.Makernote、会改变 dtype 的 fromarray)。将版本上限提高至 <14.0.0 的请求正在等待处理;请查看 2.141.0 之后的发布版本,以获取官方修复。故障排除为什么 Docling 会将分号分隔的 CSV 文件按逗号拆分,以及如何解决?
这是 Docling 的 CSV 后端中的一个 bug:docling/backend/csv_backend.py 中的 _sniff_dialect() 只根据第一行(表头)检测分隔符。如果表头列名中包含逗号(例如 Weight (kg, net)),Python 的 csv.Sniffer 会选择 , 而不是 ;,导致每个单元格都被错误解析。这通常会影响 Excel 在欧洲区域设置下导出的文件,这些文件中 ; 是列分隔符,而 , 是小数点。解决方法:(1) 在转换前移除表头列名中的逗号(例如将 Weight (kg, net) 重命名为 Weight (kg net))——这样同一个文件就能按 ; 正确拆分。(2) 对文件进行预处理:使用完整文件内容探测方言(csv.Sniffer().sniff(full_text, ',;\t|:'))并重写文件,或者先将 CSV 转换为 XLSX,再用 Docling 转换。(3) 在 issue #4895 对应的修复 PR 合并后更新 Docling,该修复会让方言检测使用多行数据以保持一致性。