en_ppstructure_mobile_v2.0_SLANet_infer 是 PaddleOCR PP-StructureV2 提供的表格结构识别模型(Table Structure Recognition),基于 SLANet(Structure Layout Analysis Network)架构。该模型能够识别表格的布局结构,输出表格的 HTML 结构描述和每个单元格的边界框坐标。
本仓库提供基于 ONNX Runtime CPU ExecutionProvider 的推理适配版本。
表格结构识别(Table Structure Recognition)- 识别表格的行列结构、合并单元格和布局
softmax_1.tmp_0,形状 [1, 501, 30]fill_constant_15.tmp_0.1.0,形状 [1, 501, 4]当前状态:NPU 推理暂不可用
本模型使用 ONNX Loop 算子(opset 14)实现 Attention-based LSTM 序列解码器。当前 CANNExecutionProvider(onnxruntime-cann 1.24.4)不支持 ONNX Loop 算子,导致以下错误:
CANN Graph error executing ge::aclgrphParseONNXFromMemATC(Ascend Tensor Compiler)工具同样不支持 Loop 算子转换:
No operator plugin is registered for Op: Loop.0, optype: ai.onnx::14::Looppip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnxruntime numpy Pillow opencv-python-headlesspython3 inference.py /path/to/table_image.png该脚本会同时在 CPU 上进行推理,并尝试 NPU(CANN)推理,输出对比结果。
| 设备 | 测试图片 | 推理耗时 | 检测结果 |
|---|---|---|---|
| CPU | test_table.png | 0.81s | 4 列 × 5 行表格结构 |
| CPU | test_document.png | 0.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>"运行精度对比脚本:
python3 compare_cpu_npu.py该脚本会依次:
compare_results.json| 测试图片 | CPU Run1 vs Run2 预测一致性 | HTML 一致 | NPU 状态 |
|---|---|---|---|
| test_table.png | 100.0000% | 是 | 不可用(Loop 算子限制) |
| test_document.png | 100.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)。