EXPERIMENT / 配套代码

main.py

← 返回文章
下载代码

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

cd 'content/posts/AI-深度学习/嵌入式视觉模型进阶/28-面向 NPU 的计算图与算子兼容/code' && python3 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()