Docling 高级选项实战指南:模型预取与离线部署、远程服务开关与 PDF 管线调优
Docling 高级选项实战指南:模型预取与离线部署、远程服务开关与 PDF 管线调优
导读
Docling(Get your documents ready for gen AI)默认在首次使用时自动联网下载模型权重,但在内网隔离、批量生产等场景下,你需要一套"提前下载、离线复用、按需限制、显式放行"的精细控制手段。本文围绕仓库中的 docs/usage/advanced_options.md,完整讲解 Docling 的模型预取与离线配置、远程服务开关机制,以及 PDF 管线(表格识别、标题层级、Pages 文档、规模与资源限制)的核心调优项,并辅以 docling/datamodel/pipeline_options.py、docling/utils/model_downloader.py、docling/cli/models.py 等源码佐证,让读者既能照抄可运行配置,又能理解每个开关背后的实现原理。
一、模型预取与离线使用(Model prefetching and offline usage)
1.1 默认行为与预取动机
Docling 默认会在首次使用某个模型时自动下载其权重。该设计方便快速上手,但在以下场景并不适用:
- air-gapped(物理隔离/内网)环境,无法访问外网;
- 容器或 CI 流水线中,希望把模型固化进镜像、避免运行时拉取的不确定性;
- 批量生产环境,希望把"下载"与"推理"彻底分离。
因此 Docling 提供了两步走的离线方案:先用工具显式预取模型,再让转换管线指向本地模型目录。整体逻辑可参考 docling/utils/model_downloader.py 中的 download_models() 实现(第 53 行起)。
1.2 命令行预取:docling-tools models download
在仓库根目录安装 Docling 后(docling-tools 是附带 CLI,入口见 docling/cli/tools.py),直接执行:
$ docling-tools models download
Downloading layout model...
Downloading tableformer model...
Downloading picture classifier model...
Downloading code formula model...
Downloading rapidocr torch chinese models...
Downloading rapidocr torch english models...
Downloading rapidocr onnxruntime chinese models...
Downloading rapidocr onnxruntime english models...
Models downloaded into $HOME/.cache/docling/models.
默认下载目录为 $HOME/.cache/docling/models——该值来自全局设置 settings.cache_dir / "models"(默认 Path.home() / ".cache" / "docling",见 docling/datamodel/settings.py)。
默认只会拉取一组"开箱即用"模型。从 docling/cli/models.py 可以看到默认集合由五个成员构成:
| 模型标识 | 用途 | 对应管线阶段 |
|---|---|---|
layout | 版面分析 | Layout 检测(如 Heron/Egret) |
tableformer | 表格结构识别 | TableFormer |
code_formula | 代码/公式识别 | CodeFormula 模型 |
picture_classifier | 图片分类 | 图片分类器 |
rapidocr | 轻量 OCR | RapidOCR(torch/onnxruntime × chinese/english) |
CLI 子命令还提供如下参数(详见 docling/cli/models.py):
# 只下载指定模型(可按需列出多个)
docling-tools models download layout tableformer
# 下载全部可用模型(--all 与逐个指定互斥)
docling-tools models download --all
# 自定义输出目录 + 强制重新下载
docling-tools models download -o /data/models --force
# 静默模式:只打印最终模型目录,便于脚本解析
docling-tools models download -q
其中 --all 对应的完整模型清单(枚举定义)还包括 tableformerv2、smolvlm、granitedocling、granitedocling_mlx、smoldocling、smoldocling_mlx、granite_vision、granite_chart_extraction、granite_chart_extraction_v4、easyocr、nemotron_ocr_v2 等,属于按需启用的进阶能力。
注意:
--all与显式传入模型列表两者不可同时使用,CLI 会抛出参数错误(docling/cli/models.py)。
1.3 预取 EasyOCR 指定语言模型
默认预取并不包含 EasyOCR 权重。若你的管线使用 EasyOcrOptions.lang 指定了语言(如简体中文、日文),应使用 --easyocr-lang 重复传参,语言码必须与 EasyOcrOptions.lang 完全一致:
$ docling-tools models download easyocr --easyocr-lang ch_sim --easyocr-lang ja
该参数要求同时包含 easyocr 模型(docling/cli/models.py);底层会调用 _resolve_easyocr_recognition_models() 把语言码解析为对应的识别模型文件(english_g2/latin_g2 等),非法语言码会直接报参数错误。
RapidOCR 侧也有对应的高级预取语法 --rapidocr-backend-lang '<backend>:<lang>',用于精确控制"后端+语言"组合(例如 onnxruntime:el、torch:korean),它会替换默认下载集合而非追加(docling/cli/models.py)。
1.4 下载任意 HuggingFace 仓库:download-hf-repo
如果需要预取未内置在默认清单中的模型(例如 VLM 权重),可使用 download-hf-repo 子命令,直接以 repo id 为参数:
$ docling-tools models download-hf-repo ds4sd/SmolDocling-256M-preview
Downloading ds4sd/SmolDocling-256M-preview model from HuggingFace...
实现上它把 repo_id 中的 / 替换为 -- 作为本地子目录名,再通过 download_hf_model() 完成下载(docling/cli/models.py),同样支持 -o/--output-dir、--force 与 -q/--quiet。
1.5 在代码中程序化下载
不必拘泥于 CLI,也可以直接调用工具函数:
from docling.utils.model_downloader import download_models
# 全量参数见 download_models() 签名;可按需关闭某些组件以节省带宽
output_dir = download_models(
output_dir="/local/path/to/models",
force=False,
with_layout=True,
with_tableformer=True,
with_picture_classifier=True,
with_code_formula=True,
with_rapidocr=True,
with_easyocr=False,
)
print(output_dir)
download_models() 的关键开关与默认值(源码)包括:with_layout=True、with_tableformer=True、with_tableformer_v2=False、with_code_formula=True、with_picture_classifier=True、with_rapidocr=True、with_easyocr=False,以及针对各类 VLM(with_smolvlm、with_granitedocling、with_granitedocling_mlx、with_granitedocling_2stage、with_smoldocling、with_smoldocling_mlx、with_granite_vision、with_granite_chart_extraction)的独立开关。其中 easyocr_languages 与 with_easyocr=False 同时出现会触发 ValueError 提示(源码)。
1.6 使用预取模型:三种接入方式
下载完成后,将模型目录交给转换管线即可完全离线运行。
方式一:Python API——通过 PdfPipelineOptions.artifacts_path
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import EasyOcrOptions, PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
artifacts_path = "/local/path/to/models"
pipeline_options = PdfPipelineOptions(artifacts_path=artifacts_path)
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
artifacts_path 字段定义于 PipelineOptions 基类(pipeline_options.py),语义为"存放预下载模型产物的本地目录;若为 None 则首次使用时从远端获取"。模型加载代码会优先在 artifacts_path / repo_cache_folder(如 HuggingFaceTB--SmolVLM-256M-Instruct)下寻找权重(可参考 docling/models/extraction/nuextract_transformers_model.py 的目录探测逻辑)。
方式二:命令行
docling --artifacts-path="/local/path/to/models" FILE
方式三:环境变量(推荐用于脚本/容器)
export DOCLING_ARTIFACTS_PATH="/local/path/to/models"
python my_docling_script.py
DOCLING_ARTIFACTS_PATH 会被全局设置解析:AppSettings 使用 env_prefix="DOCLING_",因此该环境变量直接映射到 settings.artifacts_path(见 settings.py),管线初始化时即使用该路径作为默认 artifact 目录。仓库自带 Dockerfile 也采用了同一思路:构建时执行 docling-tools models download 将权重固化进镜像,运行时通过 -e DOCLING_ARTIFACTS_PATH=/root/.cache/docling/models 挂载使用。
注意区分两类"网络行为":拉取模型权重是否被允许,由上面的
artifacts_path/DOCLING_ARTIFACTS_PATH机制决定;而向远程服务发送文档数据则是另一套独立的enable_remote_services显式开关,见下文。
二、显式开启远程服务(Using remote services)
2.1 设计理念:隐私优先的 Opt-in 机制
Docling 的核心定位是运行本地模型、不与远程服务共享用户数据。但确实存在合法场景需要把部分管线交给远程执行,例如调用云厂商的 OCR 引擎、接入托管的 LLM/VLM。
Docling 的立场是:允许这类模型存在,但必须由用户显式声明同意与外部服务通信,否则系统会抛出异常拒绝执行。
2.2 开启方式与报错行为
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from docling.document_converter import DocumentConverter, PdfFormatOption
pipeline_options = PdfPipelineOptions(enable_remote_services=True)
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
该开关定义在 PipelineOptions 上,默认 False(pipeline_options.py)。当需要使用远程服务的模型、却未设置 enable_remote_services=True 时,系统会抛出 OperationNotAllowed() 异常。该异常类型定义于 docling/exceptions.py;例如 docling/models/inference_engines/image_classification/api_kserve_v2_engine.py 在 enable_remote_services=False 时即拒绝与 KServe 端点建立连接,报错信息会明确提示用户设置 pipeline_options.enable_remote_services=True。这与 XBRL/图片加载等场景中 OperationNotAllowed 表达"未显式授权的外部访问"的语义是一致的(可对比 docling/backend/xml/xbrl_backend.py)。
命令行工具同样暴露了对应开关(--enable-remote-services,见 docling/cli/main.py),会把值透传给各类 PipelineOptions。
注意:该开关**仅约束"系统向远程服务发送数据"**这一行为。模型权重的"拉取"控制不在此列,仍沿用前文 模型预取与离线使用 中描述的
artifacts_path/DOCLING_ARTIFACTS_PATH逻辑。
2.3 需要远程开关的模型清单
PictureDescriptionApiOptions:通过调用 OpenAI 兼容的 Chat Completions API 对图片做描述。它要求父管线显式开启enable_remote_services=True(类文档注释见 pipeline_options.py)。该选项支持配置url(默认http://localhost:8000/v1/chat/completions)、headers(如Authorization: Bearer TOKEN)、timeout(默认 20 秒)、concurrency(默认 1)、prompt模板等字段。
从源码结构可以推断,凡是后端走
api_kserve_v2_engine.py等远程引擎的选项类,都会在初始化阶段校验enable_remote_services,这构成了统一的"远程服务授权"防线。
三、调优管线功能(Adjust pipeline features)
官方示例文件 docs/examples/custom_convert.py 汇集了多种可组合的管线调整方式(切换 OCR 引擎、开关表格结构识别、指定后端等),其头部注释与多个可切换的配置块可作为快速实验的起点。下面逐项讲解本文核心的调优点。
3.1 图像分辨率与缩放(Image resolution and scale)
理解 Docling 的坐标系是调整一切"清晰度"类参数的前提:
- 页面坐标基于 72 points per inch(每英寸 72 点);
- 对图片输入,嵌入的 DPI 元数据决定物理页面尺寸;缺失 DPI 以及被标记为
(1, 1)的 DPI 一律按 72 DPI 处理; - 以
n倍率渲染时,每个文档点(point)产生n个像素。
围绕这一坐标系,有两个独立缩放参数需要注意:
- OCR 引擎的
scale字段:页面试图按"72 DPI × 该系数"渲染,因此默认值 3 等效于 216 DPI;当源图本身已是高分辨率、放大反而降低识别率时,可下调(pipeline_options.py); PdfPipelineOptions.images_scale:生成页面/元素图像的缩放系数,默认1.0,推荐取值 0.5(预览)/1.0(标准)/2.0(高清),值越大越清晰但越耗时耗空间(pipeline_options.py)。
3.2 控制 PDF 表格结构识别:do_cell_matching
Docling 默认会把 TableFormer 识别出的表格结构映射回 PDF 原始单元格(cell)。若你发现提取出的表格里多个本应独立的列被错误合并成一列,可以关闭该映射,改而直接使用表格结构模型自身预测出的文本单元格:
from docling.datamodel.base_models import InputFormat
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipeline_options import PdfPipelineOptions
pipeline_options = PdfPipelineOptions(do_table_structure=True)
pipeline_options.table_structure_options.do_cell_matching = False # uses text cells predicted from table structure model
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
源码层面,do_cell_matching 默认值为 True(TableStructureOptions)。TableStructureV2Options 的字段注释直接点明了两者的取舍:True 表示映射回 PDF 单元格、但若 PDF 单元格跨表格列合并会导致输出破碎;False 则由表格结构模型自行定义文本单元格。注意该选项仅在 do_table_structure=True(默认即为 True)时生效。
3.3 TableFormer 模式:FAST 与 ACCURATE
自 docling 1.16.0 起,你可以显式选择 TableFormer 的工作模式,在"更快但精度较低"与"更准但更慢"之间权衡。面对结构困难的表格,ACCURATE(默认)能获得明显更好的结果:
from docling.datamodel.base_models import InputFormat
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.pipeline_options import PdfPipelineOptions, TableFormerMode
pipeline_options = PdfPipelineOptions(do_table_structure=True)
pipeline_options.table_structure_options.mode = TableFormerMode.ACCURATE # use more accurate TableFormer model
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
TableFormerMode 是定义在 pipeline_options.py 的枚举(FAST/ACCURATE),TableStructureOptions.mode 的默认值即 TableFormerMode.ACCURATE(源码),其中字段注释给出的工程建议是:追求生产质量选择 accurate。
3.4 恢复 PDF 标题层级(Recover PDF heading levels)
版面模型只会把区域标记为 SECTION_HEADER(章节标题),却不会给出标题的层级深度,因此默认情况下 PDF 中的每个标题都落在 level 1,文档层级被"拍平"。Docling 可综合三类信号推断标题级别:PDF 书签/目录、大纲编号(如 1. → 1.1)、标题字体样式。
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import (
HeadingHierarchyOptions,
PdfPipelineOptions,
)
from docling.document_converter import DocumentConverter, PdfFormatOption
pipeline_options = PdfPipelineOptions()
pipeline_options.heading_hierarchy_options = HeadingHierarchyOptions(enabled=True)
pipeline_options.generate_parsed_pages = True # required by the font-style signal
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
}
)
两个关键点:
HeadingHierarchyOptions(enabled=True):enabled默认False(pipeline_options.py),开启后HeadingHierarchyModel会在阅读顺序模型之后运行,为SectionHeaderItem.level赋值;generate_parsed_pages = True:字体样式信号依赖解析后的 PDF 单元格仍可用,因此必须开启该选项;若不开启,样式推断会被静默跳过(但编号信号仍会生效)。
各信号的优先级与可控选项如下(对应 HeadingHierarchyOptions 的字段定义):
| 选项 | 默认值 | 作用 |
|---|---|---|
enabled | False | 总开关 |
use_bookmarks | True | 使用 PDF 书签/目录,与检测到的标题按标题文本+页码做模糊匹配,高置信匹配结果优先于编号与样式;无匹配的条目回落到编号/样式 |
use_numbering | True | 使用章节编号(如 PART I → 1. → 1.1 → (a) → (i),罗马/阿拉伯数字区分)作为主要信号 |
use_style | True | 使用标题视觉样式(字号,配合 use_font_style 还含粗细、斜体、全大写)作为兜底;需要 generate_parsed_pages=True |
use_font_style | True | 从嵌入字体名解析字重/倾斜并做全大写检测,用于字号相同的标题间排序 |
style_size_tolerance | 0.05 | 字号相对差在此范围内视为同一字号(0.05 意味着更高值会把更多字号折叠到同一级) |
numbering_schemes | None | 覆盖编号方案优先级;可选 part/chapter/article/roman_u/arabic/alpha_u/alpha_l/roman_l |
max_level | 6 | 允许分配的最大标题层级,更深层级被截断 |
bookmark_match_threshold | 0.8 | 书签与标题归一化相似度的最低阈值,越高越严格 |
各信号源、优先级与全部参数细节,请继续阅读仓库内的专项文档:docs/usage/heading_levels.md。
3.5 转换 Apple Pages 文档(Convert Apple Pages documents)
Apple Pages(.pages)文件与其它格式一样可直接转换,支持两代容器格式(需要安装 format-iwork 附加依赖):
from docling.document_converter import DocumentConverter
doc = DocumentConverter().convert("report.pages").document
print(doc.export_to_markdown())
Pages 在 2013 年彻底更换过容器格式,Docling 会自动识别并读取文档实际使用的容器:
- Pages 5 及以后(2013 年起):文档存储为
Index/*.iwa——一种 Snappy 帧封装的 protobuf 归档。Docling 通过 docling/backend/iwork/iwa.py 直接遍历该对象图解析; - iWork '09 及更早:文档是普通
index.xml,由 docling/backend/iwork/pages_backend.py 解析;其中模板占位文本sf:ghost-text会被跳过,因此未编辑过的模板不会产生多余内容。
两代容器共用同名段落样式(Title、Heading 1、Subheading),Docling 借此恢复标题与章节结构。
尚未覆盖的能力(官方明示):字符级格式、列表、文本框、页眉页脚、脚注与批注不会读取——只有正文及其中的表格被纳入;带密码保护的文档无法读取;表格中除文本外的单元格内容留空。
容器视为不可信输入:.iwa 归档在解包时会分别约束"成员数量、总大小、单成员大小、解压后输出大小",避免 zip 炸弹式攻击。这些上限可通过 IWorkBackendOptions 调优(backend_options.py 中的默认值:max_total_bytes=300 MB、max_file_bytes=100 MB、max_member_count=5000):
from docling.datamodel.backend_options import IWorkBackendOptions
from docling.datamodel.base_models import InputFormat
from docling.document_converter import DocumentConverter, IWorkPagesFormatOption
doc_converter = DocumentConverter(
format_options={
InputFormat.IWORK_PAGES: IWorkPagesFormatOption(
backend_options=IWorkBackendOptions(max_total_bytes=50 * 1024 * 1024)
)
}
)
四、限制文档规模(Impose limits on the document size)
面向不可信的批量输入(例如直接喂入 URL 抓取的内容)时,可同时限制单个文档的文件大小与允许处理的最大页数:
from pathlib import Path
from docling.document_converter import DocumentConverter
source = "https://arxiv.org/pdf/2408.09869"
converter = DocumentConverter()
result = converter.convert(source, max_num_pages=100, max_file_size=20971520)
max_num_pages=100:超过 100 页的文档将不被转换;max_file_size=20971520:即 20 MiB(20 * 1024 * 1024),超过则跳过。
源码层面,convert() / convert_all() 的默认值为 sys.maxsize(即默认不限制),调用时会把两个参数封装进 DocumentLimits(字段见 docling/datamodel/settings.py)下发给 _DocumentConversionInput(见 docling/document_converter.py)。convert_all() 的文档字符串还给出了批量场景的惯用写法:
results = converter.convert_all(
paths, max_file_size=20 * 1024 * 1024 # 20 MB
)
此外 convert() 还支持 page_range(页码范围)与 headers(URL 请求头)等参数,DocumentLimits.page_range 默认为 (1, sys.maxsize)。
五、从二进制流转换 PDF(Convert from binary PDF streams)
当 PDF 不在文件系统中、而是来自内存缓冲区(如从对象存储、API 响应或数据库 BLOB 读取)时,可借助 DocumentStream 包装二进制流后直接转换:
from io import BytesIO
from docling.datamodel.base_models import DocumentStream
from docling.document_converter import DocumentConverter
buf = BytesIO(your_binary_stream)
source = DocumentStream(name="my_doc.pdf", stream=buf)
converter = DocumentConverter()
result = converter.convert(source)
要点是给 DocumentStream 提供一个 name(含正确扩展名),Docling 依赖它做格式路由;source 既支持 Path/str 文件与 URL,也支持 DocumentStream,convert() 的 source 形参类型定义见 docling/document_converter.py。
六、限制资源占用(Limit resource usage)
模型推理(尤其 PyTorch/ONNX 后端)默认会按可用核数开满线程,在多任务共存的服务器上容易造成 CPU 争抢。Docling 提供如下环境变量约束:
export OMP_NUM_THREADS=4 # 把推理线程数压到 4
python my_docling_script.py
默认情况下 Docling 使用 4 个 CPU 线程。线程数最终落在 AcceleratorOptions.num_threads 上:解析逻辑优先读取正式环境变量 DOCLING_NUM_THREADS,未设置时才会读取替代变量 OMP_NUM_THREADS,并对非法值(非整数)记录错误后忽略、回落到默认 4 线程(实现见 docling/datamodel/accelerator_options.py)。相关环境变量行为有测试用例覆盖(tests/test_options.py),仓库 Dockerfile 中同样通过 ENV OMP_NUM_THREADS=4 显式声明线程预算,避免容器环境出现不必要的线程拥塞。
七、组合建议与进一步阅读
上述高级选项是正交的,可以按需自由叠加,例如"离线模型目录 + 显式开启远程描述服务 + 关闭 cell 匹配 + 恢复标题层级"可以一次性配置在同一份 PdfPipelineOptions 中。建议先以 docs/examples/custom_convert.py 为最小实验台,逐块取消注释对比输出;再结合本文涉及的源码(docling/datamodel/pipeline_options.py、docling/utils/model_downloader.py、docling/cli/models.py、docling/datamodel/backend_options.py)理解各开关的默认值与边界行为。
与本文配套的深度资料还包括:
- PDF 标题层级的全部信号与选项:docs/usage/heading_levels.md
- 多格式转换与导出格式组合:docs/examples/run_with_formats.py
- 管线选项的模型级 API 文档:docs/reference/pipeline_options.md
- 端到端批量转换示例:docs/examples/batch_convert.py
更多推荐
所有评论(0)