UniRec-0.1B 是一个仅 0.1B 参数量的统一识别模型(OCR),由 OpenOCR 项目开发,用于高精度文本、数学公式、中英文混合内容的识别。原始模型基于 FocalSVTR 视觉编码器 + M2M100 自回归解码器架构。
本仓库为 UniRec-0.1B 在华为昇腾 (Ascend) NPU 上的适配版本,支持基于 torch_npu 的推理部署。
由于原始模型 VLMOCRForConditionalGenerationNew 为自定义架构,无法直接通过 transformers.AutoModel 加载,本适配版本:
model.pth) 逆向还原了完整的模型结构定义torch_npu| 组件 | 架构 | 规格 |
|---|---|---|
| Vision Encoder | FocalSVTR (Focal Modulation) | 4 stages: dims [96,192,384,768], blocks [2,2,9,2] |
| Decoder | M2M100 Transformer Decoder | 6 layers, d_model=768, heads=6, ffn=3072 |
| Vocabulary | Semantic-decoupled Tokenizer | vocab_size=56371 |
| Total Parameters | - | ~136M (0.1B) |
| 算子类型 | Ascend 兼容性 | 说明 |
|---|---|---|
| nn.Conv2d | ✅ 支持 | torch_npu 原生支持 |
| nn.Linear | ✅ 支持 | torch_npu 原生支持 |
| nn.LayerNorm | ✅ 支持 | torch_npu 原生支持 |
| nn.BatchNorm2d | ✅ 支持 | torch_npu 原生支持 |
| F.softmax | ✅ 支持 | torch_npu 原生支持 |
| F.gelu | ✅ 支持 | torch_npu 原生支持 |
| F.relu | ✅ 支持 | torch_npu 原生支持 |
| 深度可分离卷积 (groups=dim) | ✅ 支持 | torch_npu 原生支持 |
| 自定义 CUDA Kernel | 无 | 模型不依赖 CUDA kernel |
结论: 模型全部使用标准 PyTorch 算子,无 CUDA/Triton 依赖,对 Ascend NPU 零阻碍适配。
| 组件 | 版本 | 说明 |
|---|---|---|
| CANN | 8.5.1 | Ascend 计算架构 |
| torch | 2.9.0 | PyTorch |
| torch_npu | 2.9.0.post1 | Ascend NPU 适配包 |
| transformers | >= 4.49.0 | HuggingFace Transformers |
| modelscope | latest | 模型下载 |
| PIL / Pillow | latest | 图像处理 |
| numpy | latest | 数值计算 |
# 安装 modelscope 用于模型下载
pip install modelscope
# 下载模型
modelscope download --model topdktu/unirec-0.1b
# 安装依赖
pip install transformers>=4.49.0 Pillow numpy# 下载模型权重
modelscope download --model topdktu/unirec-0.1b
# 适配代码位于本仓库
git clone <this-repo>
cd unirec_npuimport torch
import torch_npu
from modeling_unirec import VLMOCRForConditionalGenerationNew
from PIL import Image
import numpy as np
# 加载模型
model = VLMOCRForConditionalGenerationNew.from_pretrained_checkpoint(
"/path/to/unirec-0.1b/model.pth"
)
model = model.to("npu:0")
model.eval()
# 预处理图像
def preprocess(image_path, size=(224, 224)):
img = Image.open(image_path).convert("RGB").resize(size, Image.BICUBIC)
arr = np.array(img, dtype=np.float32) / 255.0
arr = (arr - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225]
return torch.from_numpy(arr).permute(2, 0, 1).unsqueeze(0)
# 推理
pixel_values = preprocess("path/to/image.png").to("npu:0")
with torch.no_grad():
output_ids = model.generate(pixel_values, max_length=256)
# 解码输出
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(
"/opt/atomgit/.cache/modelscope/hub/models/topdktu/unirec-0___1b",
trust_remote_code=True
)
result = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(result)cd /opt/atomgit/unirec_npu
python inference.py --image /path/to/image.png --device npupython inference.py --benchmark使用 inference.py 对比 NPU 与 CPU 上的前向推理输出 Logits:
| 测试图像 | 最大绝对误差 | 最大相对误差 | 余弦相似度 | 结果 |
|---|---|---|---|---|
| Snipaste_2025-04-13_21-11-35.png | 0.127731 | 0.384% | 0.99999994 | ✅ PASS |
| Snipaste_2025-04-13_21-51-45.png | 0.146442 | 0.466% | 0.99999177 | ✅ PASS |
结论: NPU 推理结果与 CPU 基准高度一致,最大相对误差 0.466%,远低于 1% 阈值,精度验证 通过。
使用 inference.py --benchmark 进行端到端推理延迟测试(含 warmup):
| 设备 | 图像 | 平均延迟 | 中位延迟 | 标准差 |
|---|---|---|---|---|
| NPU (Ascend 910) | Image 1 | 191.46 ms | 190.73 ms | 5.86 ms |
| NPU (Ascend 910) | Image 2 | 192.08 ms | 191.28 ms | 3.37 ms |
| CPU (基准) | Image 1 | 14449.09 ms | 14171.78 ms | 946.27 ms |
| CPU (基准) | Image 2 | 14861.00 ms | 14355.69 ms | 1362.42 ms |
| 指标 | 数值 |
|---|---|
| NPU 平均延迟 | ~192 ms |
| CPU 平均延迟 | ~14,655 ms |
| NPU/CPU 加速比 | ~76× |
unirec_npu/
├── modeling_unirec.py # 模型结构定义 (FocalSVTR + M2M100 Decoder)
├── inference.py # NPU 推理与评测脚本
├── README.md # 本文档 (部署与评测报告)
├── output/
│ ├── evaluation_results.json # 评测结果 (JSON)
│ └── evaluation.log # 运行日志
└── screenshot/
└── evaluation_pass.png # 自验证截图| 交付件 | 文件 | 说明 |
|---|---|---|
| ✅ 推理脚本 | inference.py | NPU-adapted inference + evaluation |
| ✅ 模型定义 | modeling_unirec.py | 完整模型结构定义 (FocalSVTR + Decoder) |
| ✅ 部署文档 | README.md | 本文档 |
| ✅ 精度评测源码 | inference.py (含 compare_outputs 函数) | 自动对比 NPU vs CPU |
| ✅ 自验证截图 | output/screenshots/ | 运行结果截图 |
| ✅ 运行日志 | output/evaluation.log | 完整评测日志 |
| ✅ 模型卡片 | YAML frontmatter (见文件顶部) | #NPU #Hardware 标签 |
pixel_values 的第一个维度实现@article{du2025unirec,
title={UniRec-0.1B: Unified Text and Formula Recognition with 0.1B Parameters},
author={Yongkun Du and Zhineng Chen and Yazhen Xie and Weikang Bai and Hao Feng and Wei Shi and Yuchen Su and Can Huang and Yu-Gang Jiang},
journal={arXiv preprint arXiv:2512.21095},
year={2025}
}Apache License 2.0
模型适配: 基于 Ascend NPU (torch_npu 2.9.0) + CANN 8.5.1 完成 适配日期: 2026-05-20