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]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY