GLM-OCR ResultFormatter详解:公式合并、文本合并、列表格式化后处理四步曲
【免费下载链接】GLM-OCRGLM-OCR: Accurate × Fast × Comprehensive项目地址: https://gitcode.com/GitHub_Trending/gl/GLM-OCR
GLM-OCR 是一款主打“精确 × 快速 × 全面”的开源多模态 OCR 模型,而 ResultFormatter 是它识别管线中最后一道"精装修"工序:把模型吐出的原始识别结果,经过公式合并、文本合并、列表格式化等后处理四步曲,打磨成干净、可直接使用的 JSON 与 Markdown。这篇完整指南将带你快速看懂这套后处理机制,哪怕你是 OCR 新手也能一次搞懂。
为什么 OCR 结果需要"后处理"?
GLM-OCR 的两阶段管线(版面分析 + 并行识别)会先把文档切成一个个区域(标题、正文、公式、表格、图片……),再逐区域识别。但模型的原始输出往往"毛糙":
- 数学公式和右下角的编号
(1)被识别成两个独立文本块; - 英文换行处的连字符把
state-of-the-art拆成了state-+of-the-art两块; - 列表中间某一项漏掉了项目符号
-。
上图为 GLM-OCR 对论文首页的版面识别结果,每个色块都标注了区域类型(doc_title、abstract、chart、figure_title等)。这些原始区域标签正是后处理的起点。ResultFormatter继承自 base_post_processor.py 中的基类,负责把区域结果统一格式化为JSON + Markdown 双输出(见 config.yaml 中的 output_format 配置)。
后处理四步曲总览
在 process 方法 中,每一页的区域结果会依次经过四道工序:
| 步骤 | 方法 | 作用 | 默认开关 |
|---|---|---|---|
| ① 内容清洗与规范化 | _clean_content/_format_content | 去重复标点、修正常式、统一$$公式与标题#前缀 | 始终执行 |
| ② 公式编号合并 | _merge_formula_numbers | 把formula_number用\tag{}并入相邻公式 | ✅ 开启 |
| ③ 文本块合并 | _merge_text_blocks | 合并英文连字符断词的相邻文本块 | ✅ 开启 |
| ④ 列表项格式化 | _format_bullet_points | 给漏了符号的列表项自动补- | ✅ 开启 |
三步开关均可在 ResultFormatterConfig 中配置,对应 config.yaml 的 result_formatter 段,全部默认开启。
第一步:内容清洗与格式规范化
这是"打底"工序,_clean_content 方法 会:
- 去掉行首行尾的
\t字面量和多余空格; - 压缩连续重复的标点(如
...之外的....、____); - 对超长文本调用 clean_repeated_content,检测并截断模型"复读机"式重复;
- 通过 normalize_inline_formula 把
$ x $规范成$x$,并在行内公式两侧补空格。
随后 _format_content 方法 按区域类型做针对性排版:doc_title前缀#、paragraph_title前缀##、公式统一包裹为$$...$$多行形式、正文补齐未闭合的代码块```、把(1)、2)这类编号后统一补一个空格。
第二步:公式编号合并
论文里公式和右下角编号常被识别为两个区域。_merge_formula_numbers 方法 会同时处理"编号在后"和"编号在前"两种顺序:先用 clean_formula_number 剥掉(1)、(2.1)的括号,再在公式末尾插入\tag{1}。
上图中这类含行内公式与编号(1)(2)的数学题页面,正是公式编号合并的典型场景——合并后每个编号都会贴回自己的公式,渲染出的 Markdown 里公式与编号一一对应。
第三步:连字符文本块合并
英文文档中,长单词常在换行处被连字符断开,布局切块后变成两个文本块。_merge_text_blocks 方法 的策略很稳健:
- 只处理"以
-结尾"的文本块; - 找到下一个以小写字母开头的文本块;
- 把两块边界处的词片段拼起来,用 _is_likely_valid_merged_word 验证——优先调用
wordfreq词频库判断是否是真实英文单词,未安装时退化为轻量正则启发式,避免把e-mail这类真连字符误合并。
验证通过才合并,合并后重新分配index,保证输出顺序稳定。
第四步:列表项自动补全项目符号
!示例:含编号列表的文档页面
上图这类"1. 2. 3. 4."编号列表页面最容易踩坑:某一项识别时漏了序号或符号,列表就显得断裂。_format_bullet_points 方法 的判定条件是:
- 当前文本块的前一个和后一个文本块都以
-开头; - 三者的左边界 x 坐标互差不超过 10 像素(
left_align_threshold),即视觉上左对齐;
同时满足,就给当前块补上-前缀。这样列表在 Markdown 里重新变成连续条目。
输出:JSON 与 Markdown 双格式
四步曲跑完后,process 方法 会生成两份结果:
- Markdown:按阅读顺序拼接正文、公式、表格,图片区域则被裁剪保存为
imgs/cropped_page{页}_idx{序}.jpg并转成...引用,例如 examples/result/GLM-4.5V/imgs/ 下的这些裁剪图; - JSON:保留每个区域的
index、label、content、bbox_2d,适合程序化消费,样例见 examples/result/paper/paper.json。
如上图这类纯图片区域(image标签)不会强行转文字,而是保留原图、在 Markdown 中直接嵌入——这也是process中_is_image标记要单独处理的原因。
想关掉某一步?改一行配置即可
三个开关全部集中在 config.yaml:
enable_merge_formula_numbers: true— 公式编号合并enable_merge_text_blocks: true— 连字符文本块合并enable_format_bullet_points: true— 列表项符号补全
处理英文为主的文档可以全开;处理以中文为主、几乎没有连字符断词的文档时,也可以按需关闭某一步。单元测试覆盖了这些分支,可参考 test_unit.py 中的 ResultFormatter 用例,最终效果可以在 examples/result/ 下的paper.md、code.md、handwritten.md等成品中直接对照。
小结
ResultFormatter 用四步后处理——清洗规范 → 公式编号合并 → 连字符文本合并 → 列表符号补全——把 GLM-OCR 的原始识别区域"精装修"成人类爱读的 Markdown 和机器好用的 JSON。它默认全开、逐项可配,既照顾了论文、代码、手写等复杂版面的识别质量,又几乎不增加额外调用成本。理解这四个开关,你就掌握了 GLM-OCR 输出质量调优的第一把钥匙。
【免费下载链接】GLM-OCRGLM-OCR: Accurate × Fast × Comprehensive项目地址: https://gitcode.com/GitHub_Trending/gl/GLM-OCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考