{"notes":[{"id":"text-spotting/olmocr","category":"text-spotting","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"olmOCR","subtitle":"给模型一份小抄","author":"Z. Yuan","paperDate":"2025-02-25","publishedOn":"2026-02-03","paperTitle":"olmOCR: Unlocking Trillions of Tokens in PDFs with Vision Language Models","paperUrl":"https://arxiv.org/abs/2502.18443","bibliography":{"title":"olmOCR: Unlocking Trillions of Tokens in PDFs with Vision Language Models","authors":["Jake Poznanski","Aman Rangapur","Jon Borchardt","Jason Dunkelberger","Regan Huff","Daniel Lin","Aman Rangapur","Christopher Wilhelm","Kyle Lo","Luca Soldaini"],"url":"https://arxiv.org/abs/2502.18443","pdfUrl":"https://arxiv.org/pdf/2502.18443v3","codeUrl":"https://github.com/allenai/olmocr","preprint":{"id":"2502.18443","submittedOn":"2025-02-25","url":"https://arxiv.org/abs/2502.18443"},"publication":null,"citation":"@misc{textspottingolmocr2025,\n  title = {{olmOCR: Unlocking Trillions of Tokens in PDFs with Vision Language Models}},\n  author = {Jake Poznanski and Aman Rangapur and Jon Borchardt and Jason Dunkelberger and Regan Huff and Daniel Lin and Aman Rangapur and Christopher Wilhelm and Kyle Lo and Luca Soldaini},\n  year = {2025},\n  eprint = {2502.18443},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2502.18443}\n}\n","citationPath":"/content/papers/citations/text-spotting/olmocr.48e77a79a2cb.bib"},"thumbnail":{"src":"/content/papers/assets/044c3df431d57e98d00da32fff3b3df21f0cad1cb9a2e9176487efa55b628c17.png","width":994,"height":622},"locale":"zh-hans","path":"/content/papers/zh-hans/text-spotting/olmocr.4ed8c4526a2e.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"document-anchoring把-pdf-里的字一起交给模型","text":"Document anchoring：把 PDF 里的字一起交给模型","depth":3},{"id":"用-gpt-4o-生成训练数据","text":"用 GPT-4o 生成训练数据","depth":3},{"id":"微调一个-7b-的专用模型","text":"微调一个 7B 的专用模型","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"olmocr-bench用单元测试打分","text":"olmOCR-Bench：用单元测试打分","depth":3},{"id":"拿来训练语言模型","text":"拿来训练语言模型","depth":3},{"id":"成本","text":"成本","depth":3},{"id":"社区的反应","text":"社区的反应","depth":3},{"id":"读这篇时要知道的事","text":"读这篇时要知道的事","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[]}],"text":"网上有数以万亿计的 PDF。论文、报告、说明书、政府文件，很多内容只存在于 PDF 里，网页上找不到。对要训练语言模型的团队来说，这是一座还没开采的矿。\n\n麻烦在于，PDF 生来就不是为了「读出文字」而设计的。\n\n它最初是用来描述「怎么把文档印到纸上」的。文件里存的不是标题、段落这些有意义的单位，而是一个个字形，加上它的字体、字号与坐标。论文 Figure 2 举了一个例子：标题「olmOCR」在 PDF 里是六条记录，每条一个字母，各带一个变换矩阵。哪个字先读、哪段接哪段，PDF 不管。\n\n艾伦人工智能研究所（Ai2）在 2025 年 2 月提出 olmOCR，目标是把大量 PDF 转成干净、按阅读顺序排列的纯文本。本文依据 2025 年 7 月的 v3 阅读，模型、训练数据与代码都以宽松许可开源。\n\n## 定义问题\n\n当时的做法大致分两派：\n\n- **流水线式工具**，例如 MinerU、Marker，把版面分割、表格解析等多个模型串在一起；GROBID、PaperMage 这类则专门处理学术论文。\n- **端到端模型**，例如 Nougat、GOT，输入页面图像，直接输出文本。\n\n作者指出，端到端模型只看图像，等于放弃了一样东西：**很多 PDF 本来就是原生数字的，里面已经有文字**。这些文字虽然乱，却是正确的字。\n\n另一方面，直接拿 GPT-4o 这种通用 VLM 来读，质量也不够。作者观察到，在文字密集或版面复杂的页面上，只靠图像的 GPT-4o 容易漏掉内容、改写或「补全」原文，没被要求时还会给图片配上说明。附录写得更具体：只给页面图像时，模型会把没写完的句子补完，图像含糊时甚至会编出更长的文字。\n\n所以问题变成：能不能让 VLM 在看图像的同时，也拿到 PDF 里的文字作为参考？\n\n## 解决问题\n\n### Document anchoring：把 PDF 里的字一起交给模型\n\n[![document anchoring 示意：左侧是一页 PDF，右侧是从中提取的锚定文本，包含页面尺寸、图片位置，以及带坐标的文本块，例如「[71x459]Figure 1」、「[71x398]1 Introduction」](/content/papers/assets/044c3df431d57e98d00da32fff3b3df21f0cad1cb9a2e9176487efa55b628c17.png)](/content/papers/assets/044c3df431d57e98d00da32fff3b3df21f0cad1cb9a2e9176487efa55b628c17.png)\n\n*原论文 Figure 3，取自 [**v3 PDF 第 17 页**](https://arxiv.org/pdf/2502.18443v3#page=17)，CC BY 4.0。左为 PDF 页面，右为插入提示词的锚定文本。*\n\n右边那个框，就是作者说的 **document anchoring**。做法是：\n\n1. 用 pypdf 读取 PDF 的内部结构，取出每个文本块和图片，连同它们在页面上的坐标。\n2. 按优先级挑选文本块放进提示词，直到达到字数上限。文档开头与结尾的块优先，因为标题、摘要、页脚信息大多在那里。\n3. 把这段锚定文本和页面图像一起交给 VLM，请它输出这一页的纯文本。\n\n看图上的格式：`[71x459]Figure 1` 表示坐标 (71, 459) 处有一段文字「Figure 1」；`[Image 480x298 to 525x312]` 标出一张图片的位置。\n\n作者很坦白地说，这份锚定文本**很杂乱**：没有保留阅读顺序，正文和各种样板文字、PDF 渲染产生的噪声混在一起。但它提供了模型可以照抄的字，以及字在页面上的大概位置。VLM 负责看懂版面、排出顺序，PDF 文字负责把字钉住。\n\n如果页面是扫描件、没有内嵌文字，锚定文本就只剩页面尺寸与图片位置，模型主要靠图像来读。\n\n### 用 GPT-4o 生成训练数据\n\n有了锚定方法，作者先拿它来制作训练数据。\n\n他们在 2024 年 10 月比较了几个候选的「老师」模型：Gemini 1.5 经常返回 RECITATION 错误，GPT-4o mini 幻觉太多，Claude Sonnet 3.5 太贵。最后选了 `gpt-4o-2024-08-06`。\n\n提示词要求 GPT-4o 以结构化的 JSON 回答，先输出页面的语言、方向、是否有表格等元数据，再输出按阅读顺序排列的文本。作者发现，这个结构很关键，能让 GPT-4o 在页面没有文字时，不去给图片编说明。\n\n这样做出来的 **olmOCR-mix-0225** 共 258,641 页、102,825 份文档：其中 96,929 份是从约 2.4 亿份公开网页 PDF 中抽样得到，另有 5,896 份来自 Internet Archive 的公共领域书籍。按抽样估计，学术文档约占 56%，其次是宣传手册与法律文件。\n\n### 微调一个 7B 的专用模型\n\n用锚定提示词来指挥 GPT-4o 效果不错，但作者发现，它的效果因模型而异，比较适合当作生成数据的技巧。他们接着问：一个较小的专用 VLM，能不能做得和 GPT-4o 一样好？\n\n他们从 Qwen2-VL-7B-Instruct 出发，在 olmOCR-mix-0225 上微调约 1.2 个 epoch，用一台 8 张 H100 的机器训练了 16 小时。微调时，页面缩放到最长边 1,024 像素，锚定文本上限 6,000 个字符。一页的典型输入是：图像约 1,000 个 token，锚定文本约 1,800 个，合计约 3,000 个。\n\n## 讨论\n\n### olmOCR-Bench：用单元测试打分\n\n要比较 OCR 系统，作者不想用编辑距离这类「和参考答案有多像」的指标。他们举的例子是数学公式：$x$ 和 $x_i$ 的字符串只差一点点，意思却完全不同。\n\n所以他们做了 **olmOCR-Bench**：约 1,400 份 PDF、7,010 个通过／失败式的单元测试，每个测试都能由程序明确判定：\n\n- **文本存在**：某段一到三句的文字有没有出现在输出里。\n- **文本不存在**：页眉、页脚、页码这类边缘内容有没有被排除。\n- **阅读顺序**：两段文字的先后是否正确。例如同一页有好几篇新闻，可以只检查每篇的标题在第一句之前，不管各篇之间的顺序。\n- **表格**：存在某个值所在的单元格，而且它上方、左方的单元格符合预期。\n- **数学公式**：把参考的 LaTeX 用 KaTeX 渲染出来，记下每个符号的相对位置，再看输出里有没有一组符号排得一样。\n- **基本检查**：每页都有，确认有输出文本、结尾没有超过 30 个重复的 n-gram，也没有中日文或 emoji 字符。\n\n基本检查这一项，等于把「陷入重复」和「冒出不该有的文字」直接写成了必考题。\n\n\n> [!NOTE]\n> \n> 论文对这个基准的规模有三种写法：摘要写 1,400 份 PDF，§3 写 1,402 份，结论写 1,403 份。测试数都是 7,010。\n\n\n[![olmOCR-Bench 结果表：GOT OCR、Marker、MinerU、Mistral OCR API、GPT-4o、Gemini Flash 2、Qwen 2 VL、Qwen 2.5 VL 与 olmOCR 在 ArXiv、旧扫描件数学、表格、旧扫描件、页眉页脚、多栏、长篇小字与基本检查八个来源上的通过率与整体分数](/content/papers/assets/970cd043bba14de362481d37c8428e947780e9ec1c949f7846a8be7c4f58fbbf.png)](/content/papers/assets/970cd043bba14de362481d37c8428e947780e9ec1c949f7846a8be7c4f58fbbf.png)\n\n*原论文 Table 4，取自 [**v3 PDF 第 8 页**](https://arxiv.org/pdf/2502.18443v3#page=8)，CC BY 4.0。各列依次为 ArXiv、旧扫描件数学、表格、旧扫描件、页眉页脚、多栏、长篇小字、基本检查；整体分数是各来源的平均，附 95% 置信区间。*\n\n整体分数最高的是锚定版的 olmOCR，75.5；商用的 Mistral OCR API 是 72.0，Marker 是 70.1，MinerU 是 61.5，GOT 只有 48.3。作者特别说明，olmOCR-Bench 是在模型训练完**之后**才做的，以免反复对着基准调模型。\n\n表上有一组对照值得细看：**锚定对不同模型的帮助差别很大**。\n\n| 模型 | 不锚定 | 锚定 | 差距 |\n| --- | ---: | ---: | ---: |\n| GPT-4o | 68.9 | 69.9 | +1.0 |\n| Gemini Flash 2 | 57.8 | 63.8 | +6.0 |\n| olmOCR | 74.7 | 75.5 | +0.8 |\n\n对 olmOCR 自己来说，锚定只多了 0.8 分，落在置信区间附近。它真正的进步，主要来自用锚定做出来的训练数据：同样的 Qwen2-VL 基座模型，不微调只有 31.5 分。\n\n另外，olmOCR 在「旧扫描件」这一列只有 42.2，表格也只有 71.0 左右。扫描件没有内嵌文字可以锚定，仍然是难点。\n\n### 拿来训练语言模型\n\n作者也测了这些文本对语言模型有没有用。他们取 OLMo-2-7B 的一个中间检查点，各用 500 亿 token 继续预训练：一组是原本用 GROBID 加规则提取的 peS2o 学术论文，另一组是同一批 PDF 改用 olmOCR 重新处理的版本。\n\n在 MMLU、ARC、DROP、HellaSwag 等六项任务上，平均分从 53.9 升到 55.2，提高了 1.3 个百分点。\n\n### 成本\n\n| 系统 | 每百万页成本（美元） |\n| --- | ---: |\n| GPT-4o（批处理） | 6,240 |\n| Marker（H100） | 1,484 |\n| Mistral OCR API | 1,000 |\n| MinerU（L40S） | 596 |\n| Gemini Flash 2（批处理） | 249 |\n| olmOCR（L40S） | 176 |\n\n*表：节选自原论文 Table 6。L40S 按每小时 0.79 美元、H100 按每小时 2.69 美元估算，olmOCR 计入了 12% 的重试率。*\n\n摘要里「一百万页只要 176 美元」，指的是自己用 L40S 跑推理的估算。\n\n### 社区的反应\n\nolmOCR 在 2025 年 2 月 28 日登上 Hacker News，讨论串里有人直接点出生成式 OCR 的老问题：幻觉与结果不稳定。开发 Marker 的用户 vikp 回复说，他们在自己的测试集上看到 olmOCR 有不少漏字与幻觉，也质疑论文拿 Marker 的 API 价格和 olmOCR 的自部署推理成本相比，条件不对等。[Hacker News，2025-02-28](https://news.ycombinator.com/item?id=43174298)\n\nvikp 是竞品的开发者，他的立场要一并考虑；不过他指出的成本比较条件，确实可以在 Table 6 上看到：Marker 那一行是 H100 上的强制 OCR 模式，olmOCR 那一行是 L40S。\n\n### 读这篇时要知道的事\n\n1. **训练数据来自 GPT-4o**。olmOCR 学的是 GPT-4o 在锚定提示下的输出，老师的错也可能一起学了过来。作者在附录里另外测量了学生和老师的一致程度。\n2. **基准是自己做的**。olmOCR-Bench 的设计很有参考价值，但最早的比较结果来自作者自己。\n3. **锚定依赖 PDF 的质量**。原生数字的 PDF 效果最好；纯扫描件没有内嵌文字可用。\n\n## 结论\n\nolmOCR 的核心是一个很朴素的想法：**PDF 里已经有字了，就给模型看**。\n\n1. **Document anchoring** 把 PDF 内嵌的文字与坐标放进提示词，让 VLM 有可以照抄的字。\n2. **用锚定做数据、再微调小模型**：26 万页 GPT-4o 标注，加上 7B 的 Qwen2-VL，整体分数超过了 GPT-4o 本身。\n3. **olmOCR-Bench 用单元测试取代相似度**，把重复、漏字、阅读顺序都写成可以自动判定的题目。\n\n生成式 OCR 最大的风险，是它在看不清楚时会自己补字。olmOCR 给出的答案之一是：先找找看，有没有不必猜的字可以用。\n","imageSizes":{"/content/papers/assets/044c3df431d57e98d00da32fff3b3df21f0cad1cb9a2e9176487efa55b628c17.png":{"width":994,"height":622},"/content/papers/assets/970cd043bba14de362481d37c8428e947780e9ec1c949f7846a8be7c4f58fbbf.png":{"width":1394,"height":527}}}
