你扔给 AI 的扫描件,它一个字都看不懂?OCR 与文档理解焊死「赋予 AI 阅读能力」的完整链路,从 Tesseract 到 Donut 一篇打通

你把一张发票拍照扔给大模型,它回了句"我看不到图片";你把合同 PDF 塞进本地知识库做 RAG,检索出来的向量全是乱码。别急着怪 AI 笨——问题出在它没有"眼睛":图像里的文字对人类是白纸黑字,对模型只是像素迷宫。OCR 与文档理解,就是给 AI 焊上"阅读"能力的全过程:先看见字(文本检测),再读懂字(文本识别),最后看懂结构(版面分析、表格识别、表单理解、关键信息抽取)。

很多教程只教你 pip install pytesseract 然后调一行 API,遇到扫描件倾斜、表格错位、发票字段抽不出来就当场翻车。这篇把 OCR/文档理解从 1929 年的机械扫描讲到 2022 年的 Donut 端到端模型,检测、识别、版面、表格、表单、训练、部署、面试题一次性焊透。读完全文你将能:说清 OCR Pipeline 每一环在干什么、CTC Loss 到底解决了什么、DBNet 为什么靠"可微分二值化"封神、CRNN 和 TrOCR 各赢在哪、LayoutLM 三代演进的核心矛盾、以及 PaddleOCR/TrOCR/LayoutLMv3 三行代码怎么落地。


1. 概述与定义

1.1 什么是 OCR 与文档理解

OCR(Optical Character Recognition,光学字符识别):把图像/扫描件/照片里的文字,从像素转录成可编辑、可检索的文本或字符序列。回答的问题是"图像里写了什么字,字在哪儿"。

文档理解(Document Understanding / Document AI):在 OCR 之上再做结构化与语义化,回答的问题是"这份文档是什么类型、版面怎么组织的、关键信息(金额、日期、合同号)在哪里"。它通常包含 OCR 组件,但目标从"转录"升维到"理解"。

两者是包含关系而非并列关系,一张图说清分层:

结构级 Document Understanding

版面分析
Layout Analysis

表格理解
Table Understanding

表单理解 / KIE
关键信息抽取

阅读顺序
Reading Order

文字级 OCR

图像预处理

文本检测
Text Detection

文本识别
Text Recognition

结构化输出
JSON / XML / 数据库

层次 任务 输入 输出 代表技术
像素级 文本检测 整图 文本框坐标(框/多边形/曲线) DBNet、PSENet、EAST
字符级 文本识别 文本框裁剪图 字符串 CRNN、TrOCR、SVTR
页面级 版面分析 整页图 区域类型(标题/正文/表格/图) LayoutLM 系列、U-Net 分割
结构级 表格/表单理解 版面区域 单元格结构 / 键值对 Table Transformer、PaFormer
语义级 文档问答/分类 整页图 答案 / 类别 Donut、VLM 读文档

1.2 文档类型与处理难度

不同文档的处理难度差异极大,这是工业落地的第一个决策点:

文档类型 典型例子 复杂点 难度
印刷体扫描件 书籍、报纸 倾斜、摩尔纹、装订阴影
拍照文档 手机拍的合同、PPT 透视畸变、反光、光照不均
表格文档 财务报表、化验单 跨列合并单元格、无边框表格 中高
表单/票据 发票、行程单、快递单 字段布局不固定、盖章遮挡
手写内容 手写病历、签到表 连笔、风格差异、字符集大 很高
场景文字 路牌、招牌、商品包装 弯曲、透视、低分辨率、遮挡 很高

难度主要来自三方面:图像退化(模糊、光照、畸变)、文字形态(印刷/手写、横排/竖排/弯曲、中英文混排)、版面结构(表格、多栏、阅读顺序)。后面每一章都是在跟这三类敌人作战。


2. 发展历史与里程碑

2.1 OCR 发展历程

OCR 是 AI 领域历史最悠久的分支之一,比深度学习早了大半个世纪:

1929 Tauschek 申请 OCR 专利<br/>机械模板匹配读字 1950s 商用读取机出现<br/>银行支票自动处理 1970s 印刷体识别实用化<br/>专用硬件扫描识别 1980 Neocognitron 提出<br/>卷积神经雏形 1989-98 LeNet-5 手写数字<br/>CNN 证明自己 2012 AlexNet 引爆深度学习 2015 CRNN + CTC 定式<br/>"CNN+RNN+CTC" 成为主流 2017 Transformer 问世 2019 DBNet / LayoutLM<br/>分割式检测 + 版面预训练 2021 TrOCR 纯 Transformer<br/>检测识别分离 2022 Donut 端到端<br/>LayoutLMv3 去 OCR 2023- 大模型读文档<br/>DocVQA / VLM 多模态理解 OCR 百年简史

几个关键转折点值得单独说:

  • 1929 年,Gustav Tauschek 获得光学字符识别专利,用机械模板和光敏器件匹配字符形状,这是 OCR 的起点。
  • 1950-1960 年代,商用化爆发:美国运通、银行系统用 OCR 读取支票和信用卡单,IBM 推出 1287/1288 型读取机。这个阶段 OCR 靠的是模板匹配和结构特征,只能处理特定字体。
  • 1980 年,福岛邦彦提出 Neocognitron,首次用"卷积+池化"层级结构模拟视觉皮层,是 CNN 的直系祖先;1989-1998 年 LeCun 的 LeNet 系列把 CNN + 反向传播焊在一起,手写数字识别达到商用水准(当时美国银行支票用 LeNet 系模型)。
  • 2015 年,CRNN(Shi et al.)把"CNN 提特征 + RNN 建模序列 + CTC 对齐"三件套固定为经典范式,让 OCR 从"逐字分类"进化到"整行识别",这一范式统治场景文字识别近五年。
  • 2017 年 Transformer 问世后,OCR 进入第二曲线:2019 年 DBNet 用分割思路解决任意形状文字检测,2019 年 LayoutLM 给 BERT 焊上 2D 位置编码做版面理解,2021 年 TrOCR 把识别器换成纯 Transformer,2022 年 Donut 直接"图进、结构化文本出"、彻底抛弃 OCR 中间步骤。
  • 2023 年至今,多模态大模型(GPT-4V、Qwen-VL 等)可以直接"看"图答题,OCR 的场景文字识别与文档理解开始被大模型"下凡平推",但 OCR 作为结构化管线组件、端侧部署、表格细粒度识别,价值依然不可替代。

一句话总结历史脉络:从模板匹配 → CNN 分类 → 序列建模(CTC)→ 注意力 → Transformer 多模态,精度一步步被焊死,端到端程度越来越高,对人工中间步骤的依赖越来越低。


3. 核心概念与基础理论

3.1 OCR Pipeline

现代 OCR 系统的标准流水线(两阶段范式):

输入图像

图像预处理

文本检测

文本区域裁剪

文本识别

语言模型后处理

版面/表格/表单结构化

JSON 结构化输出

环节 输入 输出 典型手段
预处理 原图 规整图像 灰度化、二值化、去噪、倾斜矫正
检测 规整图像 文本行框/多边形 DBNet、EAST、PSENet
识别 每个文本行裁剪图 字符串 + 置信度 CRNN、SVTR、TrOCR
后处理 原始字符串 纠正后的字符串 词典约束、纠错、置信过滤
结构化 全部文本行 JSON/XML 版面分析、KIE、表格还原

理解这条流水线是理解后面所有内容的地基:检测负责"字在哪儿",识别负责"字是什么",结构化负责"文档在表达什么"。 任何一个环节精度掉链子,整个系统的可端到端复用的文档解析质量都会崩。

3.2 图像预处理技术

预处理的目标是"把汤里的杂质去掉,让检测识别模型吃得干净"。核心手段:

灰度化与归一化

  • RGB 三通道转单通道灰度(如 0.299R + 0.587G + 0.114B),降低计算量;
  • 像素归一化到 [0,1] 或标准化(减均值除方差),稳定模型输入分布。

二值化(Binarization)

  • 文本与背景对比度明显时,用阈值把图像压成黑/白两值;
  • Otsu 大津法:自动寻找使类间方差最大的全局阈值,公式为 σ²(t) = ω₀(t)·ω₁(t)·[μ₀(t) − μ₁(t)]²,遍历灰度级找最大值;
  • 局部阈值(自适应阈值,Niblack/Sauvola)处理光照不均:T(x,y) = m(x,y) · (1 + k·(s(x,y)/R − 1)),对每像素邻域动态定阈值。

去噪

  • 中值滤波(去椒盐噪声)、高斯滤波(去高斯噪声)、形态学开闭运算(去小噪点、连断笔画)。注意:滤波太狠会抹掉细笔画,需按字号调核尺寸。

