OvisOCR2 解析长合同越往后越容易丢内容——先查切分还是先查页面图像?

文章导读
长合同越往后越丢内容,先查切分还是先查页面图像,取决于缺失是否固定在某个页段重复出现。一个可执行的顺序是:先做分页级日志,把“哪一页开始缺”定位出来;再固定图像只改切分跑一次,固定切分只改后半段图像跑一次。两次对照之后,问题通常能落到切分边界或页面图像质量中的一条线上。如果日志还没做,先不要改切分参数,因为改完后丢失位置会移动,反而更难比对。
📋 目录
  1. Ⅰ 先给每页打上处理日志
  2. Ⅱ 找出内容开始缺失的那一页
  3. Ⅲ 单独改切分策略再跑一次
  4. Ⅳ 单独改输入图像再跑一次
  5. Ⅴ 确认长文档的稳定处理上限
A A

长合同越往后越丢内容,先查切分还是先查页面图像,取决于缺失是否固定在某个页段重复出现。一个可执行的顺序是:先做分页级日志,把“哪一页开始缺”定位出来;再固定图像只改切分跑一次,固定切分只改后半段图像跑一次。两次对照之后,问题通常能落到切分边界或页面图像质量中的一条线上。如果日志还没做,先不要改切分参数,因为改完后丢失位置会移动,反而更难比对。

长合同解析到后半段出现段落缺失或重复,建议按“日志定位 → 切分单变量对照 → 图像单变量对照 → 定稳定处理上限”的顺序排查。判断依据是每页输出块数、字符数与前一页相比是否突变,以及同一页在两次运行中的输出差异;风险边界是不要在一次运行里同时改切分和图像,否则无法归因。若缺失集中在文档末端固定页段,优先怀疑分页切分与页序衔接;若缺失随页面清晰度、方向、扫描质量变化,则优先怀疑页面图像。两种线索都存在时,仍应逐条单变量验证。

先给每页打上处理日志

没有分页日志时,只能看到“整篇少了几段”,无法判断是哪一页开始丢。建议在解析流程里给每一页落一条记录,至少包含:页码、该页耗时、该页输出块数、该页输出字符数、错误标记。输出块数比字符数更能反映结构被切碎或合并的情况,两者一起看,才能区分“内容没识别出来”和“块被合并且顺序错乱”。

下面的脚本骨架只是通用写法,字段名和落盘方式按你实际流程替换;把它放在每页解析完成之后执行,写成一个独立函数即可。

import json, time

def log_page(page_no, page_file, fn_parse):
    t0 = time.time()
    err = ""
    blocks, chars = 0, 0
    try:
        result = fn_parse(page_file)      # 替换为实际的单页解析调用
        blocks = len(result.get("blocks", []))
        chars  = sum(len(b.get("text", "")) for b in result.get("blocks", []))
    except Exception as e:
        err = type(e).__name__ + ":" + str(e)[:120]
    rec = {
        "page_no": page_no,
        "page_file": page_file,
        "cost_ms": int((time.time() - t0) * 1000),
        "out_blocks": blocks,
        "out_chars": chars,
        "error": err
    }
    with open("page_trace.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps(rec, ensure_ascii=False) + "\n")
    return rec

验证方式很简单:随机抽几页,把 out_chars 与人工看到的页内文字量做粗略对比,确认日志本身没有统计偏差。日志里不要只留最终结果,错误标记也要留,因为有些页不是“输出为空”,而是输出了少量块并抛出异常,这两种情况处理方向不同。

找出内容开始缺失的那一页

把 page_trace.jsonl 按页码排序,统计每页 out_blocks 与 out_chars,并与前一页对比。合同类文档单页文字量一般比较接近,如果第 N 页开始出现连续多页输出量明显低于前面页面的均值,突变点附近就是排查起点。这里不追求精确阈值,先看相对变化:某页字符数掉到前一页的一小部分且后续没有恢复,比单页小幅波动更值得关注。

同时要把日志页码与原文档页数对齐。扫描件里常出现空白页、分隔页、印章页,它们本身输出就少,容易误判成缺失。建议在日志旁边加一列人工标注的页类型(正文页/空白页/图表页),对照表如下:

  • 页码:解析流程内的顺序号,必须与 PDF 页序一致,不要用文件名排序。
  • out_blocks:突变判断的主指标,连续下降比单页下降更可信。
  • out_chars:用于区分“块数正常但每块变短”和“块数直接减少”。
  • error:有错误的页单独列出来,不参与均值比较。
  • 页类型:人工抽标若干页,排除空白页干扰。

做完这一步,问题范围就从“整篇越往后越丢”缩到“从第 X 页起,到第 Y 页明显偏低”。如果偏低段只出现在末尾几页,切分策略的嫌疑上升;如果偏低段与页面扫描质量差的页重合,图像线索上升。两者都可能存在,所以下一步要单变量验证。

OvisOCR2 解析长合同越往后越容易丢内容——先查切分还是先查页面图像?

单独改切分策略再跑一次

固定输入图像不变,只调整页切分方式,比如从固定字符数切块改成按页或按段落边界切块,或者调整跨页合并窗口。两次运行的日志字段保持一致,落到不同文件,再按页码做对照表,比较每页 out_blocks 和 out_chars 的差异。

判读时看两类现象:如果改切分后,原先缺失的那几页输出量恢复,且其他页没有明显退化,说明分页衔接或跨页合并规则是主因;如果改切分后缺失位置只是整体平移、总量不变,说明切分不是根因。需要注意,改切分本身会改变块边界,块数变化不等于内容找回,最终仍要抽几页人工核对文本是否连续、有没有跨页重复。

单独改输入图像再跑一次

固定切分策略不变,只对后半段页面做图像修正:统一方向、提高有效分辨率、去掉扫描噪点或重做倾斜校正。前半段页面保持原样作为对照。再次跑分页日志,比较修正页在两次运行中的 out_blocks 与 out_chars。

如果修正后缺失页的输出量明显回升,同时前半段未修正页的结果基本不变,图像质量就是这段丢失的主要解释。如果修正后输出量没有改善甚至更差,说明问题不在这几页的成像,应回到切分与页序衔接上继续查。图像修正不要一次叠加多个处理,先只做方向校正,再做清晰度处理,才能知道哪一步起了作用。

确认长文档的稳定处理上限

两次单变量对照之后,建议用同一份日志确定这份文档在当前配置下能整篇处理到多少页。做法是从头按页累加 out_chars,找出从哪一页之后输出量持续偏低且无法通过单页重试恢复,这个页数就是当前的稳定处理上限,通常需要结合具体文档类型和环境确认,不同扫描质量的合同会有差别。

超过上限后,建议按章节或固定页区间拆分,例如每 20 到 30 页一组,组间保留一页重叠用于校验。拆分后要校验拼接结果:检查相邻组的首尾段落是否重复或断裂,比较分组处理的总块数与整篇处理的块数是否在同一量级,并抽查每组最后一页和下一组第一页是否连续。对拆分后仍出现缺失的页,单独重跑并记录,不要为了掩盖缺失而放宽切分粒度。