Docling GPU 调优实战:从设备选择、批处理大小配置到 VLM 推理服务器的高吞吐方案
本文基于 Docling 官方文档 docs/usage/gpu.md 展开,讲清 GPU 加速在 Docling 中的两条落地路径——Standard Pipeline 的设备选择与阶段级批处理配置,以及 VLM Pipeline 基于本地推理服务器(vLLM / LM Studio / Ollama)的并发调优,并结合仓库源码验证每个关键参数的实际行为与默认值,读完即可复制一套可运行的高吞吐 GPU 配置。
官方文档同时提醒:GPU 性能的改进与优化策略是一个持续演进的话题,建议定期关注 GPU support 的更新。
一、GPU 加速的两条主线
Docling 中“用上 GPU”这件事分属两条不同的流水线,配置面完全不同:
- Standard Pipeline:多阶段(布局检测、OCR、表格结构)的流水线,GPU 收益来自“设备选择 + 各阶段批处理大小”;
- VLM Pipeline:用视觉语言模型整体理解页面图像,GPU 利用率取决于推理服务器(本地 vLLM 等)与 Docling 侧的
concurrency、page_batch_size是否匹配。
两条主线分别对应仓库中的完整示例 docs/examples/gpu_standard_pipeline.py 和 docs/examples/gpu_vlm_pipeline.py。
二、Standard Pipeline:设备选择与阶段批处理
2.1 通过 AcceleratorOptions 启用 GPU
通过 AcceleratorDevice 与 AcceleratorOptions 指定推理设备:
from docling.datamodel.accelerator_options import AcceleratorDevice, AcceleratorOptions
# Configure accelerator options for GPU
accelerator_options = AcceleratorOptions(
device=AcceleratorDevice.CUDA, # or AcceleratorDevice.AUTO
)
从源码 docling/datamodel/accelerator_options.py 可以看到该配置的完整取值面:
AcceleratorDevice枚举支持auto/cpu/cuda/mps/xpu五种设备;device字段是str | AcceleratorDevice的联合类型,因此还可以传入字符串"cuda:N"来指定某一块具体的 NVIDIA 卡(字段校验器接受^cuda(:\d+)?$);AcceleratorOptions是BaseSettings子类,可用DOCLING_前缀环境变量配置,如DOCLING_DEVICE=cuda:1、DOCLING_NUM_THREADS(CPU 线程数,默认 4,另兼容OMP_NUM_THREADS作为回退);- 还有一个 GPU 相关开关
cuda_use_flash_attention2:在 Ampere 及更新的 NVIDIA GPU 上启用 Flash Attention 2,可显著降低显存并提速,需要额外安装flash-attn包。
设备最终如何被解析,由 docling/utils/accelerator_utils.py 中的 decide_device() 决定:auto 模式按 CUDA → MPS → XPU 的优先级探测可用后端;显式指定 cuda 而系统没有可用 CUDA 时,会抛出 AcceleratorDeviceNotAvailableError 并提示改用 auto/cpu,而不是静默回退——这一点在排障时值得注意(cpu 除外,显式指定 cpu 永远安全)。
2.2 批处理大小:让模型以 GPU batch 模式推理
文档批处理与并发性通过 ThreadedPdfPipelineOptions 按流水线阶段分别控制:
from docling.datamodel.pipeline_options import ThreadedPdfPipelineOptions
pipeline_options = ThreadedPdfPipelineOptions(
ocr_batch_size=64, # default 4
layout_batch_size=64, # default 4
table_batch_size=4, # currently not using GPU batching
)
结合 docling/datamodel/pipeline_options.py 的字段定义:
| 参数 | 默认值 | 作用(源码 Field 描述摘要) |
|---|---|---|
ocr_batch_size |
4 | OCR 阶段的页面批大小,页面成组处理以提升吞吐;值越大越吃显存/内存 |
layout_batch_size |
4 | 布局分析阶段的页面批大小,提升吞吐但内存占用更高 |
table_batch_size |
4 | 表格结构提取的批大小,跨页面的表格成组处理 |
三个批处理参数“仅被 threaded 模式的 StandardPdfPipeline 使用”,这是源码描述中的明确限定;ThreadedPdfPipelineOptions 继承自 PdfPipelineOptions,把页面送入由有界队列连接的并发阶段,形成单文档内的流水线并行。
文档强调的一个关键机制是:把 page_batch_size(页面批)调大,Docling 的模型(尤其是布局检测阶段)就会进入 GPU batch 推理模式。换句话说,小批意味着逐页前向,显存利用不充分;调大批大小才是“把模型喂饱”的核心手段。注意 table_batch_size 目前并未真正走 GPU batching(官方文档原话),调大它收益有限。
2.3 完整示例
完整可运行示例见 docs/examples/gpu_standard_pipeline.py,其要点为:
pipeline_options = ThreadedPdfPipelineOptions(
accelerator_options=AcceleratorOptions(device=AcceleratorDevice.CUDA),
ocr_batch_size=4,
layout_batch_size=64,
table_batch_size=4,
)
pipeline_options.do_ocr = False
doc_converter = DocumentConverter(
format_options={
InputFormat.PDF: PdfFormatOption(
pipeline_cls=ThreadedStandardPdfPipeline,
pipeline_options=pipeline_options,
)
}
)
注意示例中显式使用 ThreadedStandardPdfPipeline 作为 pipeline_cls,并关闭 OCR(do_ocr = False)以验证纯 GPU 布局推理路径;示例还会打印“pages/second”用于对比吞吐。运行方式:python docs/examples/gpu_standard_pipeline.py(Python 3.9+,pip install docling)。
2.4 OCR 引擎的 GPU 支持现状
Docling 的 OCR 引擎依赖第三方库,因此 GPU 支持取决于各引擎自身的能力。据官方文档,当前已知可用的唯一组合是 RapidOCR + torch 后端:
pipeline_options = PdfPipelineOptions()
pipeline_options.ocr_options = RapidOcrOptions(
backend="torch",
)
这一点可在 PdfPipelineOptions.ocr_options 的默认值 OcrAutoOptions()(见 docling/datamodel/pipeline_options.py)处印证:默认走自动选择引擎,要固定到 RapidOCR 的 torch 后端需显式覆盖。更多细节见该项目 GitHub Discussions 中的 #2451 讨论(仓库文档中的原引用)。
三、VLM Pipeline:本地推理服务器 + 并发匹配
3.1 选择推理服务器
官方建议:为获得最佳 GPU 利用率,使用本地推理服务器。Docling 支持所有暴露 OpenAI 兼容 chat completion 端点的推理服务器,文档列出的三个例子及平台可用性:
| 服务器 | 端点 | 平台 |
|---|---|---|
| vllm | http://localhost:8000/v1/chat/completions |
仅 Linux |
| LM Studio | http://localhost:1234/v1/chat/completions |
Linux / Windows |
| Ollama | http://localhost:11434/v1/chat/completions |
Linux / Windows |
3.2 启动 vLLM 服务(以 Granite Docling 为例)
官方给出的针对 Granite Docling 模型的 vLLM 启动命令(含调优参数):
vllm serve ibm-granite/granite-docling-258M \
--host 127.0.0.1 --port 8000 \
--max-num-seqs 512 \
--max-num-batched-tokens 8192 \
--enable-chunked-prefill \
--gpu-memory-utilization 0.9
参数含义:--max-num-seqs 512 与 --max-num-batched-tokens 8192 放宽 vLLM 的并发调度上限,--enable-chunked-prefill 允许分块预填充以平滑批处理,--gpu-memory-utilization 0.9 让 KV cache 占满约 90% 显存。
3.3 配置 Docling 侧:concurrency 与 page_batch_size 匹配
官方文档给出的直接配置写法:
from docling.datamodel.pipeline_options import VlmPipelineOptions
vlm_options = VlmPipelineOptions(
enable_remote_services=True,
vlm_options={
"url": "http://localhost:8000/v1/chat/completions", # or any other compatible endpoint
"params": {
"model": "ibm-granite/granite-docling-258M",
"max_tokens": 4096,
},
"concurrency": 64, # default is 1
"prompt": "Convert this page to docling.",
"timeout": 90,
}
)
关键约束:除 concurrency(默认 1)之外,还必须同步设置 settings.perf.page_batch_size,且要满足:
settings.perf.page_batch_size >= vlm_options.concurrency
from docling.datamodel.settings import settings
settings.perf.page_batch_size = 64 # default is 4
这个约束的来由可从 docling/datamodel/settings.py 印证:settings.perf 是全局单例 AppSettings 下的 BatchConcurrencySettings,其中 page_batch_size 默认值为 4(字段注释:“Number of pages processed in one batch”),另有 doc_batch_size、elements_batch_size(富集模型批大小,默认 16)等。若并发度为 64 而页面批只有 4,则 Docling 一次只喂 4 页给推理服务器,64 路并发大部分时间空转,GPU 自然吃不饱。AppSettings 同样支持 DOCLING_ 前缀环境变量(嵌套分隔符 _),也提供了 settings.scoped() 上下文管理器用于临时覆盖后自动还原。
3.4 完整示例:基于 preset 的推荐写法
完整示例 docs/examples/gpu_vlm_pipeline.py 展示了仓库当前推荐的“preset + 引擎覆盖”写法:
BATCH_SIZE = 64
settings.perf.page_batch_size = BATCH_SIZE
settings.debug.profile_pipeline_timings = True
# 使用 granite_docling preset,并用 API 运行时(vLLM)覆盖
vlm_options = VlmConvertOptions.from_preset(
"granite_docling",
engine_options=ApiVlmEngineOptions(
runtime_type=VlmEngineType.API,
url="http://localhost:8000/v1/chat/completions",
concurrency=BATCH_SIZE,
),
)
pipeline_options = VlmPipelineOptions(
vlm_options=vlm_options,
enable_remote_services=True, # 使用远程推理服务时必须开启
)
对应源码 docling/datamodel/pipeline_options.py 中的 VlmPipelineOptions:其 vlm_options 字段类型联合中包含 VlmConvertOptions(preset 体系,推荐)、旧版 InlineVlmOptions / ApiVlmOptions(兼容保留),默认 preset 为 granite_docling;该流水线不单独跑布局与 OCR 阶段,generate_page_images 默认开启(VLM 需要视觉输入)。示例运行前需 pip install vllm(Python 3.10+),并把前面 3.2 的 vLLM 服务先拉起来。
3.5 可用模型(gguf)
LM Studio 与 Ollama 均以 llama.cpp 为运行时,使用前需把模型转换为 gguf 格式。官方文档中“已知可用的 gguf 模型清单”目前标注为 TBA(待补充),此处不做臆测——以官方文档后续更新为准。
四、官方基准:测试数据、测试机与实测吞吐
4.1 测试数据
| PDF 文档 | ViDoRe V3 HR | |
|---|---|---|
| 文档数 | 1 | 14 |
| 页数 | 192 | 1110 |
| 表格数 | 95 | 258 |
| 数据形态 | 图像 Parquet |
4.2 测试基础设施
| g6e.2xlarge | RTX 5090 | RTX 5070 | |
|---|---|---|---|
| 描述 | AWS 实例 g6e.2xlarge |
Linux 裸金属 | Windows 11 裸金属 |
| CPU | 8 vCPU,AMD EPYC 7R13 | 16 vCPU,AMD Ryzen 7 9800 | 16 vCPU,AMD Ryzen 7 9800 |
| 内存 | 64GB | 128GB | 64GB |
| GPU | NVIDIA L40S 48GB | GeForce RTX 5090 | GeForce RTX 5070 |
| CUDA 版本 | 13.0,驱动 580.95.05 | 13.0,驱动 580.105.08 | 13.0,驱动 581.57 |
4.3 实测结果(pages/second)
| 流水线 | g6e.2xlarge (PDF) | RTX 5090 (PDF / ViDoRe) | RTX 5070 (PDF / ViDoRe) |
|---|---|---|---|
| Standard - Inline(无 OCR) | 3.1 pages/s | 7.9 pages/s(*纯 CPU 仅 1.5 pages/s) | 4.2 pages/s(*纯 CPU 仅 1.2 pages/s) |
| Standard - Inline(含 OCR) | — | 待补 / 1.6 pages/s(ViDoRe) | 待补 / 1.1 pages/s(ViDoRe) |
| VLM - 推理服务器(GraniteDocling) | 2.4 pages/s | 3.8 pages/s / 3.6–4.5 pages/s | 2.0 pages/s / 2.8–3.2 pages/s |
* 纯 CPU 计时使用 16 个 PyTorch 线程测得。
从这组数字能读出三个结论(均以官方文档数字为准,环境各不相同,请勿跨行直接比较):
- 在 RTX 5090 / 5070 上,Standard 流水线(无 OCR)相比纯 CPU 有明显加速(约 5 倍量级),而开启 OCR 后吞吐显著回落(1.6 / 1.1 pages/s)——这与 2.4 节“OCR 引擎 GPU 支持有限”的现状一致;
- VLM 流水线借助 vLLM 本地服务在 RTX 5090 上可达 3.8–4.5 pages/s,说明“本地推理服务器 + 并发 64”这一组合是当前 VLM 路径的主要吞吐来源;
- 云端实例(L40S)与本地高端消费级显卡吞吐处于同一数量级,选型时可按成本与合规约束权衡。
五、落地清单与调优建议
- Standard 路径:
AcceleratorOptions(device=AcceleratorDevice.CUDA)(或用DOCLING_DEVICE环境变量、cuda:N指定卡)→ThreadedPdfPipelineOptions中调大ocr_batch_size/layout_batch_size(默认均为 4)→ 确认流水线类是 threaded 模式; - OCR 需要 GPU:显式
RapidOcrOptions(backend="torch"); - VLM 路径:本地起 vLLM/LM Studio/Ollama →
concurrency与settings.perf.page_batch_size同值且都显著大于默认 4 →enable_remote_services=True; - 验证手段:开启
settings.debug.profile_pipeline_timings = True,用 docs/examples/gpu_vlm_pipeline.py 中的计时与ProfilingItem导出方式查看各阶段(如page_init、vlm)的 min/median/max 秒/页; - 多卡场景:可用
device="cuda:1"指定 GPU,或配合num_threads控制 CPU 侧线程,避免 CPU 成为前处理瓶颈。
以上所有参数与行为均可在仓库内复核:设备解析逻辑见 docling/utils/accelerator_utils.py,批处理选项定义见 docling/datamodel/pipeline_options.py,全局 settings.perf 见 docling/datamodel/settings.py,官方 GPU 指南见 docs/usage/gpu.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00