666DZY666 / micronet

micronet, a model compression and deploy lib. compression: 1、quantization: quantization-aware-training(QAT), High-Bit(>2b)(DoReFa/Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference)、Low-Bit(≤2b)/Ternary and Binary(TWN/BNN/XNOR-Net); post-training-quantization(PTQ), 8-bit(tensorrt); 2、 pruning: normal、regular and group convolutional channel pruning; 3、 group convolution structure; 4、batch-normalization fuse for quantization. deploy: tensorrt, fp32/fp16/int8(ptq-calibration)、op-adapt(upsample)、dynamic_shape
MIT License
2.22k stars 478 forks source link

量化流程细节的疑问? #27

Open VisionZQ opened 4 years ago

VisionZQ commented 4 years ago

Hi, 感谢自己的分享。在代码中有一处疑问向你请假一下,

image

对权重和输入执行量化后进行卷积操作,但在代码对权重进行量化时,为什么还进行了反量化的操作,数据也是如此,且这反量化都在卷积之前,有点疑惑?

二,有考虑过量化后部署的问题吗?目前似乎三方工具都不直接支持。

666DZY666 commented 4 years ago

1、采用量化/反量化这个方式在之前范围实现离散化(量化)。量化-反量化-卷积 和 量化-卷积-反量化的结果是一样的。这里的量化训练采用前者是为了方便写代码,模拟量化的过程,验证量化精度;量化部署采用后者,量化卷积实现加速; 2、可以这样考虑,一方面如果是在通用平台部署可以自己做下剪枝等,然后放到已有框架上量化部署;一方面如果是FPGA或ASIC等,可以自己做剪枝/量化等,然后把纯参数提取出来去部署。当然,框架里也有压缩的部分,但大部分框架压缩这块儿其实做的不太好,且操作自由度不太高,也有必要借鉴下。

VisionZQ commented 4 years ago

谢谢。又Review了一次论文,理解到了。

BADBADBADBOY commented 4 years ago

1、采用量化/反量化这个方式在之前范围实现离散化(量化)。量化-反量化-卷积 和 量化-卷积-反量化的结果是一样的。这里的量化训练采用前者是为了方便写代码,模拟量化的过程,验证量化精度;量化部署采用后者,量化卷积实现加速; 2、可以这样考虑,一方面如果是在通用平台部署可以自己做下剪枝等,然后放到已有框架上量化部署;一方面如果是FPGA或ASIC等,可以自己做剪枝/量化等,然后把纯参数提取出来去部署。当然,框架里也有压缩的部分,但大部分框架压缩这块儿其实做的不太好,且操作自由度不太高,也有必要借鉴下。

您好,我这样操作后,发现结果不对,请问是哪里有问题吗,代码如下@666DZY666 @VisionZQ

import torch.nn.functional as F

bias = torch.rand(160).cuda()
weight = torch.rand(160,192,1,1).cuda()
q_input =torch.rand(1,192,224,224).cuda()
scale = torch.rand(160,1,1,1).cuda()
zero_point = torch.rand(160,1,1,1).cuda()

weight1 = quantize(weight,scale,zero_point)   ##### 量化
weight1 = torch.round(weight1)
weight1 = clamp(weight1, 0, 255)
weight1 = dequantize(weight1,scale,zero_point) ##### 反量化
output = F.conv2d(
    input=q_input,
    weight=weight1,
    bias=None,
    stride=1,
    padding=0,
    dilation=1,
    groups=1
)                                                                         #### 卷积
output1= output + bias.reshape(1, 160, 1, 1)
print(output1[0,0,0:5,0:5])

weight2 = quantize(weight, scale, zero_point)  ##### 量化
weight2 = torch.round(weight2)
weight2 = clamp(weight2, 0, 255)

output = F.conv2d(
    input=q_input,
    weight=weight2,
    bias=None,
    stride=1,
    padding=0,
    dilation=1,
    groups=1
)                                                                      #### 卷积
output = dequantize(output, scale.reshape(1,160,1,1), zero_point.reshape(1,160,1,1)     )##### 反量化
output2 = output+bias.reshape(1,160,1,1)
print(output2[0,0,0:5,0:5])
ghost commented 4 years ago

谢谢。又Review了一次论文,理解到了。

嗨,您好,请问您做博主说的这个量化、卷积、反量化这个训练操作了吗?

Mazhengyu93 commented 3 years ago

1、采用量化/反量化这个方式在之前范围实现离散化(量化)。量化-反量化-卷积 和 量化-卷积-反量化的结果是一样的。这里的量化训练采用前者是为了方便写代码,模拟量化的过程,验证量化精度;量化部署采用后者,量化卷积实现加速; 2、可以这样考虑,一方面如果是在通用平台部署可以自己做下剪枝等,然后放到已有框架上量化部署;一方面如果是FPGA或ASIC等,可以自己做剪枝/量化等,然后把纯参数提取出来去部署。当然,框架里也有压缩的部分,但大部分框架压缩这块儿其实做的不太好,且操作自由度不太高,也有必要借鉴下。

你好,感谢作者的杰出工作,小白想请问一下:但是直接量化/反量化,那么数据分布就不在原先设计的8bit范围内了啊,期待您的回复