几何矫正(工业落地最高频的预处理)

  • 倾斜矫正:Hough 直线检测找文本行主方向角 θ,再做旋转 x' = x·cosθ + y·sinθ
  • 透视矫正:检测文档四角/四边(或用文档边缘检测网络),求解单应矩阵 H,把倾斜/透视的页面拉正,[x', y', 1]ᵀ = H·[x, y, 1]ᵀ
  • 矫正无效时交给检测模型:PP-OCRv4 直接引入 4 点透视矫正模型(UDM 模块)端到端处理畸变文档。

质量增强

  • 对比度增强(CLAHE 限制对比度自适应直方图均衡)、锐化(Unsharp Mask)、去摩尔纹(扫描件高频条纹)、超分(SR 模型放大低分辨率文字)。
# OpenCV 快速预处理标准姿势
import cv2
def preprocess(img_path: str):
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    img = cv2.medianBlur(img, 3)                       # 去噪
    _, img = cv2.threshold(img, 0, 255,                # Otsu 二值化
                           cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    coords = cv2.findNonZero(img)                      # 文本区域包围盒
    x, y, w, h = cv2.boundingRect(coords)
    return img[y:y+h, x:x+w]                           # 裁掉空白边

实战提醒:深度学习检测/识别模型对"工业级预处理"的依赖比想象中小(数据增强里已经见过各种噪声),但倾斜矫正和透视矫正依然收益最大——这俩是模型在训练分布里最难"见全"的退化类型。

3.3 CTC Loss 详解

CTC(Connectionist Temporal Classification,Graves 2006 年提出,2015 年被 CRNN 带入 OCR)解决的是序列对齐问题:输入是一个长序列,输出是长度短很多的字符序列,而且我们不知道每个字符对应输入的哪些帧

为什么需要 CTC 而不是直接分类?
文本识别输入是"一行像素"(宽度 W 帧),标签是"一句话"(长度 L 个字符)。逐帧给标签做不到——字的宽度不一,一个字符可能横跨 5 帧,而空白帧没有标签。CTC 的思路是:允许网络每帧输出一个字符分布,引入一个 blank 符号(表示"当前帧没有字符"),然后用动态规划把所有可能的对齐路径加总,直接优化"最终文本"的概率

对齐规则(解码规则)
给定网络输出的帧级概率和一条路径 π(每帧一个符号,来自字符集 ∪ {blank}),映射到最终文本的规则是:

  1. 先合并相邻重复字符(如 hhheelllloohello);
  2. 再去掉 blank。
    例如 h_hello_ → 合并重复 → h_e_l_l_o_…实际例子:路径 h-e-l-l-oh-e-l-l-o(帧序不同但映射相同)都映射到 hello

前向-后向算法(Forward-Backward)
CTC 的目标是最大化所有映射到标签 l 的路径概率之和:

p(l | x) = Σ_{π ∈ B⁻¹(l)} p(π | x)

其中 p(π|x) = Πₜ y⁽ᵗ⁾_{πₜ}y⁽ᵗ⁾ 是第 t 帧的 softmax 输出。直接枚举所有路径是指数级的,所以引入带 blank 扩展的标签序列 l'(每个字符之间插 blank),用动态规划计算:

  • 前向变量 α(t, s):t 时刻状态 s 的前向概率,递推 α(t, s) = (α(t−1, s) + α(t−1, s−1) + (若允许跳过则 α(t−1, s−2))) · y⁽ᵗ⁾_{l'_s}(此处为科普级简化写法,状态转移的完整约束与推导以 Graves 原始论文为准);
  • 后向变量 β(t, s) 同理从尾部递推;
  • 最终 p(l|x) = α(T, S) + α(T, S−1)(结尾 blank 或最后字符两种状态)。

训练损失
CTC Loss 取负对数:

L_CTC = −ln p(l | x)

梯度通过前向-后向变量计算"每一帧每个符号的后验概率",即网络每一帧输出都会被"所有合法对齐路径"分摊——这就是 CTC 可以不标注字符边界、直接端到端训练的根本原因。

解码

  • 贪心解码(Greedy):每帧取 argmax,再合并重复、去 blank。快,但不全局最优;
  • 束搜索(Beam Search):维护 top-K 候选路径,路径概率相乘、按合并规则累计,可再接语言模型加权(score = log p_ctc + λ·log p_lm)。精度更高,是生产标配。

CTC 的优缺点

优点 缺点
无需字符级标注,弱监督对齐 假设帧间条件独立,忽略上下文建模(靠 BiLSTM 缓解)
解码 O(T) 线性,推理快 对长序列/重复字符(如 “llll”)建模压力大
可无缝接入任意 CNN 特征 相比 Attention 硬对齐,语言建模能力弱

面试常问一句话总结:CTC 用"加总所有合法对齐路径概率"的方式,让"不知道字符在哪些帧"的序列识别任务可以被端到端训练。—

4. 传统 OCR 方法

4.1 Tesseract OCR

Tesseract 是传统 OCR 的活化石和最知名代表:1985 年由 HP 实验室开发,2005 年开源,2006 年起由 Google 维护,v4.0 起换装 LSTM 引擎(基于 OCRopus 的 LSTM 架构)。它能识别 100+ 语言,支持繁体简体中文,文档生态极其成熟。

Tesseract 的技术内核(v4+)

  • 版面分析(OSD:orientation & script detection)→ 文本行切分 → LSTM 序列分类 → 词级语言模型确认;
  • 内部用"字符分类器 + 词典 + 模糊匹配"的三级确认机制(原 HP 架构),v4 后在像素层面换成 BiLSTM+CTC 思想;
  • 高度依赖预处理质量:对低对比度、复杂背景、弯曲文字、表格结构普遍表现差。

安装与使用

# Windows / Linux / macOS
pip install pytesseract
# 另需安装 tesseract 本体(apt install tesseract-ocr 或官方安装包),
# Windows 用户记得补 tesseract-ocr-chi-sim 中文语言包
import pytesseract
from PIL import Image

text = pytesseract.image_to_string(
    Image.open("scan.png"),
    lang="chi_sim+eng",          # 中英文混排
    config="--psm 6",            # 页面分割模式:6=单一文本块
)
print(text)

# 词级置信度
data = pytesseract.image_to_data(Image.open("scan.png"), lang="chi_sim")
for d in data.splitlines()[1:]:
    parts = d.split("\t")
    if len(parts) == 12 and parts[11].strip():
        print(parts[11], parts[10])   # text, conf

PSM(Page Segmentation Mode)速查--psm 3(默认:全自动)、6(单一均匀文本块)、7(单行文本)、8(单单词)、11(稀疏文本,适合杂点图)、13(原始行,配合自定义处理)。工业经验:拍文档用 6 或 11,印刷扫描书用 3,一行的票据用 7

Tesseract 的定位与局限

维度 评价
优点 免费开源、多语言、词典确认机制、生态老牌(PDF 内嵌 OCR 都用它)
局限 复杂版面/弯曲文本/低质量图精度差;中文大字符集表现一般;是"工具"不是"可训练管线",几乎无法拿自己数据微调
适用 干净印刷体扫描件批量转录、PDF 全文检索预处理、Demo 快速验证

面试/选型结论:Tesseract 是"最后一公里的轮子",不是"AI OCR 主线"。需要高精度、可迭代的工业 OCR,主流答案是 PaddleOCR 或自训 DBNet+SVTR/TrOCR——第 4、5、6 章就是这两条路线的地基。


5. 文本检测(Text Detection)

5.1 文本检测方法分类

文本检测的目标:在整张图上定位所有文字区域,输出文本框(轴对齐矩形 / 旋转框 RBOX / 任意四边形 QUAD / 曲线多边形)。

文本检测方法

传统方法

回归式深度学习

分割式深度学习

混合/Transformer 式

MSER 最大稳定极值区域

SWT 笔画宽度变换

滑动窗口 + 分类器

EAST: RBOX / QUAD 直接回归

TextBoxes: SSD 式 anchor

Rotated RPN: 旋转候选框

DBNet: 概率图 + 可微分阈值

PSENet: 渐进尺度扩张

PixelLink: 像素连接

DBNet++ / 融合注意力

基于 Transformer 的检测器

传统方法:MSER 找灰度极值稳定区域 + 几何规则过滤;SWT 假设文字笔画宽度近似恒定,做连通域聚类。速度尚可但对手写体、复杂背景、弯曲文字基本失效,现在只作基线或辅助。

回归式(Anchor/直接回归):EAST(2017)用全卷积直接回归每条文本行的旋转框或四边形(score map + geometry map),速度快,但对长文本、弯曲文本表现差(框不能贴合曲线)。

分割式(当前主力):把检测做成"像素级二分类"(是/不是文本),再对分割掩码做连通域后处理得到任意形状区域。代表 DBNet / PSENet / PixelLink。优点:天然支持任意形状文字——这是场景文字的刚需。

5.2 DBNet 详解

DBNet(Real-time Scene Text Detection with Differentiable Binarization,AAAI 2020,百度)是 2020 年以来工业界用得最多的分割式检测器,PaddleOCR 的检测默认就是 DBNet/DBNet++。它解决的核心矛盾:分割得到概率图后,传统二值化(固定阈值)不可微,导致"分割→二值→连通域"后处理割裂,训练和推理不一致

核心思想:可微分二值化(DB)

传统流程:分割概率图 P → 固定阈值 0.5 二值化 → 连通域取框。
DBNet:网络同时输出概率图 P阈值图 T,用可微的近似二值化函数合成二值图:

B̂ᵢⱼ = 1 / (1 + e^(−k·(Pᵢⱼ − Tᵢⱼ)))

其中 k 是放大因子(论文取 50,控制陡峭程度)。训练时阈值由网络自适应学出(谁该是背景谁该是文字),整条链路处处可导。

渲染错误: Mermaid 渲染失败: Parse error on line 6: ...值化
B = sigmoid k(P-T)] D2 --> E -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'

标签生成(收缩扩张)

  • 对每个文本多边形 G,用 Vatti clipping 算法按偏移量 D = A·(1 − r²)/L 收缩得到 G_s(r=0.4),G_s 内为概率图正样本;
  • 同样用偏移量 D 扩张得到 G_dG_sG_d 之间的环带作为阈值图监督区间(该区域内 T 被监督趋近 1,区域外趋近 0)。

损失函数
L = L_b + α·L_t + β·L_s(α = β = 10)

  • L_b:概率图与近似二值图的 Dice Loss(对 P 和 B̂ 各算一次);
  • L_t:阈值图的 L1 Loss(只在扩张环带内计算);
  • L_s:收缩掩码的 Dice Loss(空间监督,DBNet++ 新增,显式让 P 在 G_s 内部更"实")。

推理后处理

  1. 用固定阈值或直接判 P − T > 0 得到二值图(阈值化);
  2. 膨胀操作把收缩过的区域还原;
  3. 连通域分析(findContours + minAreaRect)得到文本框,可按面积/短边过滤噪点。

DBNet 的优势

  • 训练推理一致:DB 模块无缝嵌入训练,消除二值化断层;
  • :ResNet-18 backbone 上推理可达论文报告的 62 FPS+,且后处理简单;
  • 任意形状:分割天然贴合弯曲、倾斜文字;
  • 鲁棒:对低质量图、长文本行比回归式更稳。

5.3 文本检测方法对比

方法 类型 输出形式 速度 任意形状 代表特点
MSER 传统 轴对齐框 基线,复杂背景差
EAST 回归 RBOX/QUAD 有限 直接回归,长文本差
TextBoxes/ROTATE-RPN 回归+anchor 旋转框 类 SSD 思路
PixelLink 分割 任意多边形 像素+连接分类
PSENet 分割 任意多边形 中慢 渐进扩展,分行粘连稳
DBNet/DBNet++ 分割+可微二值化 任意多边形 工业默认首选
DB++ (Paddle) 分割+可微二值化 任意多边形 加空间监督+主干增强

选型结论:通用场景直接上 DBNet/DBNet++(PaddleOCR 内置),弯曲密集文本可试 PSENet,极速端侧可用精简版 EAST/DBNet-mobile。


6. 文本识别(Text Recognition)

6.1 文本识别方法分类

文本识别:输入"一行文字的裁剪图",输出字符串。核心难点是变长序列建模 + 字符对齐。三类主流路线:

文本识别方法

CTC 类
CNN + RNN + CTC

注意力类
Seq2Seq + Attention

Transformer 类
纯预训练范式

CRNN: VGG-like + BiLSTM + CTC

SVTR: 纯视觉 Transformer 变体
PP-OCRv3 识别主干

ASTER: 校正 + Attention

SAR: 1D/2D 注意力

TrOCR: Swin + RoBERTa

端到端: Donut / VLM

路线 代表 对齐方式 语言建模 推理速度 适用
CTC CRNN、SVTR 帧级隐性对齐 弱(BiLSTM 缓解) 生产主流、长文本稳
Attention ASTER、SAR 显式注意力注意力 较强 不规则/弯曲文本
Transformer TrOCR 自回归生成 最强 手写、复杂场景、领域微调

6.2 CRNN 详解

CRNN(An End-to-End Trainable Neural Network for Image-based Sequence Recognition,2015,Shi et al.)是 OCR 领域"焊死"了近十年的经典定式:CNN 提特征 + BiLSTM 建模序列 + CTC 对齐

输入图像
高固定 32 宽可变

CNN Backbone
7 层 VGG-like 卷积

特征图
512 x 1 x W'

特征序列
每列一个向量

BiLSTM x 2
hidden 256

每帧字符分布
softmax over 词典+blank

CTC 解码
贪心/束搜索

架构细节

  • CNN 特征提取:7 层卷积(结构类似 VGG 前段 + 第 3、4 个 maxpool 用 [1×2] 核,避免把宽度方向压太狠),输出 512 通道特征图;
  • 序列化:把特征图按列切分,每一列(1×512)作为序列的一个时间步,得到长度 W' 的特征序列——本质是"每一帧看图像的一竖条";
  • BiLSTM:2 层、hidden 256,双向建模上下文(字符间的语言依赖),输出 512 维(前向+后向拼接);
  • CTC 头:每帧过一个全连接 + softmax,输出"词典(如 37 类英文含 blank)+ 1"的分布,训练用 3.3 节的 CTC Loss,推理用 CTC 解码。

为什么用 BiLSTM 而不是纯 CNN?
CNN 的感受野有限且各列独立,而文字有强序列依赖(“q"后面常跟"u”)。BiLSTM 让每一帧都能"看到"整行的左右上下文,显著提升易混淆字符(0/O1/l/I5/S)的判别力。

优缺点

  • 优点:训练不需要字符边界、解码 O(T) 快、长文本行稳定,工程性好,PaddleOCR SVTR 之前的主力识别器;
  • 缺点:CTC 的帧独立假设限制了语言建模上限;对弯曲/透视文字需要额外校正模块(如薄板样条 TPS 校正)。
# 伪代码级别的 CRNN 训练骨架(思想示意)
import torch, torch.nn as nn

class CRNN(nn.Module):
    def __init__(self, num_classes):
        super().__init__()
        # 7 层 CNN -> 512 通道特征;此处省略 conv 层细节
        self.bilstm = nn.LSTM(512, 256, num_layers=2,
                              bidirectional=True, batch_first=True)
        self.fc = nn.Linear(512, num_classes)   # 每帧分类

    def forward(self, x):            # x: (B, 1, H, W)
        feats = self.cnn(x)          # (B, 512, 1, W')
        seq = feats.squeeze(2).permute(0, 2, 1)   # (B, W', 512)
        seq, _ = self.bilstm(seq)    # (B, W', 512)
        return self.fc(seq)          # (B, W', num_classes)

# torch.nn.CTCLoss(blank=0) 直接接上即可端到端训练

6.3 TrOCR 详解

TrOCR(Microsoft,ICCV 2021)把文本识别彻底搬上 Transformer:Swin Transformer 做视觉编码器 + RoBERTa 做文本解码器,不再依赖 CNN 和 CTC/Attention 混合架构。

文本行裁剪图

Swin Transformer
encoder 输出视觉 token

交叉注意力
decoder 逐 token 自回归

字符序列
hello world

交叉熵训练
teacher forcing

模型结构

  • Encoder:Swin Transformer(Swin-T/Swin-L),在 ImageNet-22K 预训练后初始化;
  • Decoder:RoBERTa(base/large),在文本语料预训练后初始化;
  • 输入:把文本行图切成 patch(4×4 等)做 patch embedding;输出:逐字符自回归生成,损失就是标准交叉熵(语言模型范式)。

三阶段训练(论文核心配方)

  1. (I→T):先在合成数据(S synthetically generated text images,如 MJSynth/Synth90k)上训练 encoder-decoder;
  2. (I+U→T):再用真实无标注图像做自监督(U,masked image modeling 让 Swin 学视觉)——TrOCR-large 用这一步提升泛化;
  3. (I→T) domain:最后在目标领域(手写、印刷、场景)微调。

TrOCR 的优势与代价

优势 代价
完全数据驱动,无需 RNN/CTC 对齐技巧 自回归解码慢(逐 token 生成),推理是 CTC 的数倍
预训练知识迁移强:手写识别(IAM)直接刷新 SOTA(当时) 需要海量数据和较长训练时间
语言建模能力天然强(RoBERTa 解码器) 上下文窗口限制长文本行(千字符级受限)

CRNN vs TrOCR 如何选(面试高频)

维度 CRNN TrOCR
架构 CNN+BiLSTM+CTC Swin + RoBERTa
训练数据需求 中等,合成数据即可 大,靠预训练+多阶段
推理速度 快(CTC 线性解码) 慢(自回归逐 token)
精度上限 中高(CTC 对齐损失) 高(强语言模型)
场景 工业通用、长文本、端侧 手写/复杂领域、离线高精度
中文支持 容易(改词典+数据) 需中文预训练权重支持

一句话:要快上 PaddleOCR 系(SVTR/CRNN),要准且不差算力上 TrOCR,两者可做级联或集成投票。

7. 端到端 OCR

7.1 端到端方法

两阶段(检测→识别)范式的问题:误差级联——检测框歪一点,识别器就吃哑巴亏;两个模型分别训练、分别部署,管线维护成本高。端到端 OCR 的目标是"一张图进,全文出",两种技术路线:

路线 A:检测+识别联合训练(One-Stage)

  • 代表:FOTS(2018,RoI-Rotate 把检测特征旋转对齐后直接复用给识别)、ABCNet(贝塞尔曲线框 + 轻量识别头);
  • 本质:共享 backbone,检测和识别共用特征,避免重复提取;
  • 优点:单模型、速度快、特征共享;缺点:仍需要显式框监督,弯曲文字的对齐损失难处理。

路线 B:直接序列生成(Vision → Sequence)

  • 代表:Donut、PaL(parse from pixels)、以及各类文档 VLM——完全抛弃检测/识别组件,Encoder 把整页图编码成视觉 token,Decoder 自回归输出结构化文本(XML/JSON/Markdown);
  • 优点:无误差级联、无 OCR 中间产物、天然支持结构化输出;
  • 缺点:对页级长图编码成本高、输出长度限制、可解释性弱。

7.2 Donut: 无 OCR 文档理解

Donut(Document Understanding Transformer,NAVER,ECCV 2022)是"路线 B"的里程碑:不依赖任何 OCR,直接"图→结构化文本"。名字是 document kNowledge Understanding Transformer 的缩写,对应甜甜圈——因为视觉 Transformer 的架构长得像糖霜面包圈。

整页文档图

Swin Transformer
Encoder

视觉 token 序列

BART 风格 Decoder
自回归

结构化 XML
例如发票字段

核心设计

  • Encoder:Swin Transformer(纯视觉 patch,无任何文字检测/OCR token);
  • Decoder:BART(facebook/bart-base 初始化或随机初始化),自回归生成目标序列;
  • 目标格式:任务相关的轻量 XML。例如发票解析(以下为演示样例数据,非真实票据):
    <s_doc>
      <s_company>百度智能云</s_company>
      <s_date>2026-08-25</s_date>
      <s_total>1,000,000</s_total>
    </s_doc>
    
    XML 结构同时承担"版面结构 + 键值语义",decoder 生成的每个配对 token 对应文档里的一个视觉区域;
  • 数据构造:用语义空间对齐做数据增强(SynthDoG:把真实文档的语义布局重新渲染成合成图),把"版面→文字"对错位问题消灭在数据层面。

Donut 的突破与代价

维度 说明
突破 彻底去 OCR:不依赖检测器/识别器/词表,避免误差级联;解码输出结构化 XML,文档分类、信息抽取、VQA 统一建模
精度 在当时 SROIE(发票 KIE)、CORD(收据)、DocVQA 上达到 SOTA 或接近两阶段方案
代价 长文档(多页/大图)编码开销大;输出序列长度受限;对细粒度表格单元格还原不如专用表格模型

Donut 的工业意义:它证明"文档理解可以不先做 OCR",为后来 PaL、文档 VLM(DocOwl 等)铺路。选型判断:字段相对规整的票据抽取(发票/收据)Donut 系足够,任意复杂表格还是得上 DBNet + 表格结构模型(第 10 章)。


8. 场景文字 OCR

8.1 场景文字挑战

场景文字(Scene Text)指自然图像里的文字:路牌、招牌、菜单、商品包装。与扫描文档相比,"敌人"全面升级:

挑战类型 具体表现 对检测/识别的影响
几何变形 透视(侧面看招牌)、弯曲(杯子/瓶子上的字)、任意旋转 轴对齐框失效,需 RBOX/多边形/曲线检测
图像退化 模糊(手抖/景深)、低分辨率、强反光、遮挡(树枝/行人) 特征丢失,识别置信度崩
背景干扰 复杂纹理(砖墙、树叶)、近似文字的图形 误检率飙升
版面无序 多行乱排、中英文混排、艺术字 文本行切分错误
特殊语言 中文书法体、日韩文、阿拉伯文连写 词典与字符集问题

8.2 场景文字检测方法

针对上述挑战,检测从"轴对齐框"全面进化到"任意形状框":

按标注形状分三档

  1. 旋转框(RBOX / oriented):EAST 输出 7 通道(score + 4 距离 + 1 角度),支持任意角度但仍是矩形——适合车牌、横幅;
  2. 四边形(QUAD):EAST 输出 8 通道(4 点坐标),贴合侧视文字;
  3. 曲线多边形(arbitrary polygon):PSENet、DBNet、CTPN(逐段框再连接,早期方案)——适合弯曲文字(圆形徽章、瓶身)。

检测数据与评估的对应

  • 检测数据集标注从 IC13/IC15 的轴对齐框 → Total-Text 的曲线多边形 → CTW1500 的 14 点多边形,这就是行业对"任意形状"需求不断加码的映射;
  • 评估从"框 IoU"升级为 DetEval(允许框组合匹配)、End-to-End 指标(检测+识别联合算)。

识别侧的应对(不规则文字)

  • 校正模块:ASTER 用薄板样条(TPS)把弯曲文字"拉直"再识别;MORAN 用矩形校正网络;
  • 2D 注意力:SAR 用 2D 注意力直接在有弯有扭的特征图上解码,不强制拉直;
  • 大模型兜底:TrOCR、Qwen-VL 等对不规则文字的鲁棒性显著强于 CRNN 系。

工业经验:场景文字是 OCR 里最难的一档,能用的工程策略按性价比排序:① 矫正(TPS/透视修正)→ ② 检测换 DBNet/PAN 曲线版 → ③ 识别换 SAR/TrOCR → ④ 加词典和置信过滤。别一上来就堆大模型,先扫清数据分布里的几何退化。


9. 文档版面分析(Document Layout Analysis)

9.1 版面分析任务

版面分析回答:"这一页纸上,哪些区域是标题/正文/表格/图片/页眉页脚?阅读顺序是什么?"它是从"OCR 转录"走向"文档理解"的枢纽:有了版面语义,RAG 才能按块切分、KIE 才知道去哪找字段。

整页图

版面区域检测
区域分类 + 定位

标题/小节

正文段落

表格区域 → 表格管线

图片/图表区域 → 图说/截图

页眉页脚/页码

按版面语义组织
阅读顺序 + 章节树

RAG 切块 / KIE / 文档搜索

版面分析的两个子任务

  1. 版面元素检测:定位(框) + 分类(标题/正文/表格/图/公式/页眉页脚),本质是目标检测/分割任务;
  2. 阅读顺序恢复:把检测到的区域按人类阅读顺序排序(Z 型/栏结构),决定后续文本拼接次序——RAG 切块质量直接受影响。

常用方法

  • 目标检测式:DETR、Faster R-CNN 检测版面框;
  • 分割式:U-Net 像素分类(PP-Structure 早期用);
  • 预训练范式:LayoutLM 系列(见 9.2);
  • 大模型辅助:OCR 全文 + 版面 token 一起喂给 LLM 组织章节(混合方案)。

9.2 LayoutLM 系列

LayoutLM 系列是"文档理解预训练"的开山与集大成(Microsoft),核心思想:文档不是纯文本,文本的 2D 位置和视觉外观本身就是语义("金额"通常在"合计"右下方)。三代演进回答了三个问题:

LayoutLMv3

LayoutLMv2

LayoutLMv1

文本 + 2D位置编码
Word embedding + x0y0x1y1

预训练: Masked Token
+ 文档分类

文本 + 位置 + 视觉
新增 ResNet 视觉 token

预训练: TIA 对齐
ITM 匹配 + WLM 词级

文本 + 视觉 Patch
统一 Transformer, 无 OCR

预训练: MLM + MIM
双模态遮蔽重建

LayoutLM v1(2019,KDD 2020)

  • 输入:BERT token + 2D 位置嵌入(x0,y0,x1,y1 归一化到 [0,1000])+ 段嵌入;
  • 预训练:Masked Visual-Language Model(盖住文本 token 预测原词)+ 文档多标签分类;
  • 意义:证明"layout 先验"让 FUNSD 表单理解等任务大幅超越纯文本 BERT。

LayoutLM v2(2020)

  • 输入:文本 + 2D 位置 + 视觉特征(CNN 对页面图提取视觉 token,投影后与文本 token 拼接进一个跨模态 Transformer);
  • 新增三个预训练任务:TIA(text-image alignment,判断文本 token 与视觉区域是否配对)、ITM(text-image matching,图文整体匹配)、WLM(word-level alignment,词级对齐)——强迫模型显式学习"文字和它对应的视觉区域"的关系;
  • 还需 OCR 提供文本与坐标(对 OCR 依赖依旧)。

LayoutLM v3(2022)

  • 彻底去 OCR:视觉侧直接做 patch embedding(类 ViT 分块),文本侧用 MLM;不再需要 OCR 提供的 token 坐标对,两条模态在同一个 Transformer 里融合;
  • 预训练:Masked Language Modeling + Masked Image Modeling(同时盖住部分文本 token 和部分图像 patch 重建);
  • 效果:FUNSD、CORD、RVL-CDIP 等全面 SOTA,且省掉 OCR 组件、管线更简单。

三代对比(面试必背)

维度 v1 v2 v3
输入模态 文本 + 位置 文本 + 位置 + 视觉 文本 patch + 视觉 patch
是否依赖 OCR 依赖 依赖 不依赖
视觉表征 ResNet 提取 ViT 式 patch
关键预训练 MVELM + 分类 TIA/ITM/WLM MLM + MIM
代表任务 FUNSD KIE FUNSD/CORD 全套 SOTA

工程落地:LayoutLMv3 全家桶(分类、token 分类做 KIE、问答)在 HF microsoft/layoutlmv3-base 可直接用,配合 pytesseract 自动 OCR 出框(apply_ocr=True,生产环境建议传入自有 OCR 的 words+boxes,见 19.3 关键说明),第 19 章有代码。


10. 表格理解(Table Understanding)

10.1 表格任务

表格是文档理解里"结构化程度最高、工业价值最硬"的部分。完整任务链:

子任务 输入 输出 难点
表格检测 整页图 表格区域框 无边框表格难定位
表格结构识别 表格区域图 行列网格、合并单元格、表头 跨行跨列、嵌套表头
表格内容抽取 结构 + OCR 单元格内文本 对齐错位、多行文本
表格问答/还原 结构化结果 HTML/Markdown/数据库行 阅读顺序、语义合并

为什么表格难:表格的信息在"位置关系"里——一个数字的语义完全取决于它在哪一行哪一列。丢失行列结构,表格就退化成文本串,RAG 检索这类表格基本是灾难。所以表格识别是"结构识别 + 文本识别 + 对齐"的复合问题。

10.2 表格识别方法

方法谱系

表格识别方法

传统启发式

图像分割式

端到端序列生成式

线条检测 + 格线交叉点

分割行列区域
例如 Table Transformer 检测行列线

图像转 HTML
TableMaster / GTE

结构感知解码
TEDS 评估

代表工作

  • TableBank(微软 2019):大数据集 + 两阶段(检测+结构),开山之作;
  • Table Transformer(微软 2021):DETR 直接检测表格、表头、行列分隔线,作者开源了 row/col 检测模型;
  • PubTabNet(IBM 2020):互联网 56.8 万张表格图 + HTML 标注,给出官方指标 TEDS(Tree Edit Distance based Similarity),行业事实标准;
  • TableMaster / GTE(百度 PP-Structure):端到端"表格图 → HTML 字符串",把表格结构建模为字符序列,再用树编辑距离评估;PP-Structure-SL 版本支持复杂合并单元格。

评估指标 TEDS 快速理解
TEDS(T_a, T_b) = 1 − TED(T_a, T_b) / max(|T_a|, |T_b|)
把表格解析成树结构(table → row → cell → span),计算两棵树的编辑距离归一化。值越接近 1 越好,传统 F1 只比框和文本,TEDS 连表格结构一起比,更严格。

工业落地姿势

  1. 检测表格区域(版面分析输出"表格"类)→ 2. 表格结构识别(GTE/TableMaster 输出 HTML)→ 3. 单元格内文字用文本识别填进去 → 4. 转 DataFrame/Markdown。PaddleOCR 的 PP-Structure 把这四步打包成一行 paddleocr --type structure(第 19 章见)。

11. 表单理解(Form Understanding)

11.1 表单任务

表单理解的核心是 KIE(Key Information Extraction,关键信息抽取):从票据/表单/证件里把"字段名 → 字段值"抽出来。发票上的开票日期(如 2026-08-25,示例数据)、红头文件的文号(如 国发〔2026〕1 号),就是 KIE 要的键值对。

KIE 的两种粒度

  • 字段级抽取(Field-level):把页面 token 分类成"键"“值”“无关”,再配对——值通常在键的右侧/下方;
  • 实体抽取(Entity-level):语义实体 + 实体间关系(如"公司→地址"),更接近信息抽取图谱。

方法演进

方法 思路 代表 局限
规则/模板 正则、位置模板、词典 自研脚本 布局一变全崩
序列标注 OCR 后 + CRF/BiLSTM Tesseract+CRF 不利用版面
图文布局预训练 LayoutLM 类 token 分类 LayoutLMv3、LiLT 依赖预训练权重
图神经网络 空间关系建模成图 SDMGR、PaFormer 关系构建复杂
端到端 图→XML 直接抽 Donut、PaL 长文档受限

PaFormer 简析(PP-Structure 的默认 KIE 方案,百度 2022)

  • 流程:OCR → 构建"文本行节点"图,边由位置/视觉关系(同行、同列、近邻)定义 → 图卷积建模局部结构 → 并行解码键值对(键预测 + 值预测联合优化);
  • 特点:不依赖 LayoutLM 预训练,从零训练一批数据也能出活,工业落地友好(如票据、证书)。

表单理解的关键工程点

  • OCR 质量是天花板:字段值抽错 90% 源于 OCR 错字而非 KIE 模型错配,先修 OCR;
  • 字段位置先验:同发票模板字段位置稳定,先用版面分析定位+模板对齐,再上模型,成本低十倍;
  • 盖章/条形码遮挡:多图融合(红外/反色图)或置信过滤;
  • 评估:键值 F1(键对且值对才算对)、字段级准确率。FUNSD(199 张表单,含链接标注)、SROIE(发票 4 字段)、CORD(收据 30 字段层次标注)是三个经典基准。

12. 关键模型详解

12.1 OCR 模型全景

把前 11 章的技术汇总成一张"军火库全景表",选型时对着抄:

模型/工具 类型 能力 开源权重 适用场景 备注
Tesseract 传统+OCR 工具 识别、版面粗略 干净印刷扫描、快速转录 不可微调
PaddleOCR (PP-OCRv4/v5) 全流程框架 检测+识别+版面+表格+KIE 工业通用首选 已迭代到 v5 版本,中英多语言完善
EasyOCR 识别工具 识别(检测内置) 轻量多语言 精度和速度均一般
MMOCR 研究工具箱 检测/识别/KIE 全家桶 研究与复现、对比实验 OpenMMLab 生态
DBNet/DBNet++ 检测器 任意形状文本检测 检测主线 PaddleOCR 内置
PSENet 检测器 密集/任意形状检测 粘连文本、含笔画交织 速度略慢
EAST 检测器 旋转/四边形检测 端侧轻量检测 长文本弱
CRNN 识别器 行文本识别 CTC 老将、长文本稳定 精度上限中高
SVTR 识别器 视觉 Transformer 识别 PP-OCRv3 识别主干 大模型精度高
ASTER / SAR 识别器 不规则文字识别 弯曲透视文字 含校正/2D 注意力
TrOCR 识别器 手写/复杂场景识别 离线高精度 推理慢
Donut 端到端 图→XML 结构化 票据 KIE、文档分类 无 OCR
Table Transformer 表格 表格/行列检测 表格结构识别 DETR 系
TableMaster / GTE 表格 表格图→HTML 表格还原 PP-Structure 内置
LayoutLM v1/v2/v3 文档理解 分类/KIE/QA 版面+语义融合 v3 无需 OCR
PaFormer KIE 键值对抽取 票据关键字段 图卷积+并行解码
文档 VLM (Qwen-VL/GPT-4V 等) 多模态大模型 读图问答/抽取 部分 泛化理解、复杂版面 贵、可控性弱

选型口诀

  • 要出活快、全流程:PaddleOCR(含 PP-Structure 结构化);
  • 要研究基线、对比实验:MMOCR;
  • 要手写/难样本高精度:DBNet + TrOCR(或 SAR);
  • 要票据 KIE:OCR 后接 PaFormer/LayoutLMv3 token 分类;
  • 要表格:DBNet + TableMaster/GTE;
  • 要端到端省事:Donut 或文档 VLM。—

13. 数据集与基准测试

数据是 OCR 的命脉。按任务分三类记,面试能报出规模和特点就赢一半。

13.1 文本检测数据集

数据集 规模/标注 特点 用途
ICDAR 2013 462 图,词级框 清晰印刷/场景 入门基准
ICDAR 2015 1500 图,四边形框 Incidental 场景(手机随手拍,模糊、歪) 场景检测最常用基准
ICDAR 2017 MLT 多语言 9 语种 检测+识别多语言联合 多语言评测
Total-Text 1555 图,曲线多边形 弯曲文本(圆形/弧形) 任意形状检测
CTW1500 1500 图,14 点曲线多边形 曲线+长文本 任意形状检测
SynthText / 合成数据 数百万元素级标注 程序合成(合成字体+场景贴图) 预训练/弱监督主力

工业技巧:真实数据不够时,SynthText 合成打底 + 真实数据微调是标配组合。

13.2 文本识别数据集

数据集 规模 说明
MJSynth (MJ) 890 万合成图 90k 英文单词渲染,谷歌合成
Synth90k 900 万合成图 51k 单词,合成标准
IIIT5K 3000 测试图 招牌/街景,词级
SVT / SVTP 647 / 645 街景 + 透视(SVTP 专测透视)
ICDAR 2003/2013/2015 867 / 1015 / 2077 IC15 最难:低分辨率+弯曲
CUTE80 288 曲线词 专测曲线文字
IAM 手写英文 1 万多行 手写识别基准
CASIA-HWDB 手写中文字符 中文手写(脱机/联机)

通常训练策略:MJ+Synth 合成预训练 → 真实数据集微调(IIIT/SVT/IC/Total 混合)→ 目标领域继续微调。

13.3 文档理解数据集

数据集 任务 规模/标注 说明
RVL-CDIP 文档分类 40 万页,16 类(letter/form/email/invoice…) 分类基准之王
FUNSD 表单 KIE 199 张表单、9707 语义实体、链接标注 表单理解主力
SROIE 发票 KIE 1000 张发票(646 训练),4 字段 结构化抽取经典
CORD 收据 KIE 1000 张韩语收据,30 字段 50 子类 细粒度层次抽取
PubTabNet 表格结构 56.8 万表格图 + HTML 表格识别事实标准,TEDS 评估
TableBank 表格检测+结构 41.7 万页面-表格对 表检/表结构训练
DocBank 版面分析 50 万页面,Token 级版面标签 版面预训练
DocLayNet 版面分析 80863 页,11 类 PDF 版面 IBM 高质量人工标注
DocVQA 文档问答 5 万页 + 5 万问答对 文档视觉问答基准

14. 训练策略与技巧

14.1 数据增强

OCR 的数据增强是针对"图像退化 + 文本形态"两个敌人打的:

几何类

  • 随机旋转(±10°)、透视变换、裁剪缩放、随机长宽比拉伸——模拟拍照;
  • 弹性变换/网格扭曲(thin-plate spline 随机变形)——模拟纸张褶皱、弯曲文字;
  • 拼贴/复制粘贴:把文字行随机贴到复杂背景(合成数据),大幅提升场景鲁棒性。

退化类

  • 高斯/运动模糊、高斯/椒盐噪声、亮度对比度扰动、JPEG 压缩伪影、摩尔纹模拟;
  • 光照不均(渐变暗角);暗角 + 反光光斑。

形态类

  • 笔画腐蚀/膨胀(thin/thicken),模拟低打印质量;
  • 字符级替换(把词表里的字替换成形近字)——提升易混淆字符判别。

序列级

  • 识别任务做"字级插入/删除"组合?NO——识别增强一般不破坏字序,而是用上下文无关的裁行:随机保留行内片段。

工程经验:增强强度要跟推理场景对齐——你线上收的是手机照片,训练就别只喂干净扫描件。推荐先做一次"线下增强消融",找出对指标贡献最大的 3 个增强(通常:透视、模糊、噪声保底)。

14.2 训练策略

两阶段训练(合成 → 真实)
合成数据量大但分布偏(字体正、背景净);真实数据量小但分布准。先合成粗训(学特征),再真实精调(学分布),必要时再加第三段领域微调(如发票专属权重)。

检测训练要点

  • 损失平衡:DBNet 的 L_b + L_t + L_s 权重 α=β=10 是保守起点,正负样本失衡严重时上 OHEM/焦点损失;
  • 多尺度训练:输入尺度 640/736/960 随机,长边限制,提升多字号鲁棒性;
  • 难例挖掘:文本密集区域(F-score 低的样本)加权重采样。

识别训练要点

  • 字符集与形状:固定输入高度(如 32)、动态宽度;W=4T 经验(目标序列长 T 时宽设 4T);
  • 定长 vs 不定长:CTC/Attention 用不定长,裁剪图可整行直出;
  • 词典先验:训练中给损失加词典 scale log p + λ·log p_dict(词表重打分),中文场景改为"字形近度引导";
  • EMA(指数滑动平均)稳训练、混合精度(AMP)省一半显存、warmup + cosine lr 是标配。

蒸馏与模型缩放

  • 大模型(TrOCR-large/SVTR-L)蒸馏到小模型(CRNN-mobile):软标签(教师 logits)+ 硬标签混合;
  • PP-OCR 系列就是"大模型炼丹 → 蒸馏出 tiny 模型"的工业化范本:PP-OCRv4 用 SVTR 大模型蒸馏出 22 个文件的小检测/识别模型(每方向 22MB 级)。

防过拟合提醒:识别做"字符集外字"处理——测试时遇到训练集没有的字,模型会瞎猜,生产务必做 OOV 兜底(词典校验、置信度拦截、人工复审)。


15. 后处理技术

后处理是成本最低、收益最直接的精度提升手段,工业 OCR 必须做:

15.1 文本后处理

解码层

  • CTC 贪心 → 束搜索(beam width 5-10,可挂语言模型);
  • 字典约束解码:候选词逐帧对齐打分(如 Viterbi 过词典),把"芝加歌"修正成"芝加哥"(词典法),英文效果尤佳;
  • 拼音/字形层级纠错:适合中文(“英枚"→"英镑”),需接语言模型或规则词表。

结构层

  • 置信度过滤rec_score < 阈值(如 0.6)的文本行标记为"低置信",输出时带 flag 供下游人工审核/重识别;
  • 去重与顺序:按版面阅读顺序合并文本行(先列后行、跳过页眉页脚);
  • 标点与空白归一化:全角→半角(可配置,中文文档通常保留全角)、去除多余空格、句读修正。

语义层

  • 单位/金额后处理:1,000,001,000,000(逗号位校验);RMB1o0RMB100(形近字符表 0/O、1/l/I、2/Z、5/S、8/B);
  • 上下文强校验:日期合法性、身份证校验位、税号格式、银行卡 Luhn 校验——这类"领域规则后处理"常常把字段级 KIE 精度拉高 2-5 个点。
# 形近字纠错的最小实现示意
corrections = {"0": "O", "l": "1", "I": "1", "B": "8", "S": "5", "Z": "2"}
def sanify(text: str, valid_chars: set):
    out = []
    for ch in text:
        if ch in valid_chars:
            out.append(ch)
        elif ch in corrections:          # 映射回合法字符
            out.append(corrections[ch])
        else:                             # 其余置低置信
            return None
    return "".join(out)

一句话:后处理 = 词典约束 + 置信过滤 + 领域规则,把它当成管线里的"第七个环节",不是可有可无的装饰。


16. 多语言与多模态 OCR

16.1 多语言 OCR

为什么多语言难

语言类型 难点 代表
拉丁系 字符少(26+),好办 英、法、西
大字符集 常用汉字 3000+,全量 2 万+,生僻字/异体字 中文、日文(汉字)
复合字符 元音附标、变音符号堆叠 梵文、泰文、越南文
连写/变体 字母按位置变形 阿拉伯文、波斯文
竖排/混排 竖排中文、日文,中英混排 古籍、日文文档

实践方案

  • 字符集与子词:拉丁系用字符级;中文用 6000+ 常用字库 + 生僻字兜底;多语言建议"字符级 + 语言标识"联合建模,避免子词切分破坏字形;
  • PaddleOCR 多语言:开箱支持 80+ 语言,中英文混排检测识别都稳,多语言场景首选;
  • Tesseract 多语言:100+ 语言包,但大字符集精度有限,适合简单转录;
  • TrOCR/LayoutLM 多语言:需对应语言预训练权重(中文权重稀缺,中文场景仍以 PaddleOCR/SVTR 中文模型更实用);
  • 合成多语言数据:用真实多语言文本渲染合成图(MDAR 等)是补数据最快路径。

16.2 多模态文档理解

文档 = 文本 + 布局 + 视觉(图、印章、手绘、签名)+ 表格。单一模态都吃不满,多模态融合是文档理解的终点形态:

融合路线一:预训练特征融合(LayoutLM 系)
文本 token(语义)+ 2D 位置(布局)+ 视觉 patch(外观)三个流在 Transformer 里融合(第 9.2 节已详细展开)。

融合路线二:文档 VLM(多模态大模型)

  • 代表:GPT-4V、Qwen-VL、InternVL、mPLUG-DocOwl、ReadAgent 等;
  • 做法:整页图编码成视觉 token,LLM 直接问答/抽取/推理;
  • 优势:零样本泛化强、能"理解"而非"模板匹配"、可自然语言交互(“第三列数字加起来”);
  • 劣势:价格高、延迟高、幻觉(字段值编造)、端侧跑不动、表格细粒度还原不稳;
  • 工程定位:大模型做"复杂版面理解、文档问答、难样本兜底",小模型(DBNet+PaddleOCR+LayoutLMv3)做"批量结构化管线",两层级联是目前性价比最高的架构。

多模态文档理解的核心课题:对齐(文字 token 和图像区域对齐)、解耦(把纯版面形状与语义内容分开建模)、长文档(多页上下文压缩)。这三点分别对应 LayoutLM 的 TIA、PaLi 的 patch-aligned 输入、以及 RAG 式文档切片。


17. 推理优化与部署

17.1 优化技术

OCR 管线落地的第一道坎是延迟和成本。按收益排序:

技术 手段 收益 代价
ONNX/TensorRT 导出 静态图优化、算子融合 1.5-3x 加速 显存/算子兼容性
INT8 量化 权重/激活量化(PTQ/QAT) 体积减 4 倍、延迟降 30-50% 精度损失 0.5-2%(需校准集复查)
模型蒸馏 大模型教小模型 体积降 10 倍级 训练成本
轻量 Backbone MobileNetV3/PPLCNet 检测识别一体化小模型 精度上限降低
检测识别合并 共享 backbone 单模型 省一倍前向 精度/灵活性折中
批处理 GPU 动态 batching、CUDA Graph 吞吐翻倍 显存
多线程/内存池 TBB、自定义内存池 CPU 延迟优化 工程复杂度

实测要点

  • 检测、识别分开量化和测试,通常识别对量化更敏感;
  • 中文大字符集下 softmax 层尽量保持 FP16/FP32(词典 6000+ 时 INT8 全量化精度掉得多);
  • PaddleOCR 官方提供 --export 导出 ONNX 的完整链路,PP-OCRv4/v5 的 mobile 模型已为端侧优化。

17.2 部署架构

低置信回流

修正样本

新权重

上游业务
票据/合同/工单

接入层
FastAPI / gRPC

预处理服务
矫正/增强

OCR 服务
DBNet 检测 + SVTR 识别

结构化服务
版面/表格/KIE

落库 / RAG / 报表

人工审核台

增量训练闭环

两种典型拓扑

  1. 单体服务:PaddleOCR 全流程装进一个 FastAPI 服务。适合内部工具、日均几万张:简单、易维护,横向加实例即可;
  2. 流水线微服务:预处理 / 检测 / 识别 / 结构化拆成独立服务(可选队列 Kafka)。适合日均百万级、多业务共享 OCR 中台:各环节独立扩容、独立版本迭代(识别模型升级不影响检测)、按租户配额。

部署规格参考

  • CPU 端:PaddleOCR mobile 模型,单张 A4 扫描件约 200-500ms(8 核),足够大多数内部场景;
  • GPU(推理):T4/A10 上加批处理可到 50-100 张/秒,成本敏感可上 INT8;
  • 端侧:Tiny 模型 + NCNN/MNN/TFLite 量化,手机/摄像头盒子 30-100ms/帧;
  • 高可用:超时重试、容量预估(业务峰值 5x 冗余)、模型灰度发布 + 一键回滚。

SLA 与质量护栏

  • 记录全链路指标:检测 P/R、识别置信分布、表格 TEDS、KIE F1;
  • 低置信文本行自动进人工审核队列——AI 负责 95% 的简单单,人复核 5% 的疑难单,这是文档理解工业落地的黄金比例。

18. 应用场景与工业落地

18.1 应用场景

行业 场景 用到的能力 坑点
财务 发票验真、报销单自动填报 检测+识别+KIE 电子发票版式多、盖章遮挡
银行/保险 证件识别、贷款材料审核 证件方向矫正+KIE+防伪 隐私合规、复印件质量
物流/零售 面单识别、票据匹配 条码+OCR 混排 热敏纸褪色、粘连
医疗 病历/化验单结构化 手写识别+版面 手写是最大难点
法律/政务 合同比对、红头文件归档 版面+RAG 长文档、多栏阅读顺序
教育 作业批改、题库录入 公式 OCR、表格 公式符号集
搜索/知识库 PDF 全文检索、RAG 文档解析 版面+阅读顺序 切块不能断句
交通/安防 车牌、路牌、快递柜 场景文字检测识别 恶劣天气光照

18.2 工业部署考虑

准确率与召回的业务口径

  • 识别的"字准确率"和业务的"字段准确率"是两回事:字段正确率 = 键对 × 值对,常常比字准确率低几个点,立项时的验收标准要定在业务口径上;
  • 低置信拒绝(拒绝率 5% 内)是保精度的常规手段:宁可判"不确定"进人工,不硬给错误答案。

数据与合规

  • 发票/证件/病历是敏感数据:私有化部署、不出域、脱敏日志;
  • 人工复核数据回流训练要合规授权;
  • 扫描图像本身可能含个人信息,数据标注外包需脱敏再发。

成本模型

  • OCR 是"算力换人力"的经典业务:单张成本(GPU 分摊后)经常远低于人工录入,但要注意疑难单人工复核成本通常占总成本 20-40%,别漏算;
  • 中小流量先用 PaddleOCR CPU 部署,不要一上来就上 GPU 集群——OCR 的 ROI 曲线在百万张/月级别才开始显著依赖 GPU 批处理优化。

一个可复用的落地清单

  1. 口径先行:字准确率 / 字段准确率 / 拒绝率 三指标定死验收线;
  2. 数据先行:收集目标真实样本 1000+,做一次错误分析(error analysis),先修"占比最高的一类错";
  3. 管线骨架:PaddleOCR 全流程跑通基线,再逐环节微调;
  4. 结构化层:版面 → 表格 → KIE 按业务字段优先级逐级上;
  5. 质量护栏:置信过滤 + 人工复核台 + 回流数据停不下来的闭环。

19. 代码实战

三个主流开源栈,从"一行命令"到"二次开发",直接能跑。

19.1 PaddleOCR 使用

PaddleOCR(百度)是当前中文场景最完整、最省心的 OCR 框架,检测、识别、方向分类、版面、表格、KIE 一条龙。

# 1. 安装(CPU 版)
pip install paddlepaddle paddleocr
# GPU 版:pip install paddlepaddle-gpu

CLI 一行出结果

# 中英文文本行检测+识别(含方向分类)
paddleocr --image_dir invoice.png --use_angle_cls true --lang ch
# 结构化解析(版面 + 表格识别 + KIE)
paddleocr --image_dir receipt.png --type structure --lang ch

Python API(2.x 风格,3.x 改为 ocr.predict 返回 dict)

from paddleocr import PaddleOCR

ocr = PaddleOCR(use_angle_cls=True, lang="ch")   # 自动下载权重
result = ocr.ocr("invoice.png", cls=True)

for line in result[0]:
    box, (text, conf) = line[0], line[1]
    print(f"置信度 {conf:.2f} | 文本: {text}")
    print(f"坐标: {box}")

PP-Structure 结构化(表格 + KIE)

from paddleocr import PPStructure

engine = PPStructure(lang="ch")
res = engine("table_page.png")          # 返回版面元素列表
for item in res:
    print(item["type"], item["res"])    # type: text/table/figure...
    if item["type"] == "table":
        print(item["res"]["html"])      # 表格还原为 HTML
        print(item["res"]["cell"], item["res"]["caption"])

版本提示:PaddleOCR 3.x 起 API 升级为 ocr.predict()(返回 rec_texts / rec_boxes / rec_scores 等字段),2.x 的 ocr.ocr() 仍可用但已废弃。PaddleOCR 已迭代到 v5 版本,模型下载、版本号与 API 用法均以官方 GitHub 文档为准,动手前先对照核对。

19.2 TrOCR 使用

HuggingFace 一行加载,适合手写/英文场景高精度识别:

from transformers import TrOCRProcessor, VisionEncoderDecoderModel
from PIL import Image

image = Image.open("handwritten_note.png").convert("RGB")

processor = TrOCRProcessor.from_pretrained("microsoft/trocr-base-handwritten")
model = VisionEncoderDecoderModel.from_pretrained(
    "microsoft/trocr-base-handwritten"
)

pixel_values = processor(images=image, return_tensors="pt").pixel_values
generated_ids = model.generate(pixel_values, max_new_tokens=64)
text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(text)
  • 换权重即可换任务:trocr-base-printed(印刷体,英文为主)、trocr-base-handwritten(手写)、trocr-large-*(更准更慢);
  • 中文:暂无官方中文权重,中文高精度场景建议用 PaddleOCR 中文模型,或自行在中文合成数据上微调(成本 1-2 张卡 × 数天)。

微调 TrOCR 的最小骨架

from transformers import (
    TrOCRProcessor, VisionEncoderDecoderModel, Seq2SeqTrainer,
    Seq2SeqTrainingArguments,
)

model = VisionEncoderDecoderModel.from_pretrained("microsoft/trocr-base-printed")
model.config.decoder_start_token_id = processor.tokenizer.eos_token_id
model.config.pad_token_id = processor.tokenizer.pad_token_id

args = Seq2SeqTrainingArguments(
    output_dir="./trocr-finetuned",
    per_device_train_batch_size=8,
    num_train_epochs=3,
    predict_with_generate=True,
    save_strategy="epoch",
)
trainer = Seq2SeqTrainer(model=model, args=args, train_dataset=dataset)
trainer.train()

19.3 LayoutLMv3 文档分类

文档理解全家桶(分类 / KIE / QA)直接用 LayoutLMv3:

from transformers import (
    AutoProcessor,
    AutoModelForSequenceClassification,
)
from PIL import Image

# 加载处理器(apply_ocr=True 时自动用 pytesseract 提取词框)
# 注意:需提前安装 tesseract 与 pytesseract,并下载中文语言包
processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=True)
model = AutoModelForSequenceClassification.from_pretrained(
    "microsoft/layoutlmv3-base", num_labels=16
)

