几十页文档别每页都高清读:两级分辨率的第一道闸是漏页

一、这条链路的形状:一次全量粗扫,一次小范围精读
头条科技频道有一条关于开源视觉语言模型的内容,讲的是专门处理长文档的一类做法。传统的直白路径是把每一页按高分辨率整体输入,切成大量小块再折算成词元,页数一多,词元与显存的开销就跟着快速上升。两级做法把这件事拆开:先用极低的分辨率把整份文档粗扫一遍,只判断每一页与问题是否相关;锁定少量关键页之后,再对这些页做高清提取。发布方的自述里给出了词元降幅与缓存压缩幅度,但这些数字出自其论文的自测环境,尚待第三方复跑,因此本文一处也不引用——据公开报道理解即可,它不是我们做技术判断的依据。
值得写的是这条链路的形状。它有两个计费面:第一级按页数收费,每一页都要过一次,成本与文档总页数成正比;第二级按选中页数收费,成本与你真的读了几页高清有关。两级之间唯一承重的地方,是第一级那个”相关或不相关”的判断。第二级读错页,代价是白花的算力;第一级漏页,代价是模型在缺证据的情况下给出一个流畅而错误的答案。前者是成本问题,后者是正确性问题,两者不可通约。工程上就应该把这条链路当成”一个召回系统接一个阅读器”来设计,验收重心落在召回侧。
二、成本结构:总预算怎么被选中率决定
设文档共若干页,第一级每页的代价近似相同,第二级每页的代价明显更高。那么一次问答的总代价取决于”第二级选中了多少页”,也就是选中率。这条关系决定了三件事。
第一,两级做法的收益上限由选中率决定,不由模型本身决定。如果一个业务里大多数问题确实只集中在一两页,粗扫的价值非常大;如果答案经常散落在多页表格与图注里,选中率被迫抬高,整条链路会退化——极端情况是所有页都被判为相关,第二级按全量高清跑,此时两级反而比直接全量读更贵,因为多付了一遍粗扫。第二,预算应该按”最坏情况”设上限,而不是按”平均选中几页”设。平均数在报表里好看,超支事故从来发生在长尾样本上。第三,必须有一条明确的降级路径:当某个问题锁定的页数超过上限时,系统是继续花算力、只取置信度最高的若干页、还是拒答并要求人工介入,这个选择要写在配置里,不能由运行时随机决定。
| 预算项 | 由什么驱动 | 记账口径 | 超预算时的处置 | 必须落的字段 |
|---|---|---|---|---|
| 第一级粗扫 | 文档总页数 | 每页一次判定,代价近似固定 | 不允许跳过页,跳过即等于漏页 | 总页数、实际扫描页数是否相等 |
| 第二级高清 | 被判为相关的页数 | 每选中页一次完整读图 | 按置信度截断,或整单转人工 | 选中页清单、被截断页清单 |
| 页级判定模型 | 判定用的输入精度 | 缩略图精度与判定成本 | 精度不得低于可读下限 | 缩略图档位、判定耗时 |
| 缓存占用 | 并发与单请求长度 | 归属到会话还是请求 | 超上限时降选中页数 | 上限制定的依据、命中情况 |
| 降级与人工 | 触发降级的问题数 | 一次人工复核 | 视为正常出口之一 | 触发原因码 |
三、第一级要按”召回优先”设计,且必须记下被排除的页
页级相关性判定的目标函数不是”判得准”,是”别漏”。这两者在实现上有具体差别。
阈值要故意调低。宁可多读几页高清,也不要少读一页。判据是:多读一页的成本是线性的,漏一页的代价是答案整体作废,因此当单位算力与错误代价之比明显偏向后者时,就应该把阈值往”多召回”方向推;只有当业务能给出”答错可以接受、超预算不可接受”这类明确排序时,才允许反过来收紧。这个排序必须来自业务方书面确认,不能由工程侧默认。
被排除的页必须留记录,且带置信度。这是整套设计里最容易被省掉的一条,也是事后唯一能追查漏页的入口。如果系统只保留”读了哪些页”,一次漏页事故就无法复原——你连模型当时看不到什么都不知道。排除记录要包含页序、判定置信度、所用的缩略图档位,保存这些元数据不涉及文档内容本身,与隐私约束也不冲突。
结构特征要参与判定,不能只看文字密度。长文档里真正的证据经常不是成段文字:一张财务报表的合计行、一张流程图里的一个分支、一段图注里的口径说明。这些内容在极低分辨率下几乎不可读,缩略图上看不清表格线与小字,用文字密度做页级判定会把整页图表判成”没什么字,不相关”。可用的结构特征包括版面块的数量与排布、是否存在表格框线、是否有图形区域、该页是否含标题或编号延续、以及从完整版式树上取到的页级元信息。判定模型可以粗糙,但输入不能只有字符量。
四、漏页错误为什么隐蔽,用什么检测
漏页的错误表现是”看起来正常”。模型拿到它看到的那几页,读得很认真,写出一段结构完整、术语准确的答案,读者没有任何线索知道有页被排除了。这与读错页不同,读错页往往会留下对不上的痕迹。隐蔽性来自答案里不含”依据缺失”的痕迹,所以检测必须靠输出约束,而不是靠人工通读。
三条做法按有效性排序。第一,强制引用页码。每个事实性结论必须标注来源页,无标注的结论按未经验证处理;一旦输出被约束成”每句话都要指向一页”,漏页就会表现为引用覆盖不全,而不是沉默。第二,把”未找到依据”做成合法输出。如果模型在给定页里找不到答案,它必须能返回这个结果而不被惩罚;系统里若只有”给出答案”这一条出口,缺证据时它就会编。第三,抽检被排除页。定期从排除记录里抽一批页,交回完整链路重跑或直接给人看,统计”被排除但其实相关”的比例。前两条是线上机制,第三条是评估机制,三条都齐了才有资格说这条链路可控。
五、评测必须同时看两组指标,缓存只能当约束用
只看端到端答案对不对,会奖励蒙对:一份问题里如果多数答案可以从少数页推出,或者从模型自身知识里推出,那么一个把所有页都排除的系统也能拿到不难看的分数。因此评测集要同时产出两组指标,一组是答案正确率,一组是关键页召回率——后者需要有标注的评测集,标注”回答这个问题需要哪几页”,成本不低,但没有它就无法区分”读得准”和”猜得准”。评测集构建上还要求包含”答案只在某一页且该页文字很少”的样本,以及”证据分散在多页”的样本,否则召回率会被简单样本撑高。据公开报道,发布方自述的降幅类数字来自其自测环境,第三方未复跑之前不能当作我们验收的参照。
键值缓存这一项要摆正用法。它在长输入下常常先于其他资源耗尽,是这条链路上真实存在的硬约束,正确的用法是把它当预算上限来反推第二级最多读几页,并据此设阈值;错误的用法是把它当成果来宣传。落地时的记账口径要明确三件事:缓存状态归属到单次请求还是整个会话、跨请求复用时的失效条件是什么、超上限时是被抢占重算还是排队等待。至于它随长度与并发增长的推导过程,站内已有文章算得清楚,这里不重复——本文要说的只是:约束就是约束,把它写进预算表,别写进宣传页。
工程验收字段的最低集合是:每次问答的文档页数分布、第二级选中率、每问耗时分布、超预算触发次数与触发后的降级路径、被排除页抽检结果、以及强制引用与”未找到依据”两个输出的出现比例。这些字段要能在一个看板上读到,读不到就等于没有验收。
六、派生关系写进模型卡之后,选型方该读什么
这条内容里还有一个容易被忽略的工程信息:该模型权重发布在公开托管平台上,且模型卡中把它所基于的上游模型写成了公开字段,也就是说派生关系可以被直接读到。这件事对选型方的意义比性能数字更持久,因为它把依赖声明变成了可核查项。
拿到这样一份模型卡,我们按四步读。第一步读谱系:上游是什么、哪个版本、你自己的许可义务链能不能闭合,派生声明缺失不等于没有派生,只是核查责任转移到了你自己身上。第二步读能力声明与证据:自述指标是否给了测试环境、是否公开评测集、是否第三方可复跑,没有这些就把它们记为”待验证”,不要转述成结论。第三步读资源约束声明:显存与缓存的实际边界、长输入下的行为是否给过条件,缺条件的性能声明一律按宣传处理。第四步读退出成本:权重与配置能否本地留存、依赖的分词与预处理组件版本是否可固定、上游变更时有没有回滚路径。
洹拓在把这类长文档视觉链路交付给客户时,坚持一条朴素原则:先假设第一级会漏页来设计方案,再谈它省了多少。因为省下的算力是可回收的成本,漏掉的那一页是不可回收的错误,两类账不能合并成一句话汇报。预算表可以慢慢调,漏页的检测机制上线那天就必须存在。