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=1 | 0.9.0 起取代 db_resnet50 成为默认检测器。FUNSD Recall 84.95 / Precision 86.73,CORD Recall 94.39,速度与精度的平衡点,绝大多数场景直接用它。 |
| db_resnet50(检测,DBNet 可微分二值化) | 25.4M | fp32 权重 ~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.8M | fp32 权重 ~63MB/bf16 ~32MB | 输入 32×128×3,官方基准 B=64 | FUNSD 精确匹配 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.8M | fp32 权重 ~95MB/bf16 ~48MB | 输入 32×128×3,B=64 | FUNSD 88.53 / CORD 95.56,是纯 PyTorch 权重里综合精度最好的之一,代价是 2.2 秒/迭代(CPU 基准)。社区多语种权重 Felix92/doctr-torch-parseq-multilingual-v1 也是这个架构,用 from_hub() 直接拉。 |
| viptr_tiny(识别,0.12.0 新增) | 3.2M | fp32 权重 ~13MB/bf16 ~7MB | 输入 32×128×3,B=64 | Vision Permutable Extractor,FUNSD 86.03 / CORD 93.08,0.08 秒/迭代。为边缘端和高并发场景准备的轻量选项,精度只比 CRNN 低两个点。 |
| lw_detr_s + tablecenternet(1.1.0 版面与表格) | 15.1M + 7.1M | fp32 权重合计 ~89MB | 两者输入均为 1024×1024×3,B=1 | detect_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 镜像开机即用,全程不到十分钟
- 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]" - 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 - 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() - 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 —