image = Image.open("document.png").convert("RGB")
encoding = processor(image, return_tensors="pt")
outputs = model(**encoding)
pred = outputs.logits.argmax(-1).item()
print(f"预测类别: {pred}")   # 0-15 对应 RVL-CDIP 16 类

关键说明

  • apply_ocr=True 会调用 pytesseract,Windows 需在 PATH 里装好 tesseract.exe,否则报错;生产环境不建议依赖内置 apply_ocr,建议传入自有 OCR 管线输出的 words + boxes,以便与整体 OCR 质量、语言支持保持一致
    encoding = processor(
        image, words=["合同", ...], boxes=[[0, 0, 100, 50], ...],
        return_tensors="pt",
    )
    
  • 分类权重训练在 RVL-CDIP(16 类文档)上,直接可用于版本文档分类;KIE 用 LayoutLMv3ForTokenClassification + FUNSD/CORD 微调数据;
  • 中文:可用 microsoft/layoutlmv3-base 自行在中文数据集微调,或找社区中文权重。

20. 面试高频问题

按"基础概念 / 模型架构 / 工程实践"三档,把最容易被考到的点整理成速查:

20.1 基础概念

Q1:OCR 和文档理解是什么关系?
OCR 是把图像文字转录成文本(检测+识别);文档理解是在转录之上做结构化与语义化(版面、表格、表单 KIE、问答)。文档理解依赖 OCR,但目标更高——“看懂"而非"读到”。

Q2:CTC Loss 解决什么问题?核心机制是什么?
解决"变长序列对不确定"的对齐问题(不知道每个字符落在哪些帧)。机制:引入 blank,加总所有可映射到目标文本的路径概率(前向-后向动态规划),直接优化文本级概率,无需字符级标注。

Q3:CTC 的解码规则是什么?
先合并相邻重复字符,再去 blank(hheello_hello)。

Q4:二值化和倾斜矫正有什么常见方案?
Otsu 最大类间方差、局部自适应阈值(Niblack/Sauvola);Hough 直线检测定角度旋转、透视变换(单应矩阵)拉正文档。

Q5:检测和识别分别输出什么?用什么评估?
检测输出文本框(框/多边形)+ 置信度,用 IoU/P/R/F1(DetEval 更严格);识别输出字符串,用词级/字符级准确率、编辑距离。

20.2 模型架构

Q6:DBNet 的核心创新是什么?
可微分二值化:同时输出概率图 P 和阈值图 T,用 B̂ = sigmoid(k(P−T)) 合成近似二值图,让"二值化"可微,训练与推理一致,并自适应区分文字/背景。

Q7:为什么 CRNN 要 CNN + BiLSTM + CTC 三件套?
CNN 提视觉特征(把像素变特征序列);BiLSTM 建模文字序列依赖(左右上下文,利于易混字符);CTC 解决帧级对齐,端到端可训。三者各司其职。

