PaddleOCR 印刷数学公式识别:LaTeX-OCR 算法从训练到部署完整实战指南
2026/9/11 21:12:55 网站建设 项目流程

PaddleOCR 印刷数学公式识别:LaTeX-OCR 算法从训练到部署完整实战指南

【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR

本文基于 PaddleOCR 仓库中 LaTeX-OCR 印刷数学公式识别算法文档,系统讲解从数据集准备、模型训练与评估,到 Python 推理部署的完整流程。读者将掌握 LaTeX-OCR 的 Hybrid ViT 骨干网络与自回归解码原理、pickle 标签文件生成方法、配置文件关键参数含义,以及如何将公式图片准确转换为 LaTeX 代码供下游任务使用。

1. 算法简介

LaTeX-OCR 是开源社区著名的印刷数学公式识别(Image-to-Markup)方案,原始项目由 lukas-blecher 维护。PaddleOCR 使用 LaTeX-OCR 印刷公式数据集 训练该算法,并在其测试集上完成评估与复现。算法在 PaddleOCR 中的复现效果如下:

模型骨干网络配置文件BLEU scorenormed edit distanceExpRate下载链接
LaTeX-OCRHybrid ViTLaTeX_OCR_rec.yaml0.88210.082340.01%训练模型

表中三个指标分别衡量:

  • BLEU score(0.8821):预测 LaTeX 序列与标注序列的 n-gram 重合度,数值越高越好;
  • normed edit distance(0.0823):归一化编辑距离,反映字符级差异,数值越低越好;
  • ExpRate(40.01%):整条公式完全识别正确的比例(Exact Match Rate),是 LaTeXOCRMetric 中定义的main_indicator

2. 环境准备

2.1 基础环境

首先参考《运行环境准备》配置 PaddleOCR 运行环境,再参考《项目克隆》克隆项目代码。

2.2 额外依赖安装

LaTeX-OCR 训练与推理依赖以下额外 Python 包(见 requirements.txt):

pip install -r docs/version2.x/algorithm/formula_recognition/requirements.txt

该文件声明了四类关键依赖:

  • tokenizers==0.19.1:用于加载 latex_ocr_tokenizer.json 分词器。后处理类 LaTeXOCRDecode 在初始化时通过TokenizerFast.from_file()加载该词典,并设置TOKENIZERS_PARALLELISM=false以避免多进程分叉时出现死锁告警;
  • imagesize:在生成 pickle 标签文件时读取 PNG 图片的宽高(不实际解码像素),用于按尺寸分组;
  • ftfyWand:文本修复与 Wand 图像库,用于标签清洗和图像预处理链路。

3. 数据准备:pickle 标签文件生成

LaTeX-OCR 的训练/验证/测试数据以 pickle(.pkl)格式组织,将不同尺寸的公式图像按缩放后的宽高分组,从而在训练时对同组图片做批内拼接(batch 内多张图沿宽方向拼接为一张图送入网络)。

3.1 下载并解压原始数据

从 Google Drive 下载formulae.zipmath.txt,其中formulae.zip内含trainvaltest三个子目录的公式 PNG 图片,math.txt为与图片索引对应的 LaTeX 标注文件。然后执行:

# 创建 LaTeX-OCR 数据集目录 mkdir -p train_data/LaTeXOCR # 解压 formulae.zip,并拷贝 math.txt unzip -d train_data/LaTeXOCR path/formulae.zip cp path/math.txt train_data/LaTeXOCR

3.2 执行 txt2pkl 转换

转换脚本为 math_txt2pkl.py,核心逻辑是txt2pickle()函数:遍历--image_dir下的全部 PNG,用imagesize读取宽高,过滤掉超出min_dimensions=(32,32)max_dimensions=(672,192)的图片,然后将高度/宽度向上取整到 16 的倍数(divide_w, divide_h)作为 key,把(LaTeX标注, 图片文件名)追加到对应分组。

