PaddleOCR 通用数学公式识别算法 UniMERNet 完整指南:环境搭建、数据集转换、训练评估与推理实战
【免费下载链接】PaddleOCR飞桨多语言OCR工具包(实用超轻量OCR系统,支持80+种语言识别,提供数据标注与合成工具,支持服务器、移动端、嵌入式及IoT设备端的训练与部署) Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80+ languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR
数学公式识别(Mathematical Expression Recognition,MER)是 OCR 领域中最具挑战性的任务之一——公式具有复杂的二维结构、层级嵌套与丰富的符号体系,无法像普通文本那样用一维序列简单建模。本文聚焦 PaddleOCR 仓库内集成实现的UniMERNet 通用数学公式识别算法,基于仓库中的 算法说明文档 展开,并结合 UniMERNet 配置文件、源码实现与数据集转换脚本进行纵深讲解。读完本文,你将掌握:UniMERNet 在 PaddleOCR 中的算法定位与精度表现、完整的环境依赖安装、UniMER-1M / HME100K 数据集的下载与格式转换、Texify 预训练权重加载、单卡/多卡训练、四类测试集的评估方法以及单张图片的推理预测。
1. 算法简介:UniMERNet 是什么
UniMERNet 是一个面向通用数学公式识别的端到端模型,原始项目来自 OpenDataLab 团队(其训练数据 UniMER-Dataset 亦由 OpenDataLab 发布)。PaddleOCR 将其完整复现并模块化集成,用户只需替换配置文件即可在 PaddleOCR 的框架下完成训练、评估与推理,无需改动任何核心代码——这正是 PaddleOCR“模块化代码 + 换配置训练不同模型”设计理念的典型体现(详见 文本识别训练教程)。
在 PaddleOCR 中,UniMERNet 以Donut Swin 作为视觉骨干网络(Backbone),配合MBart 风格的 Transformer 解码器(Head)构成视觉-语言序列生成结构。该结构可以从 配置文件的 Architecture 段 中直接看出:Backbone.name: DonutSwinModel,Head.name: UniMERNetHead。从源码结构看,rec_unimernet_head.py 完整实现了MBartDecoder、MBartDecoderLayer、MBartAttention、MBartForCausalLM等 MBart 系列模块,解码器通过交叉注意力(cross-attention)逐 token 生成 LaTeX 序列,从而把公式图像翻译为结构化排版语言。
1.1 官方复现精度
PaddleOCR 使用 UniMERNet 通用公式识别数据集进行训练,并在其对应测试集上的复现效果如下:
| 模型 | 骨干网络 | 配置文件 | SPE-BLEU↑ | SPE-EditDis↓ | CPE-BLEU↑ | CPE-EditDis↓ | SCE-BLEU↑ | SCE-EditDis↓ | HWE-BLEU↑ | HWE-EditDis↓ |
|---|---|---|---|---|---|---|---|---|---|---|
| UniMERNet | Donut Swin | UniMERNet.yaml | 0.9187 | 0.0584 | 0.9252 | 0.0596 | 0.6068 | 0.2297 | 0.9157 | 0.0546 |
其中四类测试集含义如下:
- SPE(Simple Formulas):简单公式;
- CPE(Complex Formulas):复杂公式;
- SCE(Scanned Captured Formulas):扫描/拍摄捕捉的公式;
- HWE(Handwritten Formulas):手写公式。
两类指标说明:
- BLEU↑:基于 n-gram 匹配的序列质量指标,越高代表生成结果与标准 LaTeX 标注越接近;
- EditDis↓(编辑距离,Edit Distance):衡量生成序列与标准序列的字符级差异,越低越好。
从表格可见,模型在 SPE、CPE、HWE 上 BLEU 均超过 0.91、编辑距离低于 0.06,而 SCE(扫描/拍摄)场景因图像质量退化明显,指标相对偏低(BLEU 0.6068、EditDis 0.2297),这提示在真实扫描/拍照场景下需要更强的图像预处理或针对性微调。官方提供了训练完成的模型权重(rec_unimernet_train.tar),可直接用于评估与推理。
2. 环境配置:PaddleOCR 环境与额外依赖
UniMERNet 的训练与推理依赖 PaddleOCR 基础运行环境,请先参考 《运行环境准备》 完成 PaddleOCR 环境配置,并参考 《项目克隆》 克隆项目代码。
除基础环境外,还需安装以下额外依赖:
sudo apt-get update sudo apt-get install libmagickwand-dev pip install -r docs/version2.x/algorithm/formula_recognition/requirements.txt该 requirements.txt 中包含了四个关键包:
| 包名 | 作用 |
|---|---|
tokenizers==0.19.1 | 公式 LaTeX 序列的 tokenizer 分词,与unimernet_tokenizer词典配合使用 |
imagesize | 快速读取图片尺寸信息 |
ftfy | 文本修复与 Unicode 规范化,用于清洗 LaTeX 标注 |
Wand | ImageMagick 的 Python 绑定,用于雨雪(Snow)等图像增强效果的渲染 |
其中libmagickwand-dev是Wand 包的编译期依赖,缺失会导致from wand.image import Image导入失败。从源码 unimernet_aug.py 可以看出,训练阶段的Snow增强会调用wand.image.Image实现运动模糊特效,因此该系统级依赖是训练数据增强链路上必不可少的。
3. 数据准备:UniMER-1M 与 HME100K 数据集转换
3.1 数据集下载
UniMERNet 的训练数据由两部分构成:
- UniMER-1M.zip 与 UniMER-Test.zip:从 OpenDataLab 的 UniMER-Dataset 页面下载;
- HME100K:手写公式数据集,从好未来(TAL)AI 平台下载,用于增强模型对手写公式的识别能力。
下载完成后,按以下命令创建数据集目录并解压:
# 创建 UniMERNet 数据集目录 mkdir -p train_data/UniMERNet # 解压 UniMER-1M、UniMER-Test 和 HME100K unzip -d train_data/UniMERNet path/UniMER-1M.zip unzip -d train_data/UniMERNet path/UniMER-Test.zip unzip -d train_data/UniMERNet/HME100K train_data/UniMERNet/HME100K/train.zip unzip -d train_data/UniMERNet/HME100K train_data/UniMERNet/HME100K/test.zip解压完成后目录结构应形如:
train_data/UniMERNet/ ├── UniMER-1M/ # 大规模公式图片与 train.txt 标注 ├── UniMER-Test/ │ ├── spe/ cpe/ sce/ hwe/ # 四类测试集图片 │ └── spe.txt cpe.txt sce.txt hwe.txt └── HME100K/ ├── train_images/ test_images/ └── train_labels.txt3.2 数据格式转换:原生标注 → PaddleOCR 训练格式
PaddleOCR 的训练数据格式为图片相对路径\t标注文本的制表符分隔文本。UniMER 原生的标注格式与 PaddleOCR 不同,因此需要使用仓库提供的转换脚本 unimernet_data_convert.py 进行转换。
训练集转换(合并 UniMER-1M 与 HME100K):
python ppocr/utils/formula_utils/unimernet_data_convert.py \ --image_dir=train_data/UniMERNet \ --datatype=unimernet_train \ --unimernet_txt_path=train_data/UniMERNet/UniMER-1M/train.txt \ --hme100k_txt_path=train_data/UniMERNet/HME100K/train_labels.txt \ --output_path=train_data/UniMERNet/train_unimernet_1M.txt四类测试集转换:
# SPE python ppocr/utils/formula_utils/unimernet_data_convert.py \ --image_dir=train_data/UniMERNet/UniMER-Test/spe \ --datatype=unimernet_test \ --unimernet_txt_path=train_data/UniMERNet/UniMER-Test/spe.txt \ --output_path=train_data/UniMERNet/test_unimernet_spe.txt # CPE python ppocr/utils/formula_utils/unimernet_data_convert.py \ --image_dir=train_data/UniMERNet/UniMER-Test/cpe \ --datatype=unimernet_test \ --unimernet_txt_path=train_data/UniMERNet/UniMER-Test/cpe.txt \ --output_path=train_data/UniMERNet/test_unimernet_cpe.txt # SCE python ppocr/utils/formula_utils/unimernet_data_convert.py \ --image_dir=train_data/UniMERNet/UniMER-Test/sce \ --datatype=unimernet_test \ --unimernet_txt_path=train_data/UniMERNet/UniMER-Test/sce.txt \ --output_path=train_data/UniMERNet/test_unimernet_sce.txt # HWE python ppocr/utils/formula_utils/unimernet_data_convert.py \ --image_dir=train_data/UniMERNet/UniMER-Test/hwe \ --datatype=unimernet_test \ --unimernet_txt_path=train_data/UniMERNet/UniMER-Test/hwe.txt \ --output_path=train_data/UniMERNet/test_unimernet_hwe.txt从 unimernet_data_convert.py 的源码可以看到转换逻辑:
unimernet_train分支:遍历 UniMER-1M 的train.txt,按行号生成0000000.png、0000001.png…… 形式的图片名(对应UniMER-1M/images子目录);再读取 HME100K 的train_labels.txt(制表符分隔的图片名\t标注),追加写入同一输出文件。注意 HME100K 转换依赖train_labels.txt的路径与图片实际存放位置,若结构不同需同步调整image_dir指向。unimernet_test分支:将spe/cpe/sce/hwe各目录下的图片按0000000.png递增命名,与各.txt中逐行 LaTeX 标注对齐,输出图片名\t标注格式。
脚本参数说明:
| 参数 | 含义 |
|---|---|
--image_dir | 图片根目录(训练集)或测试集图片目录 |
--datatype | unimernet_train或unimernet_test,决定走哪条转换逻辑 |
--unimernet_txt_path | UniMER 系列标注文件路径(训练集为train.txt,测试集为各分项.txt) |
--hme100k_txt_path | HME100K 标注文件路径(仅训练集需要) |
--output_path | 转换后的输出文件路径 |
转换产出的train_unimernet_1M.txt即为 配置文件 中Train.dataset.label_file_list指定的训练标注文件。
3.3 下载预训练模型
训练前需下载Texify 预训练模型作为初始化权重,以加速收敛并提升最终精度:
wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/texify.pdparams下载后权重位于./pretrain_models/texify.pdparams,与 配置文件 中Global.pretrained_model字段对应。
4. 模型训练:单卡与多卡
4.1 配置文件总览
训练前先理解 UniMERNet.yaml 的核心配置段,便于按需调整:
| 配置段 | 关键项 | 默认值 | 说明 |
|---|---|---|---|
| Global | epoch_num | 40 | 训练轮数 |
| Global | eval_batch_step | [0, 37880] | 每 37880 次 iteration 评估一次 |
| Global | input_size | [192, 672] | 输入图片尺寸(高×宽) |
| Global | max_seq_len | 1024 | 公式序列最大长度 |
| Global | rec_char_dict_path | ppocr/utils/dict/unimernet_tokenizer | UniMERNet 专用 tokenizer 词典 |
| Global | pretrained_model | 空 | 预训练权重路径,训练时通过-o覆盖 |
| Optimizer | name | AdamW | 优化器 |
| Optimizer | lr.name | LinearWarmupCosine | 学习率策略:线性预热 + 余弦退火 |
| Optimizer | lr.learning_rate/start_lr/min_lr | 1e-4 / 1e-5 / 1e-8 | 学习率区间 |
| Optimizer | lr.warmup_steps | 5000 | 预热步数 |
| Architecture.Backbone | name | DonutSwinModel | 视觉编码器(hidden_size: 1024、num_layers: 4、num_heads: [4,8,16,32]) |
| Architecture.Head | name | UniMERNetHead | 解码器(max_new_tokens: 1536、temperature: 0.2、do_sample: False、length_aware: True) |
| Loss | name | UniMERNetLoss | 损失函数 |
| PostProcess | name | UniMERNetDecode | 解码后处理 |
| Metric | name | LaTeXOCRMetric | 评估指标(main_indicator: exp_rate,cal_bleu_score: True) |
| Train.loader | batch_size_per_card | 7 | 单卡训练 batch size |
| Eval.loader | batch_size_per_card | 30 | 评估 batch size |
几个值得展开的源码细节:
- 损失函数:rec_unimernet_loss.py 中的
UniMERNetLoss采用word_loss(交叉熵)+count_loss(SmoothL1 长度感知计数损失)的复合结构。当length_aware=True(配置默认开启)时,模型额外预测每个 token 在公式中的出现次数,帮助解码器生成更准确的公式结构,这也是 Head 配置中length_aware: True的对应实现。 - 数据增强:unimernet_aug.py 中的
UniMERNetTrainTransform集成了 Bitmap 二值化、Fog/Frost/Snow/Rain/Shadow 天气噪声、Erosion/Dilation 形态学腐蚀膨胀、ShiftScaleRotate 仿射变换、GridDistortion 网格畸变、RGBShift、高斯噪声、亮度对比度、JPEG 压缩等一系列增强,最后统一转灰度并按均值0.7931、标准差0.1738归一化;UniMERNetTestTransform则仅做灰度化与归一化,保证测试稳定性。 - 图像预处理:
UniMERNetImgDecode负责边缘裁剪(crop margin)、等比缩放、padding 到input_size;UniMERNetImageFormat将图像按 32 的倍数补齐并转成[1, H, W]单通道格式。 - 动态 padding collator:collate_fn.py 中的
UniMERNetCollator按 batch 内最大高、宽、序列长度动态补齐,避免固定尺寸带来的计算浪费。
4.2 启动训练
完成数据准备后即可启动训练。单卡训练(默认方式):
python3 tools/train.py -c configs/rec/UniMERNet.yaml \ -o Global.pretrained_model=./pretrain_models/texify.pdparams多卡训练,通过--gpus参数指定卡号:
python3 -m paddle.distributed.launch --gpus '0,1,2,3' --ips=127.0.0.1 tools/train.py -c configs/rec/UniMERNet.yaml \ -o Global.pretrained_model=./pretrain_models/texify.pdparams注意:配置默认每训练 1 个 epoch(37880 次 iteration,对应单卡 batch_size=7 时 40 epoch 数据集规模)评估一次。若更改了 batch_size 或更换数据集,请同步调整评估间隔:
python3 -m paddle.distributed.launch --gpus '0,1,2,3' --ips=127.0.0.1 tools/train.py -c configs/rec/UniMERNet.yaml \ -o Global.eval_batch_step=[0,{length_of_dataset//batch_size//4}] \ Global.pretrained_model=./pretrain_models/texify.pdparams其中{length_of_dataset//batch_size//4}表示按“数据集长度 ÷ batch_size ÷ 4”估算出的、约 1/4 epoch 的迭代步数,可保证每 epoch 至少完成 4 次中间评估。
5. 模型评估:四类测试集逐一验证
可下载官方训练完成的模型权重,解压后得到rec_unimernet_train/目录,使用以下命令在四类测试集上分别评估。注意将pretrained_model路径设置为本地实际路径;若使用自行训练保存的模型,请相应修改路径与文件名{path/to/weights}/{model_name}。
# SPE 测试集评估 python3 tools/eval.py -c configs/rec/UniMERNet.yaml -o \ Eval.dataset.data_dir=./train_data/UniMERNet/UniMER-Test/spe \ Eval.dataset.label_file_list=["./train_data/UniMERNet/test_unimernet_spe.txt"] \ Global.pretrained_model=./rec_unimernet_train/best_accuracy.pdparams # CPE 测试集评估 python3 tools/eval.py -c configs/rec/UniMERNet.yaml -o \ Eval.dataset.data_dir=./train_data/UniMERNet/UniMER-Test/cpe \ Eval.dataset.label_file_list=["./train_data/UniMERNet/test_unimernet_cpe.txt"] \ Global.pretrained_model=./rec_unimernet_train/best_accuracy.pdparams # SCE 测试集评估 python3 tools/eval.py -c configs/rec/UniMERNet.yaml -o \ Eval.dataset.data_dir=./train_data/UniMERNet/UniMER-Test/sce \ Eval.dataset.label_file_list=["./train_data/UniMERNet/test_unimernet_sce.txt"] \ Global.pretrained_model=./rec_unimernet_train/best_accuracy.pdparams # HWE 测试集评估 python3 tools/eval.py -c configs/rec/UniMERNet.yaml -o \ Eval.dataset.data_dir=./train_data/UniMERNet/UniMER-Test/hwe \ Eval.dataset.label_file_list=["./train_data/UniMERNet/test_unimernet_hwe.txt"] \ Global.pretrained_model=./rec_unimernet_train/best_accuracy.pdparams评估命令中通过-o覆盖两个Eval.dataset字段:
Eval.dataset.data_dir:测试集图片目录;Eval.dataset.label_file_list:对应测试标注文件列表(列表语法,用方括号包裹)。
评估输出由LaTeXOCRMetric计算,包含 BLEU、编辑距离与公式级准确率(exp_rate,即main_indicator)等指标,可与 1.1 节的官方复现精度表进行对照验证。
6. 模型推理:单张图片公式识别
训练或评估完成后,使用tools/infer_rec.py对单张公式图片进行预测:
# 预测使用的配置文件必须与训练一致 python3 tools/infer_rec.py -c configs/rec/UniMERNet.yaml \ -o Global.infer_img='./docs/datasets/images/pme_demo/0000099.png' \ Global.pretrained_model=./rec_unimernet_train/best_accuracy.pdparams其中:
Global.infer_img:待识别图片路径。当需要批量预测一个文件夹下的所有图片时,可将其修改为文件夹路径,例如Global.infer_img='./doc/datasets/pme_demo/';Global.pretrained_model:本地权重路径,务必替换为实际路径;- 识别结果(LaTeX 序列)默认输出到
Global.save_res_path指定的文件(默认./output/rec/predicts_unimernet.txt)。
推理流程的底层链路是:图片经UniMERNetImgDecode边缘裁剪与缩放填充 →UniMERNetTestTransform灰度化与归一化 →UniMERNetImageFormat对齐到 32 的倍数 → Donut Swin 编码器提取视觉特征 →UniMERNetHead基于 MBart 解码器自回归生成 token 序列 →UniMERNetDecode结合unimernet_tokenizer词典解码为最终 LaTeX 文本。Head 配置中的max_new_tokens: 1536限定了最长生成序列,temperature: 0.2与do_sample: False表明推理默认采用低温度贪心解码,保证结果稳定可复现。
7. FAQ 与常见问题
- UniMERNet 数据集来自哪里?训练与测试数据(UniMER-1M、UniMER-Test)来自 UniMERNet 源项目仓库对应的 UniMER-Dataset 数据集,HME100K 手写公式数据来自好未来 AI 平台。若训练时发现标注与图片数量不匹配,请优先核对解压目录结构与源数据集版本是否一致。
- 训练时提示缺少
wand相关模块?请确认已执行sudo apt-get install libmagickwand-dev并安装Wand,同时保证 ImageMagick 系统库与 Python 绑定版本兼容。 - 换数据集或改 batch_size 后评估节奏异常?按 4.2 节说明,通过
-o Global.eval_batch_step=[0,{length_of_dataset//batch_size//4}]覆盖评估间隔。 - 推理时能否批量预测?可以,将
Global.infer_img指向文件夹路径即可,预测脚本会自动遍历目录下所有图片。
8. 延伸阅读
- 算法完整配置:configs/rec/UniMERNet.yaml
- 数据集转换脚本:ppocr/utils/formula_utils/unimernet_data_convert.py
- 模型解码头实现:ppocr/modeling/heads/rec_unimernet_head.py
- 损失函数实现:ppocr/losses/rec_unimernet_loss.py
- 数据增强与图像预处理:ppocr/data/imaug/unimernet_aug.py
- 标签编码:ppocr/data/imaug/label_ops.py
- 动态 padding collator:ppocr/data/collate_fn.py
- 环境依赖清单:docs/version2.x/algorithm/formula_recognition/requirements.txt
- 文本识别训练通用教程:docs/version2.x/ppocr/model_train/recognition.en.md
【免费下载链接】PaddleOCR飞桨多语言OCR工具包(实用超轻量OCR系统,支持80+种语言识别,提供数据标注与合成工具,支持服务器、移动端、嵌入式及IoT设备端的训练与部署) Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80+ languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考