Q8:CRNN 和 TrOCR 怎么选?
CRNN:快、无需大预训练、长文本稳,工业默认;TrOCR:变压器自带强语言模型、手写/难样本精度高,但自回归慢、需大数据和预训练权重。

Q9:LayoutLM v1/v2/v3 的演进主线?
v1 加 2D 位置预训练;v2 加视觉模态+图文对齐预训练(仍依赖 OCR);v3 去 OCR、patch 化双模态遮蔽重建——演进主线是"多模态更全 + 对 OCR 依赖更少"。

Q10:Donut 为什么能"无 OCR"?
整页图经 Swin 编码成视觉 token,BART 解码器直接自回归输出任务相关 XML,文字识别与结构化隐含在端到端解码里,所以不需要显式检测器/识别器。

Q11:端到端 OCR 与两阶段相比优劣势?
优:无误差级联、单模型快、出结构化;劣:长文档/长输出受限、可控性和可解释性弱、对检测框级错误不可独立修。

Q12:表格识别为什么用 TEDS 评估?
表格是结构化树(表格→行→单元格→跨列),普通文本 F1 比不出结构错误;TEDS 对解析树做编辑距离归一化,结构与内容一起比。

20.3 工程实践

Q13:识别置信度低怎么处理?
分层:低置信重识别(尺度放大/方向重判)→ 词典约束纠错 → 仍低则标记"不确定"入人工审核队列。不硬给答案。

