AI-深度学习

嵌入式视觉模型进阶 28:面向 NPU 的计算图与算子兼容

展开合集目录
  1. 嵌入式视觉模型进阶 01:怎样读懂一个实际模型
  2. 嵌入式视觉模型进阶 02:卷积进阶:分组、深度、逐点与空洞卷积
  3. 嵌入式视觉模型进阶 03:MobileNet:深度可分离卷积与倒残差
  4. 嵌入式视觉模型进阶 04:通道注意力与 MobileNetV3
  5. 嵌入式视觉模型进阶 05:ShuffleNet:通道拆分与重排
  6. 嵌入式视觉模型进阶 06:结构重参数化:训练分支怎样合为一个卷积
  7. 嵌入式视觉模型进阶 07:Backbone、Neck、Head 与多尺度特征
  8. 嵌入式视觉模型进阶 08:FPN 与 PAN:怎样融合不同尺度的信息
  9. 嵌入式视觉模型进阶 09:检测头:分类、位置与置信度
  10. 嵌入式视觉模型进阶 10:检测训练:标签分配与损失计算
  11. 嵌入式视觉模型进阶 11:完整 YOLOv8 推理:从图片到原图目标框
  12. 嵌入式视觉模型进阶 12:训练自己的检测器与错误分析
  13. 嵌入式视觉模型进阶 13:检测器导出对照与其他结构路线
  14. 嵌入式视觉模型进阶 14:跟踪基础:运动预测、匹配与轨迹生命周期
  15. 嵌入式视觉模型进阶 15:ByteTrack 思路:用低分框恢复已有轨迹
  16. 嵌入式视觉模型进阶 16:外观特征与 ReID:怎样比较两个目标
  17. 嵌入式视觉模型进阶 17:目标跟随:从轨迹到云台控制接口
  18. 嵌入式视觉模型进阶 18:视频系统:队列、时间戳与异步流水线
  19. 嵌入式视觉模型进阶 19:人脸处理流程:检测、关键点与对齐
  20. 嵌入式视觉模型进阶 20:特征识别:人脸向量、相似度与阈值
  21. 嵌入式视觉模型进阶 21:人体关键点与姿态估计
  22. 嵌入式视觉模型进阶 22:OCR 检测:从文字区域到矫正图片
  23. 嵌入式视觉模型进阶 23:OCR 识别:序列模型与 CTC
  24. 嵌入式视觉模型进阶 24:完整 OCR 流程与识别错误分析
  25. 嵌入式视觉模型进阶 25:轻量语义分割与实例分割
  26. 嵌入式视觉模型进阶 26:工业异常检测:缺陷样本少时怎么办
  27. 嵌入式视觉模型进阶 27:深度估计与图像恢复:两个专题入口
  28. 嵌入式视觉模型进阶 28:面向 NPU 的计算图与算子兼容
  29. 嵌入式视觉模型进阶 29:量化、蒸馏与剪枝的实际取舍
  30. 嵌入式视觉模型进阶 30:综合项目:检测、跟踪与云台跟随验收
嵌入式视觉模型进阶 28:面向 NPU 的计算图与算子兼容的封面

第 28 / 30 课。 前置:上一课。本篇的运行范围以实验说明和验证记录为准,构造样例不代表真实任务精度或板端性能。

支持一个算子名字还不够

Conv 的支持可能受 kernel、stride、groups、通道数、布局、数据类型和张量尺寸限制。算子都在支持表中,整图仍可能因动态 shape 或编译内存约束失败。本课的白名单仅用于演示审查方法,不代表任何海思芯片支持表。

固定输入的 H、W 并不保证内部计算都变成静态;Shape、Gather、Reshape 等组合可能保留形状计算。应先做模型检查与 shape inference,再查看编译器实际处理结果。

替换必须证明数值与任务效果

本课把 Hard-Swish 写成 Add、Clip、Mul、Div,比较其与框架原算子的输出。代数等价不保证执行速度相同,编译器可能融合原算子,反而对拆解图执行更多节点。

不要只因为某个算子转换失败就删除它。LayerNorm、Softmax、插值模式和坐标变换都承载模型语义;近似替换需要原始数值对照和真实验证集评价。

分区与 CPU 回退

某些运行环境可把不支持的片段放到 CPU,这不等于全图在 NPU 运行。频繁分区可能造成设备间拷贝、同步和缓存维护开销。模型很小而整体很慢时,应检查分区边界,而不只是减少权重。

脚本导出教学网络、打印算子类型与输入 shape,并用示意白名单标出需人工复核的节点。它不调用专有编译器,也不输出虚构的板端支持结论。

练习与平台衔接

加入动态 batch 或不同插值,观察图变化。建立“节点—限制—处理策略—数值验证—板端耗时”表,然后进入海思 NPU 模型转换按实际 SDK 文档验证。

交付转换日志、工具版本、输入契约和失败最小模型。不要只保留一个最终二进制,否则后续无法判断是模型变化还是编译工具变化导致结果差异。

配套实验与运行记录

实验:面向 NPU 的计算图与算子兼容

查看完整代码:main.py
"""检查 ONNX 静态形状、算子和数值替换,建立真实编译报告的阅读方法。"""

from pathlib import Path
from tempfile import TemporaryDirectory
from collections import Counter
import torch
from torch import nn
import onnx


class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv = nn.Conv2d(3, 4, 3, padding=1)

    def forward(self, x):
        x = self.conv(x)
        return x * torch.clamp(x + 3, 0, 6) / 6


def main():
    torch.manual_seed(7)
    torch.set_num_threads(2)
    net = Net().eval()
    x = torch.rand(1, 3, 16, 16)
    z = net.conv(x)
    torch.testing.assert_close(net(x), nn.functional.hardswish(z))
    with TemporaryDirectory() as directory:
        path = Path(directory) / "graph.onnx"
        torch.onnx.export(
            net, (x,), str(path), opset_version=17, dynamo=False, input_names=["images"]
        )
        graph = onnx.shape_inference.infer_shapes(onnx.load(path))
        onnx.checker.check_model(graph)
        ops = Counter(node.op_type for node in graph.graph.node)
        example_allow = {"Conv", "Add", "Mul", "Constant", "Div"}
        print("ops", dict(ops))
        print("review against DEMO allowlist:", sorted(set(ops) - example_allow))
        dims = graph.graph.input[0].type.tensor_type.shape.dim
        assert all(d.HasField("dim_value") and d.dim_value > 0 for d in dims)
        print(
            "static input",
            [d.dim_value for d in dims],
            "not a device compatibility result",
        )


if __name__ == "__main__":
    main()
下载代码

在项目根目录执行;下载包解压后,在解压目录执行 python3 main.py。

cd 'content/posts/AI-深度学习/嵌入式视觉模型进阶/28-面向 NPU 的计算图与算子兼容/code' && python3 main.py

在本篇代码目录执行 python3 main.py。依赖安装、可选入口见包内 README.md;实际运行结果见 verification.md。下载包包含本课使用的辅助模块与样例。

参考与进一步阅读

原始论文或官方文档用于核对结构、接口和适用范围。本篇代码是围绕教学目标编写的最小实验;除明确注明的完整入口外,不视为对应论文模型的完整复现。


完整进阶目录 · 入门系列 · 上一篇 · 下一篇