VL 与 OCR 的分界
OCR 是把图里的字抠出来,VL 是看懂这张图在说什么。一句话能讲完,但决定选型的不是这句话 —— 是它们把不确定性放在哪里:OCR 把它写进输出,VL 不确定的时候和确定的时候长得一模一样。
一个是测量仪器,一个是会读图的读者
这个比喻不是修辞,后面所有差异都能从它推出来。
测量仪器(OCR)
你把纸放进去,它告诉你「这个位置有这几个字符,我有多确定」。它不理解内容,但每一次输出都带刻度、可复现、可校准。
它也会读错 —— 高置信度的误识确实存在。但误差有分布、能统计、能对着标注集标定出来。
读图的读者(VL)
你把纸给它,再问一句话,它用自己的话回答你。它理解内容,能说出图表趋势、印章位置、这张单据是什么。
但读者看花了眼的时候,说出来的语气和看清楚时完全一样,而且没有一个数字告诉你这次该不该信。
所以「VL 比 OCR 先进」是个会误导人的说法。它们不在一条进化线上 —— 一个在给你带误差刻度的测量值,一个在给你没有误差刻度的理解。前者能进账,后者能解释账。
它们本来就不是同一类东西
经典 OCR 是为「找字、认字」定制的 CV 流水线,每一级有确定的输入输出;VL 把图编码成 token 塞进语言模型,和提示词一起解码。差别从第二步就分岔了。
两种「看见」,拿到手的是不同的东西
下面是同一张增值税发票分别交给两边的结果。差别不在谁认得准,而在产物的形状。
输出
[
{"text":"价税合计",
"bbox":[26,136,80,151], "conf":0.991},
{"text":"¥12,840.00",
"bbox":[208,135,282,152], "conf":0.971},
{"text":"2026-03-14",
"bbox":[268,28,330,41], "conf":0.988}
]
拿到的是字和它在哪。但「价税合计」和「¥12,840.00」是不是一对,OCR 并不知道 —— 那要靠坐标邻近规则或版式模板去拼,换一种票样就得重写一遍。
提示词
提取开票方、价税合计、开票日期, 返回 JSON。
输出
{
"seller": "示例科技有限公司",
"total_incl_tax": 12840.00,
"invoice_date": "2026-03-14"
}
拿到的直接是字段。换一种票样不用改代码,改提示词就行 —— 但没有坐标可回溯,而 12840.00 是生成出来的,它不会告诉你自己在哪一位上没把握。
只有一行是真正的分水岭
加粗那一行决定架构,其余各行多半只是它的推论。
| 维度 | OCR | VL |
|---|---|---|
| 本质 | 检测 + 识别的专用流水线 | 图像编码器 → 语言模型,通用理解 |
| 输入 | 图 | 图 + 提示词 |
| 输出 | 文本 + bbox + 置信度,结构固定 | 任意:摘要、JSON、问答、翻译 |
| 不确定性在哪 | 写在输出里 —— 每项带 conf,可设阈值拦截、可统计(高置信度误识仍会发生,但有分布可标定) | 不在输出里 —— 错的和对的同样流畅,没有一个数字告诉你该不该信这一次 |
| 非文字内容 | 识别引擎本身只出文字;版面、表格、印章要另接模块(多数商用文档方案已经打包了这些) | 能描述、能推理,不用另接 |
| 确定性 | 高,同图基本同结果 | 会飘,受措辞与采样影响 |
| 坐标 | 像素级精确,是原生产物 | 部分模型原生支持,精度与稳定性普遍弱于检测框 |
| 适配新版式 | 改规则 / 加模板 / 重训 | 改提示词 |
| 延迟量级 | 毫秒级 | 秒级 |
| 成本量级 | 按页计,很低 | 按 token 计,高出若干数量级 |
延迟与成本为量级对比,随实现、图幅、模型规模变动很大,不构成任何具体服务的基准。
真正会改变你架构的四条
上表多数行不影响决策,下面这四条影响。
不等于
替代关系
VL 顺带就能读字,但它读字是「生成」出来的
现代 VL 的识字能力已经很强,强到容易让人以为可以把 OCR 整条撤掉。问题在机制:VL 输出的每一个字符都是一次采样。
一串长数字、一个证件号、一笔金额,它可能读对前面所有位、在某一位上给出另一个数字,而且不会告诉你它在那一位上不确定。实测对拍里见过这样一次:六位数字中倒数第二位被读成了另一个数(单次观察,不是统计结论),输出没有任何异常信号 —— 若下游拿它去匹配身份,就会安静地匹配到另一个人身上。
OCR 至少给 conf。你能设阈值、挑出低分项人工复核、统计准确率。这不是精度差异,是有没有可观测性的差异。
就绕不开
OCR
要把结果放回原图,VL 的框得先实测过才敢用
PDF 结构化、合同条款比对、表单自动回填、命中区域高亮、按版面切块再分发 —— 这些都需要「这个字在第几页第几个像素」。
不少 VL 现在原生支持 grounding,能直接回一组边界框,所以「VL 给不了坐标」已经不准确了。但准确的说法是:精度和稳定性普遍弱于 OCR 的检测框,同一张图换个问法就可能偏移。把它当定位器用之前必须在自己的数据上实测;实测之后立下「VL 只读字、不给坐标,位置交给像素判断或 OCR」这条硬规矩的团队并不少见。
判据很干脆:你的下游要不要拿着结果回到原图上去?要,就得先证明那组框够准,证明不了就让 OCR 来出。
在识别
之后那一段
VL 真正省掉的不是识别,是识别之后那一堆 if
传统链路的成本从来不在 OCR 本身,而在它后面那层胶水:OCR → 正则 / 坐标邻近 / 版式模板 → 字段。换一种票样、供应商改一次排版,这层就得重写一遍,而且它的失败是脆的 —— 偏移十个像素,整条规则就不命中。
VL 链路把这层换成一句话:图 + 「提取开票方、金额、日期,返回 JSON」。版式变了不用改代码。这才是 VL 颠覆的部分 —— 不是识别,是识别之后的结构化。
最常见的
形态
要准又要懂,就两个都要
OCR 保证字符准确率和坐标,VL 负责「哪个数是总价、这两行是不是同一项」。关键字段以 OCR 的原值为准,VL 只做语义归位,不负责报数。
这条分工是可执行的:把两路的同一个字段各自归一化(去掉货币符号、千分位、全角半角、前后空白)之后比对,对不上就说明两路有分歧,那一张退回人工或第三方规则裁决,不让它静默入库。注意比对只能发现分歧,不能直接判定是哪一路错 —— OCR 自己也会漏检和误检。
要点不在「两个都调一遍」,在最后那条回查线
原图同时走两路:OCR 拿到可校验的文本层,原图直传保住版面和非文字线索,VL 在两者之上做语义归位。
顺带一个容易被忽略的环节:当结果要经过人眼转录再录入时,I / l / 1、O / 0、5 / S 这几组在多数字体下极易看混。长标识符(token、证件号、订单号)在系统之间传递要走管道或变量,不要从屏幕上重敲 —— 这个坑和模型无关,纯粹是人机接口的问题,但它造成的错误和模型读错一位长得一模一样。
按「下游要什么」倒推,不按「哪个更先进」顺推
四种典型场景,以及每种为什么这么选。
-
只要文字、要坐标、量大、版式规整
OCR
批量归档、全文检索建索引、扫描件转可搜索 PDF。成本和延迟是主要约束,语义无所谓 —— 这类场景用 VL 是纯粹的浪费,而且丢了坐标。 -
版式杂、要语义、要结构化字段、量不大
VL
多来源单据、长尾合同、截图里捞信息。省掉的那层规则胶水比推理成本值钱 —— 判据是「你为新版式写规则的人力,比 token 账单贵吗」。 -
既要准确又要理解,字段会进账、进库、进风控
OCR + VL
财务、票据、证照、合规。OCR 定值,VL 定义,关键字段双向对账。多花的那一次 OCR 调用,买的是这条链路上最直接的一道观测。 -
图里根本没有字
只能 VL
界面截图排障、商品图打标、内容审核、图表读数、UI 理解。OCR 在这里没有可抠的对象。
上生产前的一条。走 VL 做结构化时,关键数字字段要留一道交叉校验。
因为这类故障的形态是:绝大多数单据都处理对了,少数几张的金额静默错了一位。它不抛异常、不降置信度、不进错误日志 —— 那一位数字安安静静地写进了库。等到对账对不平才被发现时,已经很难定位是哪一批、哪一张。
交叉校验不是「稳一点」,它是这条链路上最直接的一道观测。不是唯一的一道 —— 单据自身的勾稽关系(金额+税额=合计)、证件号的校验位、下游的对账,都能发现问题;但那些只在数据恰好自带冗余、或者错误恰好影响到总额时才成立,而回查 OCR 原值对每一个字段都成立。