PixelUMM 先跑通单图任务、再谈多图和文档混合输入

文章导读
如果目标是一次性把 PixelUMM 的多图输入和整页文档混排都接进来,常见的结局是报错和低质输出混在一起:分不清是请求体构造错了、模型不接受这种输入组合,还是文档分页把内容切断了。更稳的推进顺序是先把一张图跑成能重复执行、能写入文件、能对照判定的最小链路,再逐层加第二张图、加整页文档。每一步都单独验证,失败时能直接定位到某一层,而不是从头重来。
📋 目录
  1. A 把单图任务跑成一条能重复执行的最小链路
  2. B 在单图链路上加第二张图,观察请求与返回结构变化
  3. C 换成整页文档输入,记录分页与长度带来的差异
  4. D 把三步产生的错误信息归到同一张记录表
  5. E 根据记录表决定哪一步可以先灰度
A A

如果目标是一次性把 PixelUMM 的多图输入和整页文档混排都接进来,常见的结局是报错和低质输出混在一起:分不清是请求体构造错了、模型不接受这种输入组合,还是文档分页把内容切断了。更稳的推进顺序是先把一张图跑成能重复执行、能写入文件、能对照判定的最小链路,再逐层加第二张图、加整页文档。每一步都单独验证,失败时能直接定位到某一层,而不是从头重来。

PixelUMM 的多图与文档混排不建议一次接入。先固定一张样本图,把请求、写入文件、通过判定做成可重复链路;再加第二张图,只观察请求体与返回结构新增了哪部分;最后换整页文档,单独记录分页方式与长度切分。三步各自保留最小复现样本和错误记录,灰度只从失败已能归因的那一步开始。模型实际支持哪些输入组合,以公开说明和自己实测为准,不要预设某组合一定可用。

把单图任务跑成一条能重复执行的最小链路

这一步的唯一目的是得到一个可信基线:后面加第二张图、换整页文档时,所有对比都对着这条链路的结果看。基线不稳定,后面所有“变差了”的判断都没有意义。

脚本骨架建议做成“固定样本 + 固定提示词 + 落盘 + 记录耗时与状态码”四件事,不要在这一步加循环、加队列、加重试策略。下面这段是通用接入骨架,ENDPOINT 和字段名需要换成你实际服务与公开说明里的写法。

# run_single.py —— 单图最小链路骨架
import json, hashlib, pathlib, time, requests

ENDPOINT = "http://localhost:8000/v1/infer"      # 换成你的服务地址
SAMPLE   = pathlib.Path("samples/one_page_form.png")  # 固定样本,别随手换
OUT      = pathlib.Path("runs"); OUT.mkdir(exist_ok=True)

def run_single(img_path, prompt):
    payload = {
        "input": [{"type": "image", "path": str(img_path)}],
        "prompt": prompt,
    }
    tag = hashlib.md5((img_path.name + prompt).encode("utf-8")).hexdigest()[:8]
    out_file = OUT / ("single_" + tag + ".json")
    t0 = time.time()
    try:
        r = requests.post(ENDPOINT, json=payload, timeout=60)
        rec = {"status": r.status_code, "elapsed": round(time.time() - t0, 2),
               "req": payload, "resp": r.json()}
    except Exception as e:
        rec = {"status": "exception", "error": repr(e), "req": payload}
    out_file.write_text(json.dumps(rec, ensure_ascii=False, indent=2))
    return out_file

if __name__ == "__main__":
    print(run_single(SAMPLE, "逐行输出图中文字,保持原有阅读顺序"))

样本图要选一张自己熟悉的:文字量中等、有表格线、有一两处空格或勾选框,这样输出质量好坏一眼能看出来。同一张样本图连续跑几次,结果都写入 runs 目录,不要覆盖同名文件,便于回看差异。

单图链路的通过标准建议写成可人工核对的条件,而不是打分数:请求正常返回、返回结构里有你需要的文本字段、图片中的主要文字行没有整行缺失、阅读顺序与人工判断一致、同一张图重复跑几次结果大体稳定。只要“整行缺失”或“顺序明显错乱”出现,就先别往下走,先确认是样本问题还是接口问题。

PixelUMM 先跑通单图任务、再谈多图和文档混合输入

在单图链路上加第二张图,观察请求与返回结构变化

加第二张图的目的是搞清楚两件事:请求体里哪些字段是新增的,返回里哪些结构是必须自己维护的,比如图与图之间的顺序、每段输出属于哪张图。不要在这一步同时改提示词或换样本图,否则变化来自哪里说不清。

