ONNX结构及构建抽取子图及编辑onnx 模型

ONNX结构

https://mmdeploy.readthedocs.io/zh-cn/latest/tutorial/05_onnx_model_editing.html

https://blog.csdn.net/u013597931/article/details/84401047

https://zhuanlan.zhihu.com/p/346511883

https://zhuanlan.zhihu.com/p/353613079

https://zhuanlan.zhihu.com/p/350702340

https://zhuanlan.zhihu.com/p/350833729

ONNX抽取子图

https://github.com/onnx/onnx/blob/main/docs/PythonAPIOverview.md
https://blog.csdn.net/u013597931/article/details/84635779

import onnx
input_path = "path/to/the/original/model.onnx"
output_path = "path/to/save/the/extracted/model.onnx"
input_names = ["input_0", "input_1", "input_2"]
output_names = ["output_0", "output_1"]
onnx.utils.extract_model(input_path, output_path, input_names, output_names)

ONNX 获取每层节点名以及每层输入

import os
import glob
import subprocess
import numpy as np
import onnxruntime as ort
import onnx
import sys
import shutil
import copy
import json
from collections import OrderedDict
from utilities.utils import *
if __name__ == "__main__":
model = onnx.load("./tmp/deeplabv3.onnx")
# 模型推理
ori_output = copy.deepcopy(model.graph.output)
# 输出模型每层的输出
for node in model.graph.node:
for output in node.output:
if output not in ori_output:
model.graph.output.extend([onnx.ValueInfoProto(name=output)])
#进行配置
if ort.get_device()=="CPU":
config = ort.SessionOptions()
cpu_num_thread=4
config.intra_op_num_threads = cpu_num_thread
config.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
providers=["CPUExecutionProvider"]
ort_session = ort.InferenceSession(model.SerializeToString(),providers=providers,sess_options=config)
input = np.fromfile("./tmp/inputdata_fp32.bin", dtype='float32').reshape(8,519,519,3)
ort_inputs = {ort_session.get_inputs()[0].name: input}
#获取所有节点输出
outputs = [x.name for x in ort_session.get_outputs()] #ort_session.get_outputs()[0].name是原模型的单一输出
ort_outs = ort_session.run(output_names=outputs, input_feed=ort_inputs)
# 生成字典,便于查找层对应输出
# ort_outs = OrderedDict(zip(outputs, ort_outs))
result_outs = OrderedDict(zip(outputs, ort_outs))
# print("result_outs.keys(): ", result_outs.keys())
for key in result_outs.keys():
if "aspp/conv_1x1_concat/Relu:0" in key:
print("key: ", key)
# print(f'key --> {key} : value --> {result_outs[key]}')
print("value shape: ", result_outs[key].shape)
stc_out = np.fromfile("./tmp/test_dump/stc_cpu/aspp.bin", dtype='float32').reshape(result_outs[key].shape)
# verify_atol_rtol(stc_out, result_outs[key], atol=1e-6, rtol=5e-6)
verify_atol_rtol(stc_out, result_outs[key], atol=1e-2, rtol=5e-2)
# verify_atol_rtol(stc_out, result_outs[key], atol=0, rtol=0)
break

编辑onnx 模型

onnx模型编辑方法有2种:

  • onnx-graphsurgeon : 手工编辑onnx模型
  • onnx-modifier : 图形化编辑onnx模型

虽然onnx-modifier有图形界面编辑onnx,但是实际用起来问题特别多。onnx-graphsurgeon用起来更加强大,简洁。

安装方法如下:

pip install onnx_graphsurgeon --index-url https://pypi.ngc.nvidia.com

也可以源码编译安装:

make build
pip install onnx_graphsurgeon/dist/onnx_graphsurgeon-*-py2.py3-none-any.whl

基本操作

使用ipython命令进行交互式操作

import onnx_graphsurgeon as gs
import onnx
import numpy as np
graph = gs.import_onnx(onnx.load("test.onnx"))
graph #查看所有信息
graph.inputs #查看所有输入信息
graph.nodes #查看所有输出信息
graph.nodes[0] #查看node0的信息
onnx.save(gs.export_onnx(graph), "modified.onnx") # 保存onnx模型

新增节点

# 新增节点,对input做transpose
trans_out = gs.Variable("trans_out",dtype=np.float32, shape=(4,6,5,7))
trans_op=gs.Node(op="Transpose", inputs=[graph.inputs[0]], outputs=[trans_out], attrs={"perm":[0,2,1,3]})
# node0的输入改为trans_out
graph.nodes[0].inputs[0]=trans_out
# 插入到nodes中
graph.nodes.insert(0,trans_op)
# 修改input shape
graph.inputs[0].shape=[4,5,6,7]

https://harmonyhu.com/2021/11/17/onnx-edit/

posted @   michaelchengjl  阅读(129)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示