一个 OCR 模型最可怕的失败,不一定是漏几个字。更麻烦的是输出突然开始复读,像卡进一个循环,整段结构化结果直接报废。

DharmaOCR 这次做了一件反常但有用的事:没有把这些退化重复输出直接丢掉,而是拿来做 DPO 的 rejected 样本。先 SFT 适配巴西葡语结构化文档 OCR,再用 DPO 压低复读失效。5 个开源模型家族全部降了,平均相对降幅 59.4%,最高 87.6%。

这件事的边界也要先说清。它不是聊天机器人偏好对齐,也不能写成“DPO 证明优于 SFT”。这里的 DPO 更像 SFT 之后的刹车系统,专治一个可判定、可构造偏好对的坏模式。

DharmaOCR 做的事:把复读输出变成拒绝样本

这次任务是巴西葡语结构化文档 OCR。重点不是开放聊天里的“哪个回答更讨人喜欢”,而是结构化输出是否掉进文本退化。

这里的退化率,可以理解为评估中统计到的文本重复、循环式坏输出比例。具体判定阈值和完整模型表,仍要回到 DharmaOCR 原文或项目实现核验;目前线索里能确认的是相对变化和几个关键案例。

变量DharmaOCR 的做法读者该抓住的点
任务巴西葡语结构化文档 OCR不是聊天机器人对齐
训练顺序SFT 后再 DPO两者不是替代关系
偏好对同一批文档、同一模型生成候选输出chosen/rejected 来自模型自身表现
rejected退化重复输出失败样本不丢,改作负反馈
结果5 个模型家族退化率全降相对 SFT 平均降 59.4%,范围约 37% 到 88%

原始开源模型的退化率差异很大:有的低于 1%,有的高于 33%。SFT 通常能降低退化,但不稳定。

Qwen2.5-VL-3B 是最值得盯的例子:原始退化率 0.60%,SFT 后升到 3.23%,DPO 后降到 1.41%。

这组数很刺眼。它说明模型被推向任务域时,能力适配可能同时把它推近某个失效吸引子。会做题了,但也更容易在某些局部格式、长序列或重复模式里打转。

对做 LLM/VLM 落地的人,这不是论文细节。这是上线风险。

如果你在做文档 OCR、票据抽取、表格解析、JSON 生成,评测表里不能只放准确率、字段召回、格式合规率。退化重复率也该单列。坏输出样本不要只清洗掉,至少要留一份,供后续偏好训练、拒绝采样或回归测试使用。

SFT 管会不会做,DPO 管别往哪儿坏

SFT 的目标很直接:让模型更像标准答案。它教模型目标语言、字段结构、输出格式和任务习惯。

但复读循环不是普通错字。它是完成级别的崩坏。token-by-token 学正确答案,未必会明确告诉模型:这一整段已经坏了,别再往这个方向走。

DPO 的切口在完成级别。同一个输入下,正常结构化输出是 chosen,退化重复输出是 rejected。训练目标变成:同样面对这份文档,别偏向那个会复读的完成。

这里不能拔高。材料并没有证明退化下降的因果机制,只能说有推测和后验分析支持。DPO 为什么有效,仍需要更多任务、更多模型、更多消融来拆。

但工程上,方向已经够清楚:

路线它擅长什么它不保证什么
SFT任务适配、格式学习、领域迁移不保证远离特定失效模式
DPO用偏好对压低坏完成不替代 SFT,也不自动提升所有能力
纯清洗让训练集更干净模型未必学到“哪里不能去”

很多团队会把所有问题都塞给“再微调一下”。识别不准,微调;格式不稳,微调;复读崩坏,也微调。

这很省事,也很危险。SFT 能把模型推向任务域,但任务域里有坑。你只奖励正确样本,模型未必学会怕失败。

“天下熙熙,皆为利来。”训练目标也是这样。奖励往哪里放,模型就往哪里挤。把失败显式放进拒绝侧,至少给了模型一条负边界。

这也是采购和评测该调整的地方。

如果你在选 OCR/VLM 供应商,不要只看平均准确率演示。要让对方拿长文档、低质量扫描件、重复字段、异常版式跑一遍,看有没有复读、截断、格式循环。平均分漂亮,坏模式没压住,到了生产环境就是工单和赔付。

如果你是算法团队,下一步不是马上把 DPO 套到所有任务上。更现实的动作是三件事:留存坏样本,建立退化检测口径,在 SFT 后单独做失效模式治理。没有可判定的 rejected,DPO 也只是换个训练名词。

真正的分水岭:能力提升和失效治理分开算账

我不太买账的一种说法是:模型变强了,产品自然更稳。

这在生成式模型上经常不成立。能力提升解决“能不能做”。失效治理解决“坏起来有多坏、多久坏一次、坏了能不能被发现”。这是两套工程。

铁路提速之后,信号、刹车、调度都要重做。这个类比不完全一样,但结构相似:速度不是安全。更强的模型,也不等于更可控的产品。

DharmaOCR 的启发正在这里。它把失败样本从垃圾桶里捡回来,变成训练信号。这个动作不华丽,但很像产品化 AI 真正需要的笨功夫。

边界也很硬。它更适合结构化任务,尤其是失败能自动判定、候选能自动打分、偏好对能批量构造的场景。OCR、表格抽取、某些代码生成、JSON 输出,都可以借鉴。

开放式写作、复杂推理、主观质量很强的任务,就不能直接照搬。chosen/rejected 如果靠不住,DPO 会把噪声训练得更自信。

接下来最该观察的不是“还有哪些任务也用了 DPO”,而是三件更具体的事:

  • 退化率定义是否稳定,能不能跨数据集复现;
  • chosen/rejected 的自动评分模型是否可靠,是否会引入新偏差;
  • DPO 降低复读后,有没有牺牲字段准确率、召回率或格式完整性。

如果这些账算不清,退化率下降也只能算局部胜利。

但这次至少把一个方向讲明白了:生成式模型的失败样本,不该只被当成脏东西清掉。对产品团队来说,它们是事故档案,也是训练资产。

模型看着更强,产品未必更稳。真正见功夫的地方,常常不是把平均分再抬一点,而是把那些低频、顽固、砸招牌的坏模式压下去。