跳到主要内容

文档 OCR 工具箱

docTR 1.1.0 跑在自己的 GPU 上:检测、识别、版面、表格,一条流水线全部落地

docTR 是 Mindee 开源的文档 OCR 库,Apache 2.0 协议,PyPI 包名 python-doctr。默认流水线 fast_base + crnn_vgg16_bn 加起来只有 32.1M 参数,fp32 权重不到 130MB —— 显存从来不是它的门槛,吞吐才是。

docTR 走的是经典两段式:先用文本检测模型框出每一个词,再把裁剪出来的词条送进识别模型逐字解码。`ocr_predictor()` 的默认组合是 det_arch="fast_base"、reco_arch="crnn_vgg16_bn",检测端输入固定 1024×1024×3,识别端输入 32×128×3、官方基准按 batch 64 计。从 1.0.0 开始 TensorFlow 后端被彻底移除,现在只剩 PyTorch 一条路(torch>=2.0,<3.0),1.1.0 又把最低 Python 版本从 3.10 抬到了 3.11 —— 很多人升级时第一个踩的就是这个坑。

1.1.0 是这条产品线迄今变化最大的一版:新增了基于 LW-DETR 的版面分析(lw_detr_s 15.1M 参数,mAP@[.5:.95] 66.89;lw_detr_m 29.5M),可以识别标题、正文、表格、页眉页脚等 11 类版面元素;新增 TableCenterNet 表格结构识别(7.1M 参数,StarNet 主干,Recall 82.31 / Precision 96.01 / F1 88.64),能把表格还原成可以直接喂给 pandas 的行列网格;再配上按阅读顺序线性化的导出器,一条命令就能把扫描件变成 Markdown、AsciiDoc、HTML 或 XML。同时落地的还有 doctr-cli 命令行、vocab 白名单约束、ignore_regions 版面屏蔽和 preserve_original_coords。

值得先说破的一件事:docTR 官方文档里那张性能表,是在 11 代 i7-11800H @ 2.30GHz 这颗 CPU 上跑出来的。所以你看到 master 识别模型 batch 64 要 17.6 秒/迭代、db_resnet50 检测 1.1 秒/张,那不是 GPU 的成绩单。换到 GPU 上并开启 bf16,量级完全不同 —— 同源的 ONNX 版本 OnnxTR 在 FUNSD 上给出的数字是 GPU float16 约 0.05 秒/页,CPU 8-bit 约 0.38 秒/页。NexGPU 在 51 个国家和地区有 1,175 个已验证可租节点、2,498 张 GPU,按秒计费、无最低消费、无配额申请,跑完就停,正好适配 OCR 这种批量突发型负载。

01 —

docTR 模型库:检测、识别、版面、表格四类可选权重

参数量与精度取自官方 model zoo,权重体积按 fp32 每参数 4 字节折算

版本参数量显存上下文说明
fast_base(检测,ocr_predictor 默认)16.3M(重参数化后 10.6M)fp32 权重 ~65MB/bf16 ~33MB输入 1024×1024×3,B=10.9.0 起取代 db_resnet50 成为默认检测器。FUNSD Recall 84.95 / Precision 86.73,CORD Recall 94.39,速度与精度的平衡点,绝大多数场景直接用它。
db_resnet50(检测,DBNet 可微分二值化)25.4Mfp32 权重 ~102MB/bf16 ~51MB输入 1024×1024×3,B=1老牌主力,FUNSD Recall 83.56 / Precision 86.68,CORD Recall 92.61。微调数据充足时上限更高,也是 references/detection/train.py 文档里的示例架构。想更轻可换 db_mobilenet_v3_large,只有 4.2M 参数。
crnn_vgg16_bn(识别,默认)15.8Mfp32 权重 ~63MB/bf16 ~32MB输入 32×128×3,官方基准 B=64FUNSD 精确匹配 88.21、CORD 95.47,CPU 上 batch 64 只要 0.6 秒/迭代。1.0.0 还专门放出了新的 crnn_vgg16_bn 检查点。要更省,crnn_mobilenet_v3_small 只有 2.1M 参数、0.05 秒/迭代。
parseq(识别,置换自回归)23.8Mfp32 权重 ~95MB/bf16 ~48MB输入 32×128×3,B=64FUNSD 88.53 / CORD 95.56,是纯 PyTorch 权重里综合精度最好的之一,代价是 2.2 秒/迭代(CPU 基准)。社区多语种权重 Felix92/doctr-torch-parseq-multilingual-v1 也是这个架构,用 from_hub() 直接拉。
viptr_tiny(识别,0.12.0 新增)3.2Mfp32 权重 ~13MB/bf16 ~7MB输入 32×128×3,B=64Vision Permutable Extractor,FUNSD 86.03 / CORD 93.08,0.08 秒/迭代。为边缘端和高并发场景准备的轻量选项,精度只比 CRNN 低两个点。
lw_detr_s + tablecenternet(1.1.0 版面与表格)15.1M + 7.1Mfp32 权重合计 ~89MB两者输入均为 1024×1024×3,B=1detect_layout=True 拉起版面分析,detect_tables=True 拉起表格结构识别。全开时检测、识别、版面、表格四个模型同时驻留显存,是 docTR 唯一真正需要留出余量的配置。

