个人电脑玩AI-08让5060 Ti给你打工——我拿 Unlimited-OCR扫了 600 页书,然后悟了

by 雪隐_上班了 from juejin.cn/user/143341...

欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可联系授权。

前言:我拿 VLM 扫了 600 页书,然后悟了

先说结论------Unlimited-OCR 是我目前用过单页效果最强的文档解析工具,没有之一。 但如果你听信某些教程,去试它所谓的"多页批处理"接口,那大概率会在第 3 页就看着显存飙红、程序崩掉。正确且唯一有效的姿势,就是写个 for 循环,一页一页地喂,让它每页都"失忆"一次。 我就是用这种"笨方法",在 5060 Ti 16G 上成功啃完了 600 多页排版爆炸的技术书,输出 Markdown 质量吊打 PaddleOCR 十条街。

下面把我的血泪经验全摊开,包括为什么必须逐页循环、怎么把 600 页跑稳、以及合并脚本怎么写,顺便吐槽一下那些"伪多页"的坑。


第一铁律:OCR 就是 OCR,别让它干编辑的活

这条是我用爆显存换来的教训,必须写在最前面:

OCR 只负责"抄写",别在 prompt 里加"总结"、"纠错"、"翻译"等任何私货。

你敢让它多嘴,它就敢让你显存原地升天。

PaddleOCR 这么干过,崩了;Unlimited-OCR 我也试过,加了 "请修正错别字",单页推理从 5 秒变 30 秒,显存从 10G 飙到 15.8G,第三页直接 OOM。所以我的 prompt 永远焊死成官方原版:

python 复制代码
prompt='<image>document parsing.'   # 多一个单词都不要!

错别字、逻辑问题,那是人眼和 LLM 的事,别在 OCR 这一步瞎操心。


为什么我抛弃 PaddleOCR,死磕 Unlimited-OCR?

PaddleOCR 快是快,但面对多栏、表格、公式,它吐出来的就是一坨"线性文字"------左栏读到一半跳右栏,表格变成空格分隔的灾难,公式全成乱码。我花在"修复结构"上的时间,比跑 OCR 本身还多。