请求体变化通常只是 input 从一项变成两项,但是否需要额外字段(序号、页号、分组标记)要按公开说明来。可以先试最朴素的双图请求:

{
  "input": [
    {"type": "image", "path": "samples/form_a.png"},
    {"type": "image", "path": "samples/form_b.png"}
  ],
  "prompt": "分别输出每张图的文字,不要合并成一段"
}

返回结构对照时重点看三处:单图时返回的是单个文本块还是带条目的列表;双图时是否出现按图分组的标记字段(具体字段名以公开说明为准,不要自己猜一个名字写进代码);当返回只有一段文本时,顺序是否与提交顺序一致。如果返回把两张图的内容合并成一段且没有边界标记,那么“哪段属于哪张图”就得由你的代码自己维护,这属于必须自己承担的部分,不是接口缺陷。

这一步的通过条件是:两张图各自的关键文字都能在输出里找到、能按图区分归属、顺序稳定。做不到按图区分,就不要继续叠加文档输入。

PixelUMM 先跑通单图任务、再谈多图和文档混合输入

换成整页文档输入,记录分页与长度带来的差异

文档类输入和图片类输入的问题性质不一样。图片的问题多在识别质量和版面理解,文档的问题多在你自己的切分方式上:一页怎么变成一张图、一份多页文档怎么变成多次请求、每段输入的页数或字符数是多少。这三件事不记录,后面出问题只能靠猜。

分页方式通常有两条路:把每页渲染成一张图逐页提交,或者用现成的文档加载方式自动切块。逐页渲染可控性强、便于对照单图链路的结果,建议先用这条;自动切块省事,但切在哪里、切了几块不透明,出问题时不好归因。

长度切分要留下记录,字段至少包括:样本文件名、总页数、本次提交的页码区间、单页图像的边长或分辨率、提示词版本。失败样本的具体表现也要写下来,常见几类:靠后页面内容整段缺失、跨页表格在切分处断行错位、请求超时、返回文本在中途被截断、多页内容顺序与页码不一致。这几种现象对应的排查方向完全不同,混在一起记会反复踩同一个坑。

把三步产生的错误信息归到同一张记录表

三个环节的错误长得像,但原因不同:单图报错多半是请求构造或环境问题,多图报错多半是组合方式或结构假设问题,文档报错多半是切分与长度问题。同一张表里用“出现环节”一列区分,用“复现所需最小样本”一列保证别人能重跑。

PixelUMM 先跑通单图任务、再谈多图和文档混合输入
错误类型出现环节最小复现样本
请求构造错误单图one_page_form.png + 原始 payload
鉴权或连接失败单图同一条命令,仅换 ENDPOINT
多图归属不清双图form_a + form_b 两张固定图
内容缺失或缺页文档某一页单独渲染后的图
超时或返回截断文档同一页区间,减少页数重跑

记录条目建议直接用同一份 JSON 结构,方便后面筛选和比对:

{
  "sample_id": "doc_p3_p7",
  "stage": "doc",
  "error_type": "content_missing",
  "minimal_repro": "samples/doc_12p.pdf 第 3-7 页逐页渲染",
  "observed": "第 6 页表格后半段没有出现在输出中",
  "next": "第 6 页单独提交,确认是切分问题还是识别问题"
}

判断标准很简单:同一个错误如果在表里出现两次以上、且“最小复现样本”一栏写不出具体文件或页码,说明这条记录还不够用,先补样本再继续排查。

根据记录表决定哪一步可以先灰度

推进决策从表里读,不从感觉里读。单图环节如果已经能重复执行、没有归类不明的失败,就可以作为灰度起点;双图环节只有在“按图区分归属”这一条稳定做到之后才考虑放量;文档环节只要有未归因的缺页或截断,就先只做内部验证,不扩大范围。

  • 灰度准入条件:该环节的失败都能在记录表里落到具体错误类型和最小复现样本;上一环节的基线仍然可复现,没有因为改动而失效。
  • 灰度范围:先固定样本集、限定少量账号或内部调用方,只保留当前环节,不同时开文档混排;每类样本都要有人在看输出。
  • 回退到上一步的触发信号:出现新的、无法归类的错误类型;同一份固定样本的输出与基线差异明显且原因说不清;文档环节缺页数量无法用切分方式解释。出现任一条,就退回上一环节,先修基线再谈放量。

这套顺序的价值不在流程好看,而在于任何一次失败都能回答三个问题:在哪一层坏的、用哪个最小样本能重跑、下一步该改请求还是改切分。多图和文档混排迟早要接,但接入顺序决定了你是在排查一个问题,还是在排查一堆互相掩盖的问题。