OvisOCR2接入分析.md 11 KB

OvisOCR2 接入分析

模型主页:https://huggingface.co/ATH-MaaS/OvisOCR2

1. 模型概况

  • 基于 Qwen3.5-0.8B 后训练得到的端到端页面级文档解析模型(0.8B,体积小、推理快),与仓库里已接入的 dots.ocr / MinerU-VL / GLM-OCR 属于同一类"整页丢进去,直接吐出结构化 Markdown"的模型。
  • 输出格式固定为单一 Markdown:
    • 正文:标准 Markdown
    • 公式:LaTeX
    • 表格:HTML <table>...</table>
    • 图片/图表区域:<img src="images/bbox_{left}_{top}_{right}_{bottom}.jpg" />,坐标归一化到 [0, 1000)
  • 官方推理示例使用 vLLM 离线 LLM() 接口做批量推理;vLLM 同时支持 vllm serve 启动 OpenAI 兼容 HTTP 服务,与仓库现有 MinerU-VL / GLM-OCR 的部署方式一致,可直接复用。
  • 只有一个通用 prompt,没有类似 GLM-OCR 的 task_prompt_mapping(按 text/table/formula/seal 分别提问)。
  • 图像分辨率范围 min_pixels=448*448 ~ max_pixels=2880*2880,整页直喂时对银行流水这类密集小字表格存在降采样丢字风险。

2. 是否还需要 layout、方向、印章等专用模型?—— 仍然需要

universal_doc_parser 现有流水线(见 core/model_factory.pyconfig/bank_statement_glm_vl.yaml)是:

方向校正 → 去水印 → layout 检测(含印章补充检测) → 表格有线/无线分类
        → 有线表:UNet + RT-DETR 单元格融合 → 单元格二次 OCR
        → 无线表/公式:VLM 识别 → 与并行 OCR 结果做单元格坐标匹配
环节 OvisOCR2 能否替代 结论
方向识别(paddle_orientation_classification 模型卡未提及旋转鲁棒性训练 保留,先扶正再喂给 OvisOCR2
Layout 检测(docling / PP-DocLayoutV3) 内部隐式做了版面理解,但不输出显式类别框(除图片/图表外没有坐标) 保留,用于按区域路由到专用模型(有线表、印章)
印章检测(seal_supplement,PP-DocLayoutV3) 无专门印章类别 保留
印章识别(SealOCRRecognizer,MinerU seal 专用 OCR) 无专门能力,见第 4 节 保留
表格有线/无线分类 不区分,统一按通用 prompt 输出 HTML 保留,有线表继续走 UNet+RT-DETR 精细单元格管线,OvisOCR2 只承担无线表/正文/公式

结论:OvisOCR2 适合替换/补充现有 vl_recognition 环节(对标 GLM-OCR/MinerU-VL 适配器),不适合替换整条 layout+方向+印章管线。

3. 能否返回表格单元格坐标?—— 不能,需复用现有坐标匹配方案

OvisOCR2 只对"图片/图表"类视觉区域给 bbox_{left}_{top}_{right}_{bottom}表格是纯 HTML <table> 结构,没有 per-cell 坐标,这一点和 GLM-OCR、MinerU-VL 完全一样(见 glmocr_vl_adapter.pyrecognize_table 直接返回 'cells': [])。

仓库已有解决方案:core/table_coordinate_utils.pyTableCellMatcher —— 并行跑一遍普通 OCR(PaddleOCR/MinerU OCR)拿到文本框,再用文本内容匹配把 HTML 表格里每个 <td> 的文字对齐到 OCR 检测框上,反推单元格坐标。OvisOCR2 接入后直接复用这套匹配逻辑即可,无需额外开发。

4. 能否识别印章?—— 不建议依赖它

  • 模型卡完全没提 "seal/印章/stamp" 能力,训练数据以 OmniDocBench/PureDocBench 通用文档为主。
  • 端到端 VLM 遇到印章大概率当成一个"图片视觉区域"整体裁出来(<img src="images/bbox_...">),不会转写印章内文字,这与 GLM-OCR 现状类似(虽然它有 seal 专用 prompt,效果也一般,所以仓库额外做了 seal_supplement + SealOCRRecognizer(MinerU 印章专用 OCR:seal_PP-OCRv4_det + 低阈值识别)兜底)。
  • 建议:印章检测与识别继续用现有专用模块(seal_ocr_adapter.py),不要指望 OvisOCR2。

5. 接入方案建议

推荐:作为新增 vl_recognition 适配器接入,不做整页端到端替换

  1. 部署:用 vLLM 起 OpenAI 兼容服务(与 MinerU-VL/GLM-OCR 一致):

    vllm serve ATH-MaaS/OvisOCR2 --port <port> --gpu-memory-utilization 0.8
    
  2. 新增适配器 models/adapters/ovisocr2_vl_adapter.py,继承 BaseVLRecognizer(见 base.py 第 651 行):

    • recognize_table():传入裁剪出的表格区域图,用官方固定 prompt 调用,从返回文本中正则提取 <table>...</table> 片段作为 htmlcells: [] 交给 TableCellMatcher 补全。
    • recognize_formula():类似地从返回 Markdown 中抽取 LaTeX 片段。
    • 由于没有任务级 prompt,需要在适配器里对返回内容做后处理裁剪(正则提取 <table>/LaTeX 部分),过滤掉多余的正文说明文字。
  3. 注册core/model_factory.pycreate_vl_recognizer:新增 elif module_name == 'ovisocr2': 分支。

  4. 新增配置 config/bank_statement_ovisocr2_vl.yaml,复制 bank_statement_glm_vl.yaml 结构,只替换 vl_recognition 段的 module/api_url/model,其余 layout/方向/印章/表格分类段保持不变。

  5. 分辨率注意max_pixels=2880*2880 对裁剪后的单表格/单区域小图影响不大,但整页直喂容易在密集小字表格上丢字,不建议整页直喂,优先沿用"裁剪表格区域后单独识别"的现有模式。

可选:额外做一个独立端到端小工具(参考 dots.ocr_vl_toolmineru_vl_toolmain.py/processor.py 结构),用于快速整页 Markdown 预览、或不需要精确单元格坐标的非结构化文档(合同、报告等)。这类场景不需要 layout/朝向/印章管线,直接调用整页 parse 即可,发挥其"小、快、OmniDocBench SOTA"的优势。

风险提示

  • 0.8B 参数量偏小,在银行流水这类密集小字、复杂合并单元格场景上的精度需要用现有测试集(data/流水典型表样数据 等)实测验证后再决定是否替换 GLM-OCR/MinerU-VL。
  • 无分任务 prompt,效果依赖对整页通用 prompt 输出的后处理解析,建议先写小脚本跑几张真实银行流水表格测试提取稳定性。

6. 能否用 llama.cpp 转 GGUF?—— 只能转文本骨干,视觉塔(mmproj)官方不支持

结论:只能转一半。OvisOCR2 的文本骨干(Qwen3.5-0.8B)可以用 convert_hf_to_gguf.py 正常转成 GGUF,但真正让它"看图"的视觉塔/多模态投影层(--mmproj)目前官方 llama.cpp 并不支持 Ovis 系列架构的胶水层,不能简单一键转出可用的多模态 GGUF。

证据

  1. bartowski 的量化包bartowski/ATH-MaaS_OvisOCR2-GGUF,用 llama.cpp b10068 release 转的)只发布了纯文本权重Architecture: qwen35),完全没有 mmproj 文件。像 bartowski 这样成熟的量化维护者不带 mmproj,基本可以判断当前官方 llama.cpp 转不出(或转出来跑不了)Ovis 的视觉部分。
  2. llama.cpp 官方仓库两个直接相关的 issue:

