一摞文档页被分成两堆,左边一堆压成灰色缩略图,右边少数几页保持清晰并被红线框住

一、这条链路的形状:一次全量粗扫,一次小范围精读

头条科技频道有一条关于开源视觉语言模型的内容,讲的是专门处理长文档的一类做法。传统的直白路径是把每一页按高分辨率整体输入,切成大量小块再折算成词元,页数一多,词元与显存的开销就跟着快速上升。两级做法把这件事拆开:先用极低的分辨率把整份文档粗扫一遍,只判断每一页与问题是否相关;锁定少量关键页之后,再对这些页做高清提取。发布方的自述里给出了词元降幅与缓存压缩幅度,但这些数字出自其论文的自测环境,尚待第三方复跑,因此本文一处也不引用——据公开报道理解即可,它不是我们做技术判断的依据。

值得写的是这条链路的形状。它有两个计费面:第一级按页数收费,每一页都要过一次,成本与文档总页数成正比;第二级按选中页数收费,成本与你真的读了几页高清有关。两级之间唯一承重的地方,是第一级那个”相关或不相关”的判断。第二级读错页,代价是白花的算力;第一级漏页,代价是模型在缺证据的情况下给出一个流畅而错误的答案。前者是成本问题,后者是正确性问题,两者不可通约。工程上就应该把这条链路当成”一个召回系统接一个阅读器”来设计,验收重心落在召回侧。

二、成本结构:总预算怎么被选中率决定

设文档共若干页,第一级每页的代价近似相同,第二级每页的代价明显更高。那么一次问答的总代价取决于”第二级选中了多少页”,也就是选中率。这条关系决定了三件事。

第一,两级做法的收益上限由选中率决定,不由模型本身决定。如果一个业务里大多数问题确实只集中在一两页,粗扫的价值非常大;如果答案经常散落在多页表格与图注里,选中率被迫抬高,整条链路会退化——极端情况是所有页都被判为相关,第二级按全量高清跑,此时两级反而比直接全量读更贵,因为多付了一遍粗扫。第二,预算应该按”最坏情况”设上限,而不是按”平均选中几页”设。平均数在报表里好看,超支事故从来发生在长尾样本上。第三,必须有一条明确的降级路径:当某个问题锁定的页数超过上限时,系统是继续花算力、只取置信度最高的若干页、还是拒答并要求人工介入,这个选择要写在配置里,不能由运行时随机决定。

预算项 由什么驱动 记账口径 超预算时的处置 必须落的字段
第一级粗扫 文档总页数 每页一次判定,代价近似固定 不允许跳过页,跳过即等于漏页 总页数、实际扫描页数是否相等
第二级高清 被判为相关的页数 每选中页一次完整读图 按置信度截断,或整单转人工 选中页清单、被截断页清单
页级判定模型 判定用的输入精度 缩略图精度与判定成本 精度不得低于可读下限 缩略图档位、判定耗时
缓存占用 并发与单请求长度 归属到会话还是请求 超上限时降选中页数 上限制定的依据、命中情况
降级与人工 触发降级的问题数 一次人工复核 视为正常出口之一 触发原因码

三、第一级要按”召回优先”设计,且必须记下被排除的页

页级相关性判定的目标函数不是”判得准”,是”别漏”。这两者在实现上有具体差别。

阈值要故意调低。宁可多读几页高清,也不要少读一页。判据是:多读一页的成本是线性的,漏一页的代价是答案整体作废,因此当单位算力与错误代价之比明显偏向后者时,就应该把阈值往”多召回”方向推;只有当业务能给出”答错可以接受、超预算不可接受”这类明确排序时,才允许反过来收紧。这个排序必须来自业务方书面确认,不能由工程侧默认。

被排除的页必须留记录,且带置信度。这是整套设计里最容易被省掉的一条,也是事后唯一能追查漏页的入口。如果系统只保留”读了哪些页”,一次漏页事故就无法复原——你连模型当时看不到什么都不知道。排除记录要包含页序、判定置信度、所用的缩略图档位,保存这些元数据不涉及文档内容本身,与隐私约束也不冲突。