Q14:训练数据不够怎么办?
合成数据打底(SynthText/MJSynth/自渲染)+ 真实数据微调;数据增强(透视、模糊、噪声);难例挖掘;模型蒸馏用大模型补标注(self-training)。

Q15:怎么判断是检测的问题还是识别的问题?
错误分析:把检测框可视化,看"框错"(漏检/误检/框歪)和"框对但字错"分别占比。框错骂检测、字错骂识别,取样 100 张就能定位主矛盾。

Q16:多语言/中文 OCR 的坑?
中文:大字符集(6000+ 常用)、生僻字、竖排、中英混排;方案:字符级建模 + 语言标识、PaddleOCR 中英模型(默认最强)、合成多语言数据补充。

Q17:OCR 服务高吞吐怎么优化?
轻量模型 + ONNX/TensorRT + INT8 量化 + 动态批处理;检测识别拆流水线并行;低峰期模型预热;必要时 GPU。

Q18:RAG 里文档解析为什么要做版面分析?
不做版面时 PDF 文本流可能乱序(多栏、页眉页脚混入正文),切块会断句、语义碎片化;版面分析恢复阅读顺序后按标题/段落切块,检索质量才稳。

Q19:如何评估整套 KIE 系统?
业务口径为主:键值对 F1(键对 + 值对)、字段级准确率、拒绝率(低置信率)、人工复核成本/时间。技术指标(字准确率/TEDS)只作辅助定位用。

