onnx模型结构优化相关记录

项目场景:

当我们使用torch模型转换为onnx模型时往往会遇到,在torch代码里就是一个算子,但是转换成onnx时就可能是好几个算子的组合形式。比如groupnorm算子就是一个很好的例子,转成onnx格式时如下所示:
在这里插入图片描述


问题描述

如下代码所示,我们使用torch定义了一个groupnorm算子,然后将该算子转换为onnx格式。

import torch
import torch.nn as nn

class PureGroupNormModel(nn.Module):
    def __init__(self):
        super().__init__()
        # 创建一个只有GroupNorm层的模型
        self.gn = nn.GroupNorm(num_groups=4, num_channels=8)
    
    def forward(self, x):
        # 直接返回GroupNorm计算结果
        return self.gn(x)

# 创建模型实例
model = PureGroupNormModel()
model.eval()  # 设置为评估模式

# 创建符合GroupNorm要求的输入张量
# 格式: (batch_size, num_channels, height, width)
dummy_input = torch.randn(1, 8, 64, 64)  # 确保通道数匹配num_channels

# 导出ONNX文件
onnx_path = "pure_groupnorm.onnx"

torch.onnx.export(
    model,                   # 待导出的模型
    dummy_input,             # 模型输入
    onnx_path,              # 保存路径
    opset_version=13,        # ONNX算子集版本
    do_constant_folding=True,  # 优化常量
    input_names=['input'],   # 输入名称
    output_names=['output'], # 输出名称
)

print(f"Successfully exported ONNX model to {onnx_path}")

但是,我们在打开onnx文件的时候,却发现文件中并不是以groupnorm算子表示的,而是以几个小算子的组合形式出现。但是,这种算子组合可能会造成一个问题,就是推理框架在解析该onnx文件时,会以算子组合去跑。并不会调到groupnorm算子,影响推理性能。
在这里插入图片描述
因此,我们希望是转换成一个groupnorm算子的onnx文件。


原因分析:

首先,我们去查看一下ONNX中groupnorm的算子定义。发现groupnorm算子是在opset18版本下才开始支持。

下面是ONNX中groupnorm支持的版本:
在这里插入图片描述
我们在转换代码中,设置的opset=13,可能是这个原因造成的。因此,我们修改opset=18重新转换onnx模型文件。查看文件发现,依然是算子组合形式。
在这里插入图片描述
针对这个问题,询问一下deepseek解释一下原因:
在这里插入图片描述
其中,第一条和第二条是符合的。第三条确实没有设置,针对此问题重新设置导出:
在这里插入图片描述
依然失败。


解决方案:

在我实在想不到的情况下,发现了一个比较好用的工具就是:onnxruntime.transformers工具。

from onnxruntime.transformers import onnx_model
from onnxruntime.transformers.fusion import FusionGroupNorm

def fuse_groupnorm(onnx_path):
    # 加载模型
    model = onnx_model.OnnxModel(onnx.load(onnx_path))
    
    # 创建并应用融合器
    fusion_manager = fusion.FusionGroupNorm(model)
    fusion_manager.apply()
    
    # 保存优化后的模型
    model.save_model_to_file(onnx_path.replace('.onnx', '_fused.onnx'))

通过该方法成功的将groupnorm算子合并到一起,如下图所示:
在这里插入图片描述而且该工具还默认将数据布局转换为NHWC格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值