# 训练集转换 python ppocr/utils/formula_utils/math_txt2pkl.py --image_dir=train_data/LaTeXOCR/train --mathtxt_path=train_data/LaTeXOCR/math.txt --output_dir=train_data/LaTeXOCR/ # 验证集转换 python ppocr/utils/formula_utils/math_txt2pkl.py --image_dir=train_data/LaTeXOCR/val --mathtxt_path=train_data/LaTeXOCR/math.txt --output_dir=train_data/LaTeXOCR/ # 测试集转换 python ppocr/utils/formula_utils/math_txt2pkl.py --image_dir=train_data/LaTeXOCR/test --mathtxt_path=train_data/LaTeXOCR/math.txt --output_dir=train_data/LaTeXOCR/

生成的 pickle 文件按输入目录名命名,例如latexocr_train.pkllatexocr_val.pkllatexocr_test.pkl,并保存在--output_dir指定的目录下,与 LaTeX_OCR_rec.yaml 中Train.dataset.data/Eval.dataset.data的默认配置对应。

3.3 数据集加载机制

从源码看,LaTeXOCRDataSet 负责读取 pickle:

  • 加载时使用受限反序列化(_RestrictedDatasetUnpickler),仅允许dict/list/tuple/set/str/int/float/bool/bytes等基础类型,防止恶意 pickle 载荷执行任意代码;
  • batch_size_per_pair(训练 56、评估 10)在同一尺寸分组内取样本构成 pair,训练时不足一批的残余样本在keep_smaller_batches=False时被丢弃,评估时keep_smaller_batches=True予以保留;
  • __getitem__中先对批内每张图执行变换(含 LatexTrainTransform 的随机bitmap_prob位图化增强),再沿宽方向np.concatenate拼接成一张图,形状为[N, 1, H, W],随后由LatexOCRLabelEncode将 LaTeX 序列编码为 token 序列与 attention mask。

4. 配置文件解析

LaTeX_OCR_rec.yaml 是 LaTeX-OCR 训练与推理的唯一配置入口,PaddleOCR 对代码进行了模块化,训练该模型只需更换配置文件即可。核心参数如下:

配置段关键参数默认值说明
Globalmodel_nameLaTeX_OCR_rec模型名,静态图推理时使用
Globalepoch_num500最大训练轮数
Globalmax_seq_len512模型输出最大 token 长度(静态图推理上限亦为 512)
Globaleval_batch_step[0, 60000]每 60000 次迭代(约 22 epoch,batch_size=56)评估一次
Globalrec_char_dict_pathppocr/utils/dict/latex_ocr_tokenizer.json分词器词典路径
Globald2s_train_image_shape[1,256,256]训练动态图输入形状
Optimizername/lrAdamW/ Const0.0001优化器与恒定学习率
Architecture.BackbonenameHybridTransformer骨干网络
Architecture.Backboneimg_size[192, 672]输入图像尺寸(H, W)
Architecture.Backboneembed_dim/depth/num_heads256/4/8ViT 嵌入维度、层数与注意力头数
Architecture.HeadnameLaTeXOCRHead自回归解码头,支持attn_on_attncross_attendff_glu等 x-transformers 风格配置
LossnameLaTeXOCRLoss交叉熵损失
PostProcessnameLaTeXOCRDecodetoken 序列解码为 LaTeX 字符串
Metricname/main_indicatorLaTeXOCRMetric/exp_rate评估指标,cal_bleu_score: True同时计算 BLEU
Train.datasetdata_dir/data./train_data/LaTeXOCR/train/latexocr_train.pkl训练数据路径
Train.datasetmin_dimensions/max_dimensions[32,32]/[672,192]尺寸过滤与缩放范围
Train.loaderbatch_size_per_card/collate_fn1/LaTeXOCRCollator每卡 loader 批大小(pair 内拼接)

4.1 网络结构(Hybrid ViT + Transformer 解码器)

从 rec_hybridvit.py 与 rec_latexocr_head.py 的源码结构看:

  • 编码器HybridTransformerResNetV2backbone_layers=[2,3,7],使用StdConv2dSame卷积与 same padding)作为 stem 提取特征,再由HybridEmbed将特征图切分为 patch 并线性投影为embed_dim=256的 token 序列,随后送入 4 层、8 头的标准 ViT Block(含 cls token 与可学习位置编码),最终输出[N, 1, H//16, W//16]的特征;
  • 解码器LaTeXOCRHead实现自回归 Transformer 解码器,配置项attn_on_attn(注意力叠加)、cross_attend(跨模态注意力)、ff_glu(GLU 前馈)等均对应 x-transformers 的实现方式,训练时使用 teacher forcing 生成 token 序列。

4.2 损失函数

LaTeXOCRLoss 将解码器输出的词表概率word_probsreshape 为[-1, vocab_size],与右移一位的标签batch[1][:, 1:]计算带ignore_index=-100的交叉熵,返回{"loss": loss}供训练器使用。

5. 模型训练

5.1 单卡 / 多卡训练

在完成数据准备后,即可启动训练:

# 单卡训练(默认训练方式) python3 tools/train.py -c configs/rec/LaTeX_OCR_rec.yaml # 多卡训练,通过 --gpus 参数指定卡号 python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/rec/LaTeX_OCR_rec.yaml

训练日志、中间权重将按Global.save_model_dir(默认./output/rec/latex_ocr/)保存,save_epoch_step: 5表示每 5 个 epoch 保存一次 checkpoint。

5.2 评估节奏调整

配置默认每训练 22 个 epoch(60000 次 iteration,对应 batch_size=56)进行一次评估。若您更改了训练 batch_size 或更换数据集,请在训练时通过-o覆盖评估步长:

python3 tools/train.py -c configs/rec/LaTeX_OCR_rec.yaml -o Global.eval_batch_step=[0,{length_of_dataset//batch_size*22}]

即用“数据集样本数 ÷ 批大小 × 22”重新计算每次评估的迭代间隔。

6. 模型评估

可下载已训练完成的 模型文件,解压后得到rec_latex_ocr_train/目录,使用如下命令评估(注意将pretrained_model路径改为本地实际路径;若使用自行训练的模型,请修改路径与文件名为{path/to/weights}/{model_name}):

# GPU 评估,验证集 python3 tools/eval.py -c configs/rec/LaTeX_OCR_rec.yaml -o Global.pretrained_model=./rec_latex_ocr_train/best_accuracy.pdparams # 测试集评估:通过 -o 覆盖 Eval 数据路径 python3 tools/eval.py -c configs/rec/LaTeX_OCR_rec.yaml -o Global.pretrained_model=./rec_latex_ocr_train/best_accuracy.pdparams Eval.dataset.data_dir=./train_data/LaTeXOCR/test Eval.dataset.data=./train_data/LaTeXOCR/latexocr_test.pkl

评估过程由 LaTeXOCRMetric 完成:逐条比较预测与标签是否完全一致累计exp_rate,同时基于compute_edit_distanceLevenshtein.normalized_distance统计编辑距离,并在cal_bleu_score=True时用compute_bleu_score累计 BLEU 分数,最终返回exp_rateedit_distancebleu_score等指标(其中exp_rate是配置指定的主指标)。

7. 单张图片预测

使用训练好的模型对单张图片进行预测(配置必须与训练一致):

python3 tools/infer_rec.py -c configs/rec/LaTeX_OCR_rec.yaml -o Global.infer_img='./docs/datasets/images/pme_demo/0000013.png' Global.pretrained_model=./rec_latex_ocr_train/best_accuracy.pdparams

预测文件夹下所有图像时,可将infer_img改为文件夹路径,如Global.infer_img='./docs/datasets/images/pme_demo/'

注意事项

  • 预测图像须为白底黑字,即公式笔画为黑色、背景为白色;
  • 图片宽高建议在[32,32][672,192](宽 672、高 192)范围内,超出范围时推理代码会先做 pad 与等比缩放处理(见 predict_rec.py 的norm_img_latexocr);
  • 若修改了字典或预处理方法,需同步调整配置文件中的rec_char_dict_path以及 predict_rec.py 中 LaTeX-OCR 的预处理逻辑。

8. 推理部署

8.1 Python 推理(动态图转静态图)

首先将训练保存的 best 模型转换为 inference model。这里以官方训练好的模型为例:

python3 tools/export_model.py -c configs/rec/LaTeX_OCR_rec.yaml -o Global.pretrained_model=./rec_latex_ocr_train/best_accuracy.pdparams Global.save_inference_dir=./inference/rec_latex_ocr_infer/ # 静态图模型支持的最大输出长度为 512

注意

  • 若您在自己的数据集上训练并调整了字典文件,请检查配置中的rec_char_dict_path是否为所需词典;
  • 官方同时提供 转换后推理模型下载。

转换成功后,./inference/rec_latex_ocr_infer/目录下应包含三个文件:

/inference/rec_latex_ocr_infer/ ├── inference.pdiparams # 识别 inference 模型的参数文件 ├── inference.pdiparams.info # 识别 inference 模型的参数信息,可忽略 └── inference.pdmodel # 识别 inference 模型的 program 文件

8.2 执行推理

使用 predict_rec.py 进行静态图推理:

python3 tools/infer/predict_rec.py --image_dir='./docs/datasets/images/pme_demo/0000295.png' --rec_algorithm="LaTeXOCR" --rec_batch_num=1 --rec_model_dir="./inference/rec_latex_ocr_infer/" --rec_char_dict_path="./ppocr/utils/dict/latex_ocr_tokenizer.json"

预测文件夹下所有图像时,可将image_dir改为文件夹路径,如--image_dir='./docs/datasets/images/pme_demo/'

从源码调用链看,推理路径为:

  1. predict_rec.py 对每张图调用norm_img_latexocr预处理(灰度化 → 按 0.7931/0.1738 归一化 → 补零到 16 的倍数并转[1,1,H,W]);
  2. 将预处理后的图像送入rec_model_dir指定的静态图模型,得到 token 序列(predict_rec.py 中LaTeXOCR分支);
  3. LaTeXOCRDecode后处理解码:先用TokenizerFast将 token 还原为子词,再拼接去空格、移除[EOS]/[BOS]/[PAD]特殊 token,最后通过post_process中的正则规则压缩\operatorname\mathrm等命令与相邻字符间的多余空格(rec_postprocess.py)。

执行命令后,识别的 LaTeX 公式会打印到屏幕上。官方文档给出的 0000295.png 预测结果示例为:

Predicts of ./docs/datasets/images/pme_demo/0000295.png: \zeta_{0}(\nu)=-{\frac{\nu\varrho^{-2\nu}}{\pi}}\int_{\mu}^{\infty}d\omega\int_{C_{+}}d z{\frac{2z^{2}}{(z^{2}+\omega^{2})^{\nu+1}}}{\tilde{\Psi}}(\omega;z)e^{i\epsilon z}~~~,

8.3 C++ 推理 / Serving / 更多部署

  • C++ 推理部署:由于 C++ 端预处理与后处理尚未支持 LaTeX-OCR,暂不支持;
  • Serving 服务化部署:暂不支持;
  • 更多推理部署:暂不支持。

9. FAQ

  1. LaTeX-OCR 数据集来源?数据集来自 LaTeXOCR 原始仓库(lukas-blecher/LaTeX-OCR),PaddleOCR 复现训练与评估均使用该数据集,测试集上的 BLEU 0.8821、normed edit distance 0.0823、ExpRate 40.01% 为官方复现结果。
  2. 预测结果异常时优先检查什么?确认输入为白底黑字公式图、尺寸在 [32,32]–[672,192] 范围内,且--rec_char_dict_path指向的词典与训练时一致。
  3. 为何需要生成 pickle 文件?公式图像尺寸差异大,pkl 将同尺度图像分组并允许批内横向拼接,从而在保证批大小的同时避免大量 padding 带来的计算浪费,这与 math_txt2pkl.py 和 LaTeXOCRDataSet 的实现一致。

相关资源速查

  • 配置文件:LaTeX_OCR_rec.yaml
  • 数据转换脚本:math_txt2pkl.py
  • 数据集实现:latexocr_dataset.py
  • 骨干网络:rec_hybridvit.py
  • 解码头:rec_latexocr_head.py
  • 损失函数:rec_latexocr_loss.py
  • 后处理:rec_postprocess.py
  • 评估指标:rec_metric.py
  • 词典:latex_ocr_tokenizer.json
  • 推理工具:predict_rec.py
  • 训练/评估/导出入口:tools/train.pytools/eval.pytools/export_model.py

【免费下载链接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100+ languages.项目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询