e
gcw_GSiqzzLf/en_ppstructure_mobile_v2.0_SLANet_infer-npu
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

en-ppstructure-mobile-v2.0-SLANet-infer-NPU

模型介绍

en_ppstructure_mobile_v2.0_SLANet_infer 是 PaddleOCR PP-StructureV2 提供的表格结构识别模型(Table Structure Recognition),基于 SLANet(Structure Layout Analysis Network)架构。该模型能够识别表格的布局结构,输出表格的 HTML 结构描述和每个单元格的边界框坐标。

本仓库提供基于 ONNX Runtime CPU ExecutionProvider 的推理适配版本。

原始模型地址

  • ModelScope: https://www.modelscope.cn/models/cycloneboy/en_ppstructure_mobile_v2.0_SLANet_infer/files

任务类型

表格结构识别(Table Structure Recognition)- 识别表格的行列结构、合并单元格和布局

模型框架

  • 架构: SLANet(Structure Layout Analysis Network)
  • 骨干网络: MobileNetV3
  • 解码器: Attention-based LSTM 序列解码器
  • 结构字符集: 30 类(sos + 28 个结构 token + eos)
  • 最大序列长度: 501
  • 输入尺寸: [N, 3, H, W](动态输入,内部缩放到 488×488)
  • 模型格式: ONNX (opset 14)
  • 模型大小: 7.3 MB (FP32)

输入格式

  • 图像: RGB 格式,缩放至最大边 488 像素(保持宽高比),填充至 488×488
  • 归一化: ImageNet 标准化(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

输出格式

  • 输出 1: 结构序列概率 softmax_1.tmp_0,形状 [1, 501, 30]
  • 输出 2: 边界框预测 fill_constant_15.tmp_0.1.0,形状 [1, 501, 4]
  • 解码输出: HTML 表格结构字符串 + 单元格边界框坐标列表

依赖环境

  • Python >= 3.10
  • onnxruntime >= 1.15.0
  • numpy >= 1.20.0
  • Pillow >= 9.0.0
  • opencv-python >= 4.5.0

NPU 适配说明

当前状态:NPU 推理暂不可用

本模型使用 ONNX Loop 算子(opset 14)实现 Attention-based LSTM 序列解码器。当前 CANNExecutionProvider(onnxruntime-cann 1.24.4)不支持 ONNX Loop 算子,导致以下错误:

CANN Graph error executing ge::aclgrphParseONNXFromMem

ATC(Ascend Tensor Compiler)工具同样不支持 Loop 算子转换:

No operator plugin is registered for Op: Loop.0, optype: ai.onnx::14::Loop

临时解决方案

  1. CPU 推理: 当前可使用 CPUExecutionProvider 完成全部推理,模型处理单张表格约 0.8 秒
  2. PaddlePaddle 原生推理: 如果安装 PaddlePaddle NPU 版本(paddle-custom-npu),可直接使用 PaddleOCR 的 PP-StructureV2 流水线在 NPU 上运行
  3. 等待 CANN 更新: 预计后续 CANN 版本将增加对 ONNX Loop 算子的支持

环境准备

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnxruntime numpy Pillow opencv-python-headless

推理命令

CPU 推理

python3 inference.py /path/to/table_image.png

该脚本会同时在 CPU 上进行推理,并尝试 NPU(CANN)推理,输出对比结果。

推理结果

设备测试图片推理耗时检测结果
CPUtest_table.png0.81s4 列 × 5 行表格结构
CPUtest_document.png0.75s文档表格结构

CPU 推理确定性强(两次运行 100% 一致),模型能够正确识别表格行列结构。

部署和推理方法

核心推理代码

import onnxruntime
import numpy as np
from PIL import Image

# 1. 加载模型
session = onnxruntime.InferenceSession(
    "model.onnx",
    providers=["CPUExecutionProvider"]
)

# 2. 图像预处理
img = Image.open("table.png").convert("RGB")
w, h = img.size
max_len = 488
ratio = max_len / max(h, w)
img = img.resize((int(w * ratio), int(h * ratio)), Image.LANCZOS)
canvas = Image.new("RGB", (max_len, max_len), (255, 255, 255))
canvas.paste(img, (0, 0))

img_np = np.array(canvas, dtype=np.float32) / 255.0
mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
img_np = (img_np - mean) / std
img_np = np.transpose(img_np, (2, 0, 1))
img_np = np.expand_dims(img_np, axis=0).astype(np.float32)

# 3. 推理
outputs = session.run(None, {"x": img_np})
loc_preds = outputs[0]      # [1, 501, 4]
structure_probs = outputs[1] # [1, 501, 30]

# 4. 解码结构序列
structure_idx = structure_probs.argmax(axis=2)
tokens = []
for i in range(structure_idx.shape[1]):
    idx = int(structure_idx[0, i])
    if idx == 0 or idx == 29:  # sos/eos
        continue
    tokens.append(char_list[idx])

html = "<html><body><table>" + "".join(tokens) + "</table></body></html>"

CPU/NPU 精度测试方法

运行精度对比脚本:

python3 compare_cpu_npu.py

该脚本会依次:

  1. 使用 CPUExecutionProvider 进行两次推理(验证确定性和可重复性)
  2. 尝试使用 CANNExecutionProvider 进行 NPU 推理
  3. 对比两次 CPU 输出的预测一致性和 HTML 一致性
  4. 输出详细结果并保存到 compare_results.json

CPU/NPU 精度测试结果

测试图片CPU Run1 vs Run2 预测一致性HTML 一致NPU 状态
test_table.png100.0000%是不可用(Loop 算子限制)
test_document.png100.0000%是不可用(Loop 算子限制)

精度测试结论:CPU 推理确定性强(100% 一致),NPU 推理因 CANN ONNX Loop 算子限制暂不可用。待 CANN 版本更新后可重新测试。

性能测试结果

指标CPU (FP32)
推理耗时(test_table.png)0.81s
推理耗时(test_document.png)0.75s
模型精度float32

终端输出截图

终端输出截图

模型标签

#+NPU #+CV #+OCR #+昇腾 #+PaddleOCR #+表格结构识别 #+SLANet #+PP-Structure #+ONNX

版权说明

本仓库仅提供适配脚本和使用示例,模型权重版权归 PaddleOCR 团队所有。使用本模型请遵守 PaddleOCR 的开源许可协议(Apache 2.0)。