都显示状态是"因 14 天无活动被 stale bot 自动关闭",并非功能真正合并完成。核心贡献者 wsbagnsv1 在 2025-08-23 明确说:"ViT 架构本身已经有了,但 ViT 输出对接到 Qwen 的'胶水层'还没搞定,我转出了 gguf 但还没法量化,因为这部分 arch 我自己还没实现"。也就是说截至目前,Ovis 系列(Ovis2 / Ovis2.5,OvisOCR2 同源架构只是换了 Qwen3.5 底座)的视觉编码器转换在官方主线里没有完全合并

  1. 第三方仓库 Abiray/OvisOCR2-GGUF 虽然放出了 mmproj-F16/F32/BF16,但结合上面 issue 的进展看,大概率基于某个非主线分支/自制 patch产出,官方发行版 llama.cpp(llama-mtmd-cli 或旧的 llama-llava-cli/llama-minicpmv-cli)不一定能正确识别和推理,其模型卡引导语也比较含糊("depending on your build version"),需自行验证效果,不能默认当作官方支持的稳定路径。

技术原因

convert_hf_to_gguf.py--mmproj 分支依赖模型架构在脚本里显式注册一个 MMPROJ 转换类(get_model_class(arch, mmproj=True))。Ovis 系列用的是"Visual Tokenizer + Visual Embedding Table(VTE)"这种和主流 LLaVA 风格(CLIP + MLP projector)不同的连接方式,官方目前没有登记这个转换器,直接跑:

python convert_hf_to_gguf.py <OvisOCR2目录> --mmproj

大概率会报 Model ... is not supported 或直接失败。

建议

  • ocr_platform 生产接入:仍然按第 5 节走 vLLM(OpenAI 兼容 HTTP server)部署,这是模型卡官方验证过的路径,也和仓库里 MinerU-VL/GLM-OCR 现有 HTTP adapter 模式一致,接入成本最低、结果可靠。
  • 如果确实需要 llama.cpp / 纯 CPU 或边缘部署
    1. 先用 convert_hf_to_gguf.py 把 Qwen3.5 文本骨干单独转出来验证没问题;
    2. 视觉部分建议直接试用 Abiray 现成的 mmproj 文件,但先在一两页真实业务图上跑通 llama-mtmd-cli 验证输出质量,不要直接上生产,因为它不是官方保证支持的路径;
    3. 关注 #14552 后续是否有人真正合并 Ovis 视觉支持的 PR。
  • 不建议自己从零写 Ovis 的 --mmproj 转换器,工作量接近重新实现一遍 vision-to-LLM 的对接层,性价比低。

7. 结论汇总

问题 结论
是否还需要 layout/朝向模型 需要,OvisOCR2 只替换 vl_recognition 环节
能否返回单元格坐标 不能,需复用 TableCellMatcher 做文本匹配
能否识别印章 不建议依赖,继续用 SealOCRRecognizer + seal_supplement
能否用 llama.cpp 转 GGUF 文本骨干可以,视觉塔(mmproj)官方暂不支持,生产建议走 vLLM