02 —

docTR 私有化部署的 GPU 选型

权重体积微不足道,选卡看的是 det_bs、并发页数和是否要训练中文识别

  • 批量文档 OCR 推理,默认 fast_base + crnn_vgg16_bn,bf16

    RTX 3090 24GB$0.193/卡·时

    Ampere 架构,计算能力 8.0+,官方推荐的 .cuda().bfloat16() 半精度路径原生可用;24GB 让 det_bs 和 reco_bs 随便往上抬,而它是我们整个价目表里最便宜的一张卡。

  • 在线服务 / 高吞吐,四模型全开(检测 + 识别 + 版面 + 表格)

    RTX 4090 24GB$0.540/卡·时

    lw_detr_s 与 tablecenternet 都吃 1024×1024 输入,全开时算力才是瓶颈;Ada 架构对 0.11.0 引入的 torch.compile 收益最明显,单位页数成本反而更低。

  • 在自有版式上微调检测模型,input_size 1024,把默认 batch_size=2 往上抬

    RTX A6000 48GB$0.817/卡·时

    references/detection/train.py 默认 batch_size 只有 2,就是因为 1024×1024 的分割特征图极耗显存;48GB 能把 batch 抬到 8~16,配合 --amp 一晚上收敛。

  • 从零训练简体中文识别模型,--vocab simplified_chinese,多卡 torchrun

    A100 SXM4 80GB$1.088/卡·时

    简体中文字表是两万余个字符量级,输出层和 CTC/自回归解码的显存开销跟词表规模直接挂钩;80GB + NVLink 多卡 nccl 是唯一舒服的训练姿势,单节点最多可挂 14 张卡。

03 —

从空实例到 Markdown 输出,四步

PyTorch 镜像开机即用,全程不到十分钟

  1. 01

    开实例,装 python-doctr

    在 console.nexgpu.net 选一张 RTX 3090 24GB,直接用预置的 PyTorch 镜像(2000+ 镜像里也有 vLLM、ComfyUI、Whisper ASR、Ubuntu CLI)。注意 1.1.0 要求 Python ≥ 3.11,torch >=2.0,<3.0。官方 Docker 镜像基于 CUDA 12.2,宿主机 CUDA 版本必须不低于 12.2。

    pip install "python-doctr[viz,html]"
  2. 02

    一条命令把 PDF 变成带表格的 Markdown

    1.1.0 新增的 doctr-cli 不用写一行 Python。--detect_layout 拉起 LW-DETR 版面分析,--detect_tables 拉起 TableCenterNet,输出按阅读顺序线性化;--format 支持 json / txt / md / xml / html,--ignore_regions 可以直接把插图区域屏蔽掉。

    doctr-cli --input_path doc.pdf --detect_layout --detect_tables --device cuda:0 --output doc.md
  3. 03

    Python API 上 GPU,开半精度

    docTR 只在 GPU 上支持半精度推理。Ampere 及更新的架构(计算能力 8.0+,含 3090、4090、A6000、A100、H100)用 bfloat16(),更老的卡退回 half()。想换识别分支只要改 reco_arch,parseq 精度最高、viptr_tiny 最快;det_bs 和 reco_bs 是把卡吃满的两个旋钮。

    from doctr.models import ocr_predictor
    predictor = ocr_predictor("fast_base", "parseq", pretrained=True, detect_tables=True).cuda().bfloat16()
  4. 04

    要中文,就得自己训识别分支

    这是 docTR 最大的认知差:references/recognition/train.py 的 --vocab 默认值是 "french",所有官方预训练识别权重都是拉丁字表,无论怎么调参都吐不出一个汉字。真要做中文,把 vocab 换成 simplified_chinese 或 traditional_chinese 自己训,或者先用 from_hub("Felix92/doctr-torch-parseq-multilingual-v1") 打底再微调。检测分支通常不用重训。

    torchrun --nproc_per_node=4 references/recognition/train.py crnn_mobilenet_v3_large --vocab simplified_chinese --train_path /data/train --val_path /data/val -b 64 --amp --backend nccl

跑 10 万页扫描件,到底多少钱