结构特征要参与判定,不能只看文字密度。长文档里真正的证据经常不是成段文字:一张财务报表的合计行、一张流程图里的一个分支、一段图注里的口径说明。这些内容在极低分辨率下几乎不可读,缩略图上看不清表格线与小字,用文字密度做页级判定会把整页图表判成”没什么字,不相关”。可用的结构特征包括版面块的数量与排布、是否存在表格框线、是否有图形区域、该页是否含标题或编号延续、以及从完整版式树上取到的页级元信息。判定模型可以粗糙,但输入不能只有字符量。

四、漏页错误为什么隐蔽,用什么检测

漏页的错误表现是”看起来正常”。模型拿到它看到的那几页,读得很认真,写出一段结构完整、术语准确的答案,读者没有任何线索知道有页被排除了。这与读错页不同,读错页往往会留下对不上的痕迹。隐蔽性来自答案里不含”依据缺失”的痕迹,所以检测必须靠输出约束,而不是靠人工通读。

三条做法按有效性排序。第一,强制引用页码。每个事实性结论必须标注来源页,无标注的结论按未经验证处理;一旦输出被约束成”每句话都要指向一页”,漏页就会表现为引用覆盖不全,而不是沉默。第二,把”未找到依据”做成合法输出。如果模型在给定页里找不到答案,它必须能返回这个结果而不被惩罚;系统里若只有”给出答案”这一条出口,缺证据时它就会编。第三,抽检被排除页。定期从排除记录里抽一批页,交回完整链路重跑或直接给人看,统计”被排除但其实相关”的比例。前两条是线上机制,第三条是评估机制,三条都齐了才有资格说这条链路可控。

五、评测必须同时看两组指标,缓存只能当约束用

只看端到端答案对不对,会奖励蒙对:一份问题里如果多数答案可以从少数页推出,或者从模型自身知识里推出,那么一个把所有页都排除的系统也能拿到不难看的分数。因此评测集要同时产出两组指标,一组是答案正确率,一组是关键页召回率——后者需要有标注的评测集,标注”回答这个问题需要哪几页”,成本不低,但没有它就无法区分”读得准”和”猜得准”。评测集构建上还要求包含”答案只在某一页且该页文字很少”的样本,以及”证据分散在多页”的样本,否则召回率会被简单样本撑高。据公开报道,发布方自述的降幅类数字来自其自测环境,第三方未复跑之前不能当作我们验收的参照。

键值缓存这一项要摆正用法。它在长输入下常常先于其他资源耗尽,是这条链路上真实存在的硬约束,正确的用法是把它当预算上限来反推第二级最多读几页,并据此设阈值;错误的用法是把它当成果来宣传。落地时的记账口径要明确三件事:缓存状态归属到单次请求还是整个会话、跨请求复用时的失效条件是什么、超上限时是被抢占重算还是排队等待。至于它随长度与并发增长的推导过程,站内已有文章算得清楚,这里不重复——本文要说的只是:约束就是约束,把它写进预算表,别写进宣传页。

工程验收字段的最低集合是:每次问答的文档页数分布、第二级选中率、每问耗时分布、超预算触发次数与触发后的降级路径、被排除页抽检结果、以及强制引用与”未找到依据”两个输出的出现比例。这些字段要能在一个看板上读到,读不到就等于没有验收。

六、派生关系写进模型卡之后,选型方该读什么

这条内容里还有一个容易被忽略的工程信息:该模型权重发布在公开托管平台上,且模型卡中把它所基于的上游模型写成了公开字段,也就是说派生关系可以被直接读到。这件事对选型方的意义比性能数字更持久,因为它把依赖声明变成了可核查项。

拿到这样一份模型卡,我们按四步读。第一步读谱系:上游是什么、哪个版本、你自己的许可义务链能不能闭合,派生声明缺失不等于没有派生,只是核查责任转移到了你自己身上。第二步读能力声明与证据:自述指标是否给了测试环境、是否公开评测集、是否第三方可复跑,没有这些就把它们记为”待验证”,不要转述成结论。第三步读资源约束声明:显存与缓存的实际边界、长输入下的行为是否给过条件,缺条件的性能声明一律按宣传处理。第四步读退出成本:权重与配置能否本地留存、依赖的分词与预处理组件版本是否可固定、上游变更时有没有回滚路径。

洹拓在把这类长文档视觉链路交付给客户时,坚持一条朴素原则:先假设第一级会漏页来设计方案,再谈它省了多少。因为省下的算力是可回收的成本,漏掉的那一页是不可回收的错误,两类账不能合并成一句话汇报。预算表可以慢慢调,漏页的检测机制上线那天就必须存在。