PaddleOCR 中 UniMERNet 通用数学公式识别算法:训练、评估与源码解析
【免费下载链接】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 仓库中 UniMERNet 通用数学公式识别算法的官方文档为核心,系统讲解该算法在 PaddleOCR 中的完整落地流程:从算法精度表现、环境配置、数据集准备,到训练 / 评估 / 预测的完整命令行操作,并结合 UniMERNet.yaml 配置文件与 解码器源码、数据增强实现 等仓库源码,剖析其模型结构与数据管线原理。读完本文,你将能够独立完成 UniMERNet 模型在 PaddleOCR 中的训练、评测与推理部署。
1. 算法简介
UniMERNet 是一个通用的数学公式识别(OCR for Mathematical Expressions)算法,其原始项目由 OpenDataLab 开源。PaddleOCR 将其完整移植并接入自身模块化的训练 / 评估 / 预测体系中,使用UniMERNet通用公式识别数据集进行训练,模型配置统一收敛在 UniMERNet.yaml 中。
在对应测试集上的精度如下:
| 模型 | 骨干网络 | 配置文件 | 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 Printed Equations),CPE 表示复杂公式(Complex Printed Equations),SCE 表示扫描捕捉公式(Scanned/Captured Equations),HWE 表示手写公式(Hand-Written Equations)。可以看到,模型在打印体公式(SPE、CPE)上表现最佳,BLEU 均超过 0.91、编辑距离(Edit Distance,EditDis)低于 0.06;在扫描捕捉公式(SCE)上由于图像噪声与形变,精度相对较低;在手写公式(HWE)上同样保持了较高的识别水平。
从源码结构看,该算法在 PaddleOCR 中的定位是"图像 → LaTeX 序列"的序列到序列生成任务,属于model_type: rec(识别)分支,与 PP-FormulaNet 等公式识别模型并列,可服务于论文公式抽取、文档结构化等场景。
2. 环境配置
训练与推理前,请先参考 《运行环境准备》 配置 PaddleOCR 运行环境,并参考 《项目克隆》 克隆项目代码。
此外,UniMERNet 的数据增强与图像预处理依赖额外的系统库与 Python 包,需要额外安装:
sudo apt-get update sudo apt-get install libmagickwand-dev pip install -r docs/version2.x/algorithm/formula_recognition/requirements.txt其中libmagickwand-dev是 ImageMagick 的 Wand 绑定所需的系统依赖,docs/version2.x/algorithm/formula_recognition/requirements.txt中固定了以下 Python 依赖版本:
tokenizers==0.19.1:用于 LaTeX tokenizer 词表加载与文本 token 化;imagesize:用于读取图像尺寸信息;ftfy:用于修复 Unicode 文本编码问题;Wand:用于实现雪花(Snow)等需要动感模糊的高阶数据增强(见 unimernet_aug.py 中Snow变换的实现)。
注意:由于训练数据增强中的Snow变换在运行时通过wand.image处理图像,若未正确安装libmagickwand-dev,训练时会在该变换处报错。
3. 模型训练、评估、预测
3.1 准备数据集
UniMERNet 训练采用 UniMERNet 通用公式识别数据集(UniMER-1M)与好未来手写公式数据集 HME100K 混合训练,测试则使用 UniMER-Test 的 SPE / CPE / SCE / HWE 四个子集分别评测。数据集下载地址:
- UniMER-1M.zip 与 UniMER-Test.zip:从 OpenDataLab 的 UniMER-Dataset 页面下载;
- HME100K:从好未来平台下载。
下载完成后,使用如下命令创建数据集目录并对数据进行转换:
# 创建 UniMERNet 数据集目录 mkdir -p train_data/UniMERNet # 解压 UniMERNet 、 UniMER-Test.zip 和 HME100K.zip 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 # 训练集转换 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 的源码可以确认转换逻辑:
datatype=unimernet_train时调用latexocr2paddleocr_train:UniMER-1M 的标注按行读取,图像按行号格式化为{0:07d}.png,从UniMER-1M/images子目录下查找;HME100K 的标注为img_name\tmath_gt格式,从HME100K/train_images子目录下查找。两类数据统一转换为 PaddleOCR 标准的图像相对路径\t公式LaTeX标注两列 TSV 格式;datatype=unimernet_test时调用unimernet2paddleocr_test:测试集图像按{0:07d}.png命名,与spe.txt/cpe.txt/sce.txt/hwe.txt中的标注按行一一对应。
脚本仅保留图像实际存在且标注能正确对齐的样本,生成的文件即可直接作为 UniMERNet.yaml 中Train.dataset.label_file_list与Eval.dataset.label_file_list使用。
3.2 下载预训练模型
UniMERNet 的解码器基于 mBART 结构,官方推荐从 Texify 预训练权重初始化(而非从零开始训练),下载命令如下:
# 下载 Texify 预训练模型 wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/pretrained/texify.pdparams3.3 模型训练
训练整体流程请参考 文本识别训练教程。PaddleOCR 对代码进行了模块化,训练 UniMERNet 识别模型时需要更换配置文件为 UniMERNet 的 配置文件。
启动训练
具体地,在完成数据准备后,便可以启动训练,训练命令如下:
# 单卡训练 (默认训练方式) 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)进行 1 次评估,若您更改训练的 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.pdparamsGlobal.eval_batch_step=[0, N]表示从第 0 个 iteration 开始,每隔 N 个 iteration 评估一次;其中{length_of_dataset//batch_size//4}为一个占位表达式,含义为"数据集长度 ÷ batch_size ÷ 4",即每个 epoch 内评估 4 次,实际使用时应替换为计算后的具体数值。
3.4 评估
可下载已训练完成的模型文件,使用如下命令进行评估:
# 注意将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.data_dir与Eval.dataset.label_file_list,即可在不修改 YAML 的情况下轮换四个测试子集。评估指标由配置中的Metric.name: LaTeXOCRMetric决定,主指标为exp_rate(见下文源码解析)。
3.5 预测
使用如下命令进行单张图片预测:
# 注意将pretrained_model的路径设置为本地路径。 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 # 预测文件夹下所有图像时,可修改infer_img为文件夹,如 Global.infer_img='./doc/datasets/pme_demo/'。即把Global.infer_img指向单张图片或一个图片文件夹,模型会对每张公式图片输出对应的 LaTeX 序列,结果保存在Global.save_res_path指定的文件中(默认./output/rec/predicts_unimernet.txt)。
4. 配置文件核心参数解读
UniMERNet.yaml 是 UniMERNet 在 PaddleOCR 中的完整训练配置,各模块参数如下:
Global(全局)
model_name: UniMERNet:模型名,用于静态图(inference model)导出与推理;epoch_num: 40:总训练轮数;save_model_dir: ./output/rec/unimernet/:模型保存目录;save_epoch_step: 5:每 5 个 epoch 保存一次 checkpoint;eval_batch_step: [0, 37880]:评估间隔,37880 即 1M 训练数据在默认 batch_size=7 下的 iteration 数;rec_char_dict_path: ppocr/utils/dict/unimernet_tokenizer:LaTeX tokenizer 词表路径(注意此处是目录/前缀形式的 tokenizer 文件,由tokenizers库加载,而非普通 txt 词典);input_size: [192, 672]:模型输入尺寸(高 192,宽 672);max_seq_len: 1024:标签序列最大长度;d2s_train_image_shape: [1,192,672]:动态图转静态图(动态转静态)时的输入 shape。
Optimizer(优化器)
name: AdamW,beta1: 0.9,beta2: 0.999,weight_decay: 0.05;- 学习率采用
LinearWarmupCosine调度:初始learning_rate: 1e-4,start_lr: 1e-5,min_lr: 1e-8,warmup_steps: 5000。
Architecture(网络结构)
model_type: rec,algorithm: UniMERNet,in_channels: 3;Backbone.name: DonutSwinModel:Swin Transformer 视觉编码器,hidden_size: 1024、num_layers: 4、num_heads: [4, 8, 16, 32]、add_pooling_layer: True、use_mask_token: False;Head.name: UniMERNetHead:自回归解码头,max_new_tokens: 1536(单次生成最大 token 数)、decoder_start_token_id: 0、temperature: 0.2、do_sample: False(贪心解码)、top_p: 0.95、encoder_hidden_size: 1024、is_export: False、length_aware: True(长度感知生成)。
Loss / PostProcess / Metric
Loss.name: UniMERNetLoss:交叉熵式序列损失,实现在 rec_unimernet_loss.py;PostProcess.name: UniMERNetDecode:将解码 logits 转为 LaTeX 文本,实现在 rec_postprocess.py,同时指定rec_char_dict_path;Metric.name: LaTeXOCRMetric:main_indicator: exp_rate,cal_bleu_score: True,即同时统计公式级正确率(exp_rate)与 BLEU 分数。
Train / Eval 数据集与数据管线
- 训练集:
data_dir: ./train_data/UniMERNet/,label_file_list指向train_unimernet_1M.txt; - 变换链:
UniMERNetImgDecode(输入尺寸 [192,672])→UniMERNetTrainTransform→UniMERNetImageFormat→UniMERNetLabelEncode(词表 + max_seq_len)→KeepKeys保留['image', 'label', 'attention_mask']; - 训练 loader:
batch_size_per_card: 7,collate_fn: UniMERNetCollator; - 评估集:默认指向 CPE 子集(
UniMER-Test/cpe),变换链为UniMERNetImgDecode→UniMERNetTestTransform→UniMERNetImageFormat→UniMERNetLabelEncode→KeepKeys,评估时batch_size_per_card: 30。
5. 源码级实现解析
5.1 编码器:Donut Swin 骨干
骨干网络实现在 rec_donut_swin.py(DonutSwinModel)。它将公式图像编码为视觉 token 序列,其配置(hidden_size=1024、4 层、多头 [4,8,16,32])与单测用例tests/ppocr/test_formula_model.py中的test_unimernet_backbone完全一致:输入[1, 1, 192, 672]的灰度图像,输出特征形状为[1, 126, 1024],即 126 个 1024 维的视觉 token。
5.2 解码器:UniMERNetHead(mBART 序列生成)
解码头实现在 rec_unimernet_head.py(共 2674 行)。从源码结构看,它复刻了 HuggingFace mBART 的解码器体系:MBartConfig(含bos_token_id=0、eos_token_id=2、pad_token_id=1、forced_eos_token_id=2等)、MBartAttention(因果自注意力 + 编码器交叉注意力)、MBartDecoderLayer、MBartDecoder与MBartForCausalLM等模块被逐一以 Paddle 实现。训练时以公式图像特征为 encoder hidden states,以 LaTeX token 序列为 decoder input,通过自回归方式逐步生成公式的 token 序列;推理时依据do_sample=False执行贪心解码,并用length_aware机制辅助控制生成长度。单测test_unimernet_head验证了UniMERNetHead的输入输出:给定[1, 126, 1024]的编码特征,在max_new_tokens=5时输出[1, 6]的 token 序列。
5.3 数据管线与增强策略
UniMERNet 的专属数据变换集中在 unimernet_aug.py,包含:
UniMERNetImgDecode:读取图像后先做crop_margin(按灰度阈值裁掉空白边距,并限制宽高比不超过 200 以避免极端形变),再按最短边缩放并thumbnail到 192×672,最后在空白区域 padding 到固定尺寸;支持random_padding、random_resize、random_crop三个随机开关;UniMERNetTrainTransform:训练增强,采用 albumentations 组合,包括Bitmap(二值化,概率 0.05)、Fog/Frost/Snow/Rain/Shadow恶劣天气扰动(OneOf,p=0.2)、Erosion/Dilation形态学腐蚀膨胀(p=0.2)、ShiftScaleRotate微小平移缩放旋转(rotate_limit=1)、GridDistortion网格畸变(p=0.5)、RGBShift、GaussNoise、RandomBrightnessContrast、ImageCompression,最后ToGray转灰度并使用固定的归一化均值/方差(0.7931, 0.1738);UniMERNetTestTransform:评估时仅做ToGray + Normalize,保证评测稳定性;UniMERNetImageFormat:将图像 pad 到 32 的整数倍(适配 Swin 下采样),取单通道并转成[C, H, W]布局;UniMERNetCollator(collate_fn.py):对一个 batch 内的图像与标签分别做动态 padding 到 batch 内最大尺寸,同时生成label_masks供损失函数屏蔽 padding 位。
5.4 指标与评测逻辑
评测指标LaTeXOCRMetric实现在 rec_metric.py。从源码可见:
- 主指标
exp_rate:逐条比对预测序列与 GT 序列是否完全一致,统计公式级正确率; - 当
cal_bleu_score=True时,额外计算 BLEU 分数,并输出exp_rate<=1 / <=2 / <=3的容错统计(允许预测序列与 GT 相差 1/2/3 个 token 时仍记为正确)。
这解释了官方精度表中同时报告 BLEU 与 EditDis(编辑距离)两类指标的原因——它们分别衡量生成序列的语义相似度与逐 token 差异。
6. FAQ
- UniMERNet 数据集来自于 UniMERNet 源 repo(OpenDataLab 的 UniMER-Dataset);HME100K 手写公式数据集来自好未来平台。两者通过 unimernet_data_convert.py 统一转换为 PaddleOCR 标准标注格式后即可直接用于训练。
- 若训练时报 Wand / ImageMagick 相关错误,请确认已按第 2 节安装
libmagickwand-dev与WandPython 包。 - 若需要将 UniMERNet 模型导出为静态图用于推理部署,需在配置中设置
Global.save_inference_dir与Global.pretrained_model,并通过tools/export_model.py导出(Head.is_export等参数会相应切换解码路径)。
【免费下载链接】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),仅供参考