拿一个真实体量算:10 万页 PDF,默认 fast_base + crnn_vgg16_bn,bf16 推理。OnnxTR 在 FUNSD 上给出的 GPU float16 成绩是约 0.05 秒/页,我们保守按 PyTorch 后端 0.1 秒/页估:100,000 × 0.1 秒 = 10,000 秒 ≈ 2.78 小时。租一张 RTX 4090 24GB,2.78 × $0.540 ≈ $1.50;换成 RTX 3090 24GB,就算慢 40%、跑 3.9 小时,3.9 × $0.193 ≈ $0.75 —— 十万页文档的 GPU 账单不到一杯咖啡。训练侧的量级不同:从零训一个简体中文 crnn_mobilenet_v3_large,单张 A100 SXM4 80GB 按 40 小时算是 40 × $1.088 = $43.52;用 torchrun 开 4 卡压到 10 小时,总价 4 × 10 × $1.088 = $43.52 —— 因为我们按 GPU·小时计费,并行不加价,只把墙钟时间砍掉四分之三。存储另计,中位价 $0.414/GB·月,50GB 原始 PDF 约 $20.7/月,出网中位 $0.0081/GB;实例一停算力就不再计费,存储则持续到你销毁它为止。没有最低消费,没有开通费,不用申请配额。

04 —

常见问题

DocTR 本地部署需要多大显存?8GB 的卡够不够?

权重本身几乎不占地方:默认的 fast_base(16.3M)加 crnn_vgg16_bn(15.8M)一共 32.1M 参数,fp32 折算不到 130MB,bf16 再砍一半。真正决定显存的是 det_bs × 1024×1024×3 的检测输入和 reco_bs 个 32×128 词条裁剪,以及 1.1.0 版面、表格模型是否同时驻留。8GB 跑单张推理没问题,但要把吞吐拉起来就会卡在 batch 上。NexGPU 的 RTX 3090 24GB 只要 $0.193/卡·时,比很多人手里那张 8GB 卡的电费还划算,直接省掉调 batch 的功夫。

docTR 能识别中文吗?为什么我的中文文档全是乱码?

因为官方预训练识别权重的字表是拉丁语系。references/recognition/train.py 里 --vocab 的默认值就是 "french",模型输出层压根没有汉字这一类,检测框可能框得挺准,解码出来必然是乱码。源码 vocabs.py 里确实定义了 simplified_chinese、traditional_chinese、japanese、korean 和 multilingual 字表,但需要你自己拿数据训练。简体中文两万余字符的输出层建议上 A100 SXM4 80GB($1.088/卡·时),NexGPU 单节点最多可挂 14 张卡,torchrun 多卡直接开。

docTR 和 PaddleOCR、EasyOCR 比怎么选?

docTR 的卖点是干净的 Apache 2.0 授权、纯 PyTorch 实现、检测与识别两段完全解耦可自由组合(9 种检测 × 9 种识别),以及 1.1.0 起自带版面分析和表格结构识别,能直接吐 Markdown/XML/hOCR。同源的 OnnxTR 公布的 FUNSD 基准显示它与 PaddleOCR 处于同一速度量级、明显快于 EasyOCR。想少走弯路就三个都拉起来跑同一批样本对比 —— 在 NexGPU 按秒计费,一下午的横评成本是个位数美元。

docTR 还能用 TensorFlow 后端吗?升级 1.1.0 要注意什么?

不能了。1.0.0 是分水岭,TensorFlow 后端被整个移除,PyTorch 成为唯一框架,README 的副标题现在就写着 powered by PyTorch。1.1.0 又把最低 Python 从 3.10 抬到 3.11,opencv-python 上界放宽到 <6.0.0。如果你的生产环境卡在 Python 3.10 或者还有 TF 权重,需要一次真正的迁移,而不是 pip install -U。在 NexGPU 开一台干净实例并行验证新版本,验完就停,不会污染现有环境。

docTR 用 CPU 能跑吗?为什么官方的速度表看起来那么慢?

能跑,而且官方那张表就是 CPU 成绩 —— 明确标注跑在 11 代 i7-11800H @ 2.30GHz 上。所以 master 识别 batch 64 需要 17.6 秒/迭代、sar_resnet31 需要 4.9 秒、db_resnet50 检测 1.1 秒/张,都是 CPU 数字。OnnxTR 同口径下 CPU 8-bit 约 0.38 秒/页、GPU float16 约 0.05 秒/页,差了将近八倍。而且半精度推理只在 GPU 上支持,CPU 路径连 bf16 这条优化都用不上。真要批量处理,租卡永远比等 CPU 便宜。

怎么把扫描件里的表格还原成结构化数据?

用 1.1.0 新增的 TableCenterNet(7.1M 参数,StarNet 主干,F1 88.64,结构准确率 77.53)。Python 侧给 ocr_predictor 传 detect_tables=True,命令行侧加 --detect_tables,输出的是带逻辑行列的单元格网格,能直接转成 pandas DataFrame;配合 detect_layout=True 和 lw_detr_s 还能把标题、页眉页脚分离出来,导出成阅读顺序正确的 Markdown。四个模型同时驻留时建议 RTX 4090 24GB($0.540/卡·时),NexGPU 支持 SSH、Jupyter、Web 终端、REST API 和 CLI 五种接入方式,Telegram 上有中英双语支持,不用排工单。

开始使用 NexGPU

无论你是企业研发团队还是独立开发者,都可以在几分钟内跑起第一个任务。

注册即可浏览全网实时价格,无需绑定支付方式。