RetainPDF 公式保留原理详解:复杂行内公式在翻译后依然稳定的完整实现思路
【免费下载链接】retain-pdf在保留版面、公式与结构的前提下进行 PDF 翻译,适用于科研与技术文档项目地址: https://gitcode.com/gh_mirrors/re/retain-pdf
RetainPDF 是一款专注科研与技术文档的 PDF 翻译工具,它的核心能力是在保留版面、公式与结构的前提下完成整篇翻译。很多开源 PDF 翻译方案一遇到数学公式就会"翻车":行内公式被拆开、上下标错位、LaTeX 源码被大模型改写,甚至整段公式被当成普通文字翻译。本文基于 RetainPDF 的源码与文档,拆解它"公式保留"背后的完整实现思路:从 OCR 识别、占位符保护、原文擦除,到排版安全边距,一共四道防线,帮你理解复杂行内公式为什么在翻译后依然稳定。
一、为什么 PDF 翻译里的公式最难保住
先看图感受一下"科研文档 + 公式"的典型场景——这是一篇物理化学论文的首页,摘要里就混排着行内公式与符号:
公式之所以难保留,根源在于翻译流水线的工作方式:它要重写文字,但绝不能重写公式。难点集中在三处:
| 难点 | 典型失败表现 |
|---|---|
| 识别不准 | 行内公式被当成普通文字送进翻译,E_g^{dir}被"翻译"成乱码 |
| 大模型改写 | LLM 顺手"修正"LaTeX,花括号被替换、下标被拍平 |
| 原文擦除误伤 | 擦掉英文原文时把公式一起删了,或者留白不干净 |
RetainPDF 的思路不是"把公式修到最漂亮",而是每一层都只做低风险、可解释的操作。下面按数据流向逐层拆解。
二、第一道防线:识别层——分清"行内公式"和"独立公式"
一切始于 OCR 输出。RetainPDF 默认消费 MinerU 的middle.json(含真实页面坐标),并在适配层把 provider 标签投影成自己的类型体系。规则非常明确(见 output-types.md):
inline_equation→ 归一为文本 span 里的inline_formula片段,留在段落内,随所在文本块一起走渲染,但不单独送翻译;interline_equation/equation→ 独立formula块,整体不送翻译。
这个投影决策由 NORMALIZATION.md 中的 label 映射全表锁定:公式块打上formula标签并跳过翻译,未知标签则保守归为元数据而非静默丢弃。识别层的意义在于——公式从此有了独立身份,后续每一层都能"认出"它、避开它。
三、第二道防线:保护层——占位符隔离,让大模型"看不见"公式
行内公式真正危险的时刻是"进入翻译 prompt 的那一刻"。RetainPDF 的做法是把公式从文本里临时摘走,换成机器可识别的占位符。
核心实现在 protected_formula_tokens.py 与 formula_protection.py:
- 用 LaTeX 结构特征(
_、^、花括号、希腊字母串、\frac等命令)识别候选公式片段; - 将命中的片段替换为占位 token(如
@@F1@@、[[FORMULA_1]]这类带类型前缀的短标记),原文记入formula_map; - 大模型只负责翻译"夹着占位符"的散文,输出后按
formula_map把原始 LaTeX原样回填。
这一步的价值:LLM 从头到尾没有机会接触公式源码,"模型手滑改写公式"这类不可控风险被直接物理隔离了。
四、第三道防线:擦除层——只删原文文字,不动公式像素
翻译完成后要渲染回原 PDF,需要先把英文原文擦掉再叠上译文。擦除策略由render.source_cleanup_strategy控制(见 source-cleanup策略.md):
pikepdf_text_strip(默认):在 PDF 内容流层面做 text-op 物理删除,再用 Typst 渲染的翻译块做视觉覆盖;typst_fill:不做物理删除,仅用背景块覆盖原文,适合删除策略不适用的 PDF。
针对"擦除文本带时覆盖到公式"的极端情况,仓库里还保留了一个很有启发性的实验 redact_restore_formula.py:
- 先对大条文本带做 redaction(删文字,保留图片与矢量线);
- 再定位所有与删除带相交的公式区域;
- 用
show_pdf_page把原 PDF 里的公式区域作为矢量 Form XObject 原片贴回。
也就是说:就算文字带把公式盖住了,公式也是从原文件"按矢量坐标"裁下来还原的——不截图、不重绘、不失真。
五、第四道防线:排版层——给上下标公式留足呼吸空间
公式保留还不止于"不删不改"。下标、上标、分式在重排时很容易被行框裁掉。formula_safety.py 专门解决这件事:
- 检测公式是否含"深结构"(
_、^、\frac、\sqrt、\sum、\int等); - 含深结构的公式,行框上下安全边距按字号放大(底部边距最高可到约 2.6pt);
- 超长行内公式还会检查宽度占比,触发"跨行布局风险"处理,避免硬塞进原行。
效果体现在这类混排页面:表格、行内表达式(如[BMIM][BF4]、\Delta G符号)在翻译后依然完整落在原位,上下标不被裁切:
翻译块的叠印渲染采用 Typst 完成,选型理由可参考 ADR-0002:使用 Typst 做叠印渲染。
六、LaTeX 保守修正原则:宁可少修,不过修
OCR 输出的公式本质是"LaTeX-ish"文本:\mathrm { C H }、x _ { i , j }这类被空格打散的写法很常见。RetainPDF 的修正策略写在 formula_safe_rules.md 中,边界感极强:
| 允许 | 禁止 |
|---|---|
收紧\mathrm { C H }→\mathrm{CH}这类低风险格式 | 全局"{ → ("、"} → )"字符串替换 |
收紧a _ { b }→a_{b}的原子绑定 | 未确认语法边界时改写\frac、\left...\right |
数字内部空格收紧(1 . 2 7→1.27) | 按长度或字符集"猜测"复杂公式结构 |
处理顺序也是结构化的:先收紧下标/上标绑定,再递归处理花括号组内内容。如果复杂结构已经能渲染,优先保持原样;渲染失败时只做定向清理,不做激进改写。
七、小结:四道防线各司其职
| 层次 | 关键机制 | 回答的问题 |
|---|---|---|
| 识别层 | MinerU 标签投影为inline_formula/formula | 公式是公式,不是文字 |
| 保护层 | 占位符 +formula_map回填 | 大模型碰不到公式源码 |
| 擦除层 | 内容流删字 + 矢量区域原片还原 | 删原文不误伤公式 |
| 排版层 | 深结构检测 + 安全边距 | 上下标不被行框裁掉 |
这套设计没有依赖"更聪明的模型",而是把风险逐层切分到工程可控的地方——这也是它能在科研文档这类公式密集场景保持稳定输出的原因。
八、延伸资料
- MinerU 官方输出类型与归一化基线:output-types.md
- 公式安全修正规则:formula_safe_rules.md
- 渲染参数与原文擦除策略:01-渲染参数.md、02-source-cleanup策略.md
- 公式占位保护源码:protected_formula_tokens.py
- 排版安全边距源码:formula_safety.py
如果你想在自己的科研论文上验证效果,创建一个翻译任务、观察最终 PDF 中行内公式与独立公式的呈现即可;遇到特殊版式时,可切换到typst_fill擦除策略做对照。
【免费下载链接】retain-pdf在保留版面、公式与结构的前提下进行 PDF 翻译,适用于科研与技术文档项目地址: https://gitcode.com/gh_mirrors/re/retain-pdf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考