pytorch 模型量化处理及导出onnx格式模型

量化处理可以加快推理速度,减少模型占用空间 ,提高推理性能的必要选择。

量化时需要对算子进行量化处理,对输入数据fp32格式进行量化处理到int8, 再输入模型中。

最后测试了两种模型相对于torch原始模型的误差均值。

import torch
import torch.quantization


class M(torch.nn.Module):
    def __init__(self):
        super(M, self).__init__()
        self.quant = torch.quantization.QuantStub()  # 静态量化时量化桩用于量化数据
        self.conv = torch.nn.Conv2d(1, 1, 1)
        self.relu = torch.nn.ReLU()
        self.dequant = torch.quantization.DeQuantStub() #取消量化桩

    def forward(self, x):
        x = self.quant(x) #量化数据,从fp32->uint8
        x = self.conv(x)  #量化后conv
        x = self.relu(x)    #量化后relu
        x = self.dequant(x) #恢复量化变量为fp32
        return x

# create a model instance
model_fp32 = M()  #创建模型
model_fp32.eval() #推理模式
model_fp32.qconfig = torch.quantization.get_default_qconfig('fbgemm') #设置量化配置
model_fp32_fused = torch.quantization.fuse_modules(model_fp32, [['conv', 'relu']]) #量化算子并融合
model_fp32_prepared = torch.quantization.prepare(model_fp32_fused) #准备
input_fp32 = torch.randn(4, 1, 4, 4) #产生伪数据用于测试模型
model_fp32_prepared(input_fp32) #数据量化操作,准备范围,刻度等
model_int8 = torch.quantization.convert(model_fp32_prepared) #量化数据


output_x = model_int8(input_fp32) #量化后推理
traced = torch.jit.trace(model_int8, (input_fp32,))  #用于演示trace方法
traced_script = torch.jit.script(model_int8, (input_fp32,)) #用于验证script方法

torch.onnx.export(model_int8,             # model being run
                    input_fp32,                         # model input (or a tuple for multiple inputs)
                    './model_int8.onnx',   # where to save the model (can be a file or file-like object)
                    export_params=True,        # store the trained parameter weights inside the model file
                    opset_version=13,          # the ONNX version to export the model to
                    #do_constant_folding=True,  # whether to execute constant folding for optimization
                    input_names = ['input'],   # the model's input names
                    #output_names = ['output'], # the model's output names
                    #example_outputs=traced(input_fp32)
                    )

torch.onnx.export(traced,             # model being run
                    input_fp32,                         # model input (or a tuple for multiple inputs)
                    './model_int8_trace.onnx',   # where to save the model (can be a file or file-like object)
                    export_params=True,        # store the trained parameter weights inside the model file
                    opset_version=13,          # the ONNX version to export the model to
                    do_constant_folding=True,  # whether to execute constant folding for optimization
                    input_names = ['input'],   # the model's input names
                    output_names = ['output'], # the model's output names
                  #  example_outputs=traced(input_fp32)
                    )

onnx_pth= './model_int8.onnx'

oxx_m = ort.InferenceSession(onnx_pth)
onnx_blob = input_fp32.data.numpy()
onnx_out = oxx_m.run(None, {'input':onnx_blob})[0]

print('mean diff of int8 onnx= ', np.mean(onnx_out - torch_out.data.numpy()))

onnx_pth='./model_int8_trace.onnx'
oxx_m = ort.InferenceSession(onnx_pth)
onnx_out2 = oxx_m.run(None, {'input':onnx_blob})[0]

print('mean diff of traced int8 onnx= ', np.mean(onnx_out2 - torch_out.data.numpy()))


# for traced

traced_out=traced(input_fp32)

print('mean diff of traced torch= ', np.mean(traced_out.data.numpy() - torch_out.data.numpy()))
# for script
script_out=traced_script(input_fp32)

print('mean diff of script torch= ', np.mean(script_out.data.numpy() - torch_out.data.numpy()))
#保存模型,可以用于pnnx转换ncnn
torch.jit.save(traced,"./jit_trace.pth")
torch.jit.save(traced_script,"jit_script.pth")

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
ONNX模型量化int8是一种将模型数据从浮点表示换为8位整数表示的优化方法。这种量化方法可以带来多个好处。首先,使用8位整数数据进行计算时,NVIDIA GPU可以使用更快更低成本的8位张量核来执行卷积和矩阵乘法运算,从而提高计算吞吐量。其次,将数据从内存移动到计算单元需要时间和能量,并且会产生热量,将激活和参数数据的精度从32位浮点值降低到8位整数可以减少数据量,从而节省能量并减少热量的产生。此外,对于具有带宽限制的层,减少内存占用可以提高缓存利用率和参数更新效率。因此,ONNX模型量化int8是一种有效的优化方法,可以在保持模型准确性的同时提高计算效率和节省资源。\[3\] 要将模型量化为int8,可以使用PyTorch的torch.onnx.export函数将模型导出ONNX格式,并在导出时设置opset_version为13以支持每通道量化(PCQ)。在导出时,还可以将do_constant_folding参数设置为True,以生成更小且可读性更好的模型。以下是导出模型ONNX并进行量化的示例代码: ``` import torch import torchvision import torch.onnx # 初始化模型 model = torchvision.models.__dict__\[model_name\](pretrained=pretrained) # 导出模型ONNX dummy_input = torch.randn(1, 3, 224, 224) # 输入的示例数据 onnx_filename = "model.onnx" # 导出ONNX文件名 opset_version = 13 # 使用的opset版本 torch.onnx.export(model, dummy_input, onnx_filename, verbose=False, opset_version=opset_version, do_constant_folding=True) ``` 通过以上代码,您可以将PyTorch模型导出ONNX格式,并在导出时进行量化,从而将模型数据换为int8表示。\[2\] #### 引用[.reference_title] - *1* *2* *3* [利用TensorRT实现INT8量化感知训练QAT](https://blog.csdn.net/zong596568821xp/article/details/120904429)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值