Q20:新业务上线 OCR 的路径?
基线跑通(PaddleOCR 全家桶)→ 错误分析定位主错 → 针对性数据采集+微调 → 结构化层按字段优先级上 → 置信过滤+人工审核闭环 → 灰度上线+SLA 监控。50% 时间花在数据上,模型反而是最不花时间的部分。


结语

OCR 与文档理解这条链路,从 1929 年的机械模板到 1980 年代的 CNN,再到 2015 年 CRNN+CTC 定式、2019 年 DBNet 和 LayoutLM、2021 年 TrOCR、2022 年 Donut 端到端,技术演进的主线只有一条:把"让机器读图"这件事里的每一环,从手工规则逐步替换成可学习、可微、可端到端的模型

对你现在的启示可以落成三句话:

  1. 先跑通再讲精度:PaddleOCR 一行命令出全流程基线,错误分析定位主矛盾,别一上来就调参炼丹;
  2. 结构化才是价值:纯 OCR 只是转录,版面 + 表格 + KIE 才是把文档变成"可检索、可计算、可对话"资产的关键(RAG 好不好用,一半取决于文档解析做没做好);
  3. 大小模型分层:小模型批量处理(便宜、快、可控),大模型(VLM)做难样本兜底与自然语言问答——两层级联是当下工业界性价比很高的文档理解架构。

从今天起,你的 AI 不再是"瞎子的知识库"——它能看见发票上的金额、读懂合同里的条款、把一页烂 PDF 变成干净的数据库行。这就是 OCR 与文档理解的价值:赋予 AI 阅读能力

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