而 Unlimited-OCR 是端到端的 VLM,直接输出带 Markdown 结构的文本:

  • 标题自动分层(######
  • 表格转成标准 Markdown 表格
  • 公式转成 LaTeX 风格($...$
  • 多栏自动分左右,不串行

单页效果简直是艺术品。但问题来了------怎么把艺术品安全地拼成 600 页的"连环画"?


大坑:官方"多页模式"是个纸老虎

我在网上看到有人吹 Unlimited-OCR 可以直接传 PDF 路径,内部自动处理多页。于是我也试了试,结果:

  • 显存爆炸:一次性加载所有页面,16G 根本 hold 不住,跑到第 10 页就 OOM。
  • 输出混乱:即使侥幸跑完,输出的 Markdown 把所有页面揉在一起,标题序号错乱、表格断页、公式跨页分裂,根本没法用。
  • 速度感人:内部 batch 推理没做优化,比单页循环还慢。

后来翻源码才明白,官方那个"多页"其实就是把 PDF 转成图片列表,然后 for 循环调用同一个模型------但它没有做任何显存管理和输出聚合,效果还不如我们自己写循环。所以我的结论是:

Unlimited-OCR 的"单页模式"才是唯一正确的打开方式。多页场景请自己写循环,别指望官方黑盒。


我的"笨方法":逐页循环,稳如老狗

既然官方靠不住,那就自己动手。我的完整流水线如下:

1. PDF 转图片(用 PyMuPDF 或 pdf2image)

python 复制代码
import fitz  # PyMuPDF
pdf = fitz.open("book.pdf")
for page_num in range(len(pdf)):
    page = pdf[page_num]
    pix = page.get_pixmap(dpi=200)
    pix.save(f"page_{page_num+1:03d}.png")

2. 逐页调用 Unlimited-OCR(千万别开任何"批处理"参数)

python 复制代码
for page_num in range(1, total_pages+1):
    img_path = f"page_{page_num:03d}.png"
    model.infer(
        tokenizer,
        prompt='<image>document parsing.',   # 焊死!
        image_file=img_path,
        output_path=f"./output/page_{page_num:03d}",
        base_size=1024,
        image_size=640,
        crop_mode=False,          # 书本排版整齐,关掉更省显存
        max_length=32768,
        no_repeat_ngram_size=35,
        ngram_window=128,
        save_results=True,
    )
    # 每页跑完清一下缓存,防止碎片堆积
    torch.cuda.empty_cache()

关键点

  • 每页独立输出一个 .md 文件,文件名带页码。
  • crop_mode 我关掉了,因为书本排版规整,切块反而容易出边界幻觉,而且费显存。
  • 每页推理完手动清缓存,保证显存曲线平稳。

3. 合并脚本(灵魂所在)

光输出一堆碎片文件没用,必须合并成一本完整的 Markdown。我的合并脚本做了这几件事:

  • 按页码顺序读取所有 .md 文件。
  • 重新编号标题 :因为每页的 # 都从 1 开始,所以要全局统计,把 # 1. 变成 # 1.,第二页的 # 1. 自动变成 # 2.,子标题同理。
  • 拼接跨页表格 :如果上一页末尾是 |--- 且下一页开头是 |---,说明表格被切断,合并成一个大表格。
  • 处理图片引用 :把每页内的图片路径统一改成相对路径(比如 ![img](./page_001_01.png))。

整套脚本跑完,600 页直接变成一个 5MB 的 book.md,导入 Obsidian 后大纲清晰,搜索公式、跳转章节丝般顺滑。


为什么逐页循环反而比"批处理"更好?

  1. 显存可控:每页处理完释放,不会累积。
  2. 输出干净:每页独立,合并脚本可以精准控制标题编号和跨页元素。
  3. 容错性强:万一某页崩了,只需要重跑那一页,不用全部重来。
  4. 可以并行:如果你有多张卡,可以分页并行跑,但我一张 5060 Ti 串行也够用。

给后来者的终极忠告

  • 千万别用官方任何"多页"或"批量"参数 ,那都是坑。老老实实 for 循环。
  • Prompt 打死不加戏 ,就 document parsing,别想着让 OCR 做总结。
  • 合并脚本值得投资,写一次,以后所有书都能复用。
  • 5060 Ti 16G 在这个场景下非常够用,别被那些说"必须 A100"的吓到。

最后,为"单页循环"正名

有人说"逐页循环太 low,不够智能",但我想说------在 GPU 资源有限的情况下,稳定、可控、高质量,比花里胡哨的"原生多页"重要一万倍。 我用这套流水线处理了 600 页,成果是一份可以直接出版级的 Markdown 文档,而某些"高级批处理"可能连 50 页都跑不下来。

所以,如果你也想用 Unlimited-OCR 处理多页文档,别犹豫,直接上循环。代码我都给你备好了,拿去抄就行。


本章代码(含 PDF 转图、逐页 OCR、合并脚本)已上传至 Gitee

相关推荐
AskHarries1 小时前
用 OpenClaw 做一份完整 PPT:从主题、提纲到 slide deck
后端·程序员
Coffeeee1 小时前
Prompt要花心思写,与 AI 对话的七个技巧
人工智能·aigc·ai编程
Csvn1 小时前
Linux 常用操作命令合集与运维实战
后端
卷无止境2 小时前
现代C++ 编译器生态及其对编程规范的影响
后端
蝎子莱莱爱打怪2 小时前
Claude Code 官宣新升级:子智能体默认后台跑,你边聊它边干活
人工智能
云技纵横2 小时前
一个 @Async,把 @Transactional 的事务边界打穿了
后端·面试
武子康2 小时前
调查研究-206 DeepSeek DSpark 深度解析:大模型推理加速,正在从“模型能力”转向“系统工程”
人工智能·agent·deepseek
BothSavage2 小时前
OpenHarness源码研究-3-codex配置到输出对话
后端·架构
SimonKing2 小时前
Google第三方授权登录
java·后端·程序员