FormulaNet 是基于 VisionEncoderDecoder 架构的 LaTeX OCR(光学公式识别)模型,是 Texo 项目的核心模型。Texo 是一个轻量级的开源 LaTeX OCR 模型,仅有 20M 参数,支持将公式图片转换为 LaTeX 代码。
FormulaNet 采用 VisionEncoderDecoder 架构:
该模型是 PPFormulaNet-S 的蒸馏版本,在 UniMERNet-1M 数据集上微调,保留了大部分性能的同时大幅减少了参数量。
torch>=2.0.0
torchvision
transformers>=4.40.0
safetensors
Pillow>=10.0.0
numpy>=1.24.0FormulaNet 基于标准 PyTorch + HuggingFace Transformers 框架,天然支持昇腾 NPU。适配过程包括:
# 安装基础依赖
pip install torch torchvision transformers safetensors Pillow numpy
# 安装 torch_npu(根据环境选择合适的版本)
# pip install torch_npupython inference.py --image <input_image> --output result.txt --device cpu
python inference.py --image <input_image> --output result.txt --device npupython inference.py --image_dir <image_dir> --output results.txt --device npu使用 Texo 项目提供的 5 张测试公式图像(包括单行公式、多行公式、复杂表格等)。
| 图像 | 耗时(s) |
|---|---|
| 单行公式.png | 0.983 |
| 单行公式2.png | 1.885 |
| 多行公式.png | 5.249 |
| 复杂表格.png | 6.240 |
| 多行公式2.jpg | 2.194 |
| 总计 | 16.551 |
| 图像 | 耗时(s) |
|---|---|
| 单行公式.png | 0.147 |
| 单行公式2.png | 0.411 |
| 多行公式.png | 1.272 |
| 复杂表格.png | 1.887 |
| 多行公式2.jpg | 0.430 |
| 总计 | 4.147 |
输入图像: 单行公式.png
CPU 输出: 2^{2^{\lim_{n\to\infty}(\frac{1}{2})^n}}...
NPU 输出: 2^{2^{\lim_{n\to\infty}(\frac{1}{2})^n}}...
输入图像: 单行公式2.png
CPU 输出: \Re\left(\frac{-2i\kappa_0}{2\pi}\theta\right)...
NPU 输出: \Re\left(\frac{-2i\kappa_0}{2\pi}\theta\right)...# CPU 推理
python inference.py --image_dir <test_images> --output cpu_results.txt --device cpu
# NPU 推理
python inference.py --image_dir <test_images> --output npu_results.txt --device npu
# 对比
python compare_cpu_npu.py --cpu cpu_results.txt --npu npu_results.txt| 图像名称 | CPU耗时(s) | NPU耗时(s) | 加速比 | 完全一致 |
|---|---|---|---|---|
| 单行公式.png | 0.983 | 0.147 | 6.69x | 是 |
| 单行公式2.png | 1.885 | 0.411 | 4.59x | 是 |
| 多行公式.png | 5.249 | 1.272 | 4.13x | 是 |
| 复杂表格.png | 6.240 | 1.887 | 3.31x | 是 |
| 多行公式2.jpg | 2.194 | 0.430 | 5.10x | 是 |
NPU 与 CPU 的推理结果完全一致(5/5 图像输出 LaTeX 代码完全相同),精度误差为 0%。
| 指标 | CPU | NPU | 加速比 |
|---|---|---|---|
| 总耗时 (5张) | 16.551s | 4.147s | 3.99x |
| 平均耗时/张 | 3.310s | 0.829s | 3.99x |
| 最快单张 | 0.983s | 0.147s | 6.69x |
| 最慢单张 | 6.240s | 1.887s | 3.31x |
NPU(Ascend910)相比 CPU 实现了约 4 倍的平均推理加速。
import torch
from PIL import Image, ImageOps
import numpy as np
from transformers import VisionEncoderDecoderModel, AutoTokenizer
from safetensors.torch import load_file
# 注册自定义 encoder
from texo.model.hgnet2 import HGNetv2Config, HGNetv2
from transformers import AutoConfig, AutoModel
AutoConfig.register("my_hgnetv2", HGNetv2Config)
AutoModel.register(HGNetv2Config, HGNetv2)
# 加载模型
model = VisionEncoderDecoderModel.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
model.to(device)
model.eval()
# 图像预处理
image = Image.open(image_path).convert('RGB')
image = crop_margin(image)
image = resize_with_padding(image, 384)
image = image.convert('L')
arr = np.array(image, dtype=np.float32) / 255.0
arr = (arr - 0.7931) / 0.1738
tensor = torch.from_numpy(arr).unsqueeze(0).float()
tensor = tensor.repeat(3, 1, 1).unsqueeze(0)
# 推理
with torch.no_grad():
outputs = model.generate(pixel_values=tensor.to(device), max_length=512)
pred = tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]
print(pred)参考 inference.py:
python inference.py --image formula.png --output result.txt --device npu以下日志展示了 NPU 推理成功的关键信息:
NPU: Ascend910 (torch_npu 2.9.0.post1)
inference.py - 推理脚本(支持 CPU/NPU)compare_cpu_npu.py - CPU/NPU 精度对比脚本requirements.txt - Python 依赖README.md - 本文档screenshot.png - 推理运行截图cpu_results.txt - CPU 推理结果npu_results.txt - NPU 推理结果comparison_results.txt - CPU/NPU 对比结果精度测试结果.log - 精度测试日志