From d93aa905b9cf9a71013e5fdab2b5ba2ee16e6c5a Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 30 Nov 2020 09:02:13 -0800 Subject: [PATCH 1/5] [quant][fix] Add bias once in conv_fused Summary: Previously _conv_forward will add self.bias to the result, so bias is added twice in qat ConvBn module this PR added a bias argument to _conv_forward and _conv_forward is called with zero bias in ConvBn module Test Plan: Reviewers: Subscribers: Tasks: Tags: [ghstack-poisoned] --- test/quantization/test_qat_module.py | 3 ++- torch/nn/intrinsic/qat/modules/conv_fused.py | 5 +++-- torch/nn/modules/conv.py | 16 ++++++++-------- torch/nn/qat/modules/conv.py | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/test/quantization/test_qat_module.py b/test/quantization/test_qat_module.py index 4144c0744104..f33719ac3c3f 100644 --- a/test/quantization/test_qat_module.py +++ b/test/quantization/test_qat_module.py @@ -52,6 +52,7 @@ def __init__(self, self.register_buffer('num_batches_tracked', torch.tensor(0, dtype=torch.long)) self.activation_post_process = self.qconfig.activation() self.weight_fake_quant = self.qconfig.weight() + self.zero_bias = nn.Parameter(torch.Tensor(out_channels)) if bias: self.bias = nn.Parameter(torch.Tensor(out_channels)) else: @@ -110,7 +111,7 @@ def _forward(self, input): running_std = torch.sqrt(self.running_var + self.eps) scale_factor = self.gamma / running_std scaled_weight = self.weight * scale_factor.reshape([-1, 1, 1, 1]) - conv = self._conv_forward(input, self.weight_fake_quant(scaled_weight)) + conv = self._conv_forward(input, self.weight_fake_quant(scaled_weight), self.zero_bias) if self.training and not self.freeze_bn: # recovering original conv to get original batch_mean and batch_var diff --git a/torch/nn/intrinsic/qat/modules/conv_fused.py b/torch/nn/intrinsic/qat/modules/conv_fused.py index 659d284b2afd..4dd2da681ccd 100644 --- a/torch/nn/intrinsic/qat/modules/conv_fused.py +++ b/torch/nn/intrinsic/qat/modules/conv_fused.py @@ -43,6 +43,7 @@ def __init__(self, self.freeze_bn = freeze_bn if self.training else True self.bn = _BN_CLASS_MAP[dim](out_channels, eps, momentum, True, True) self.weight_fake_quant = self.qconfig.weight() + self.zero_bias = Parameter(torch.Tensor(out_channels)) if bias: self.bias = Parameter(torch.Tensor(out_channels)) else: @@ -94,7 +95,7 @@ def _forward(self, input): bias_shape[1] = -1 scaled_weight = self.weight_fake_quant(self.weight * scale_factor.reshape(weight_shape)) # this does not include the conv bias - conv = self._conv_forward(input, scaled_weight) + conv = self._conv_forward(input, scaled_weight, self.zero_bias) conv_orig = conv / scale_factor.reshape(bias_shape) if self.bias is not None: conv_orig = conv_orig + self.bias.reshape(bias_shape) @@ -402,7 +403,7 @@ def __init__(self, in_channels, out_channels, kernel_size, stride=1, def forward(self, input): return F.relu( - self._conv_forward(input, self.weight_fake_quant(self.weight))) + self._conv_forward(input, self.weight_fake_quant(self.weight), self.bias)) @classmethod def from_float(cls, mod): diff --git a/torch/nn/modules/conv.py b/torch/nn/modules/conv.py index 7fae70b601b4..01f6c69daa23 100644 --- a/torch/nn/modules/conv.py +++ b/torch/nn/modules/conv.py @@ -245,16 +245,16 @@ def __init__( in_channels, out_channels, kernel_size, stride, padding, dilation, False, _single(0), groups, bias, padding_mode) - def _conv_forward(self, input, weight): + def _conv_forward(self, input, weight, bias): if self.padding_mode != 'zeros': return F.conv1d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode), - weight, self.bias, self.stride, + weight, bias, self.stride, _single(0), self.dilation, self.groups) - return F.conv1d(input, weight, self.bias, self.stride, + return F.conv1d(input, weight, bias, self.stride, self.padding, self.dilation, self.groups) def forward(self, input: Tensor) -> Tensor: - return self._conv_forward(input, self.weight) + return self._conv_forward(input, self.weight, self.bias) class Conv2d(_ConvNd): @@ -381,16 +381,16 @@ def __init__( in_channels, out_channels, kernel_size, stride, padding, dilation, False, _pair(0), groups, bias, padding_mode) - def _conv_forward(self, input, weight): + def _conv_forward(self, input, weight, bias): if self.padding_mode != 'zeros': return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode), - weight, self.bias, self.stride, + weight, bias, self.stride, _pair(0), self.dilation, self.groups) - return F.conv2d(input, weight, self.bias, self.stride, + return F.conv2d(input, weight, bias, self.stride, self.padding, self.dilation, self.groups) def forward(self, input: Tensor) -> Tensor: - return self._conv_forward(input, self.weight) + return self._conv_forward(input, self.weight, self.bias) class Conv3d(_ConvNd): __doc__ = r"""Applies a 3D convolution over an input signal composed of several input diff --git a/torch/nn/qat/modules/conv.py b/torch/nn/qat/modules/conv.py index a9c5f8547329..4b3814983347 100644 --- a/torch/nn/qat/modules/conv.py +++ b/torch/nn/qat/modules/conv.py @@ -29,7 +29,7 @@ def __init__(self, in_channels, out_channels, kernel_size, stride=1, self.weight_fake_quant = qconfig.weight() def forward(self, input): - return self._conv_forward(input, self.weight_fake_quant(self.weight)) + return self._conv_forward(input, self.weight_fake_quant(self.weight), self.bias) @classmethod def from_float(cls, mod): From a8dcb8c3ec8736eb2c43d7abcf9c4a5312470d06 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 30 Nov 2020 09:51:22 -0800 Subject: [PATCH 2/5] Update on "[quant][fix] Add bias once in conv_fused" Summary: Previously _conv_forward will add self.bias to the result, so bias is added twice in qat ConvBn module this PR added a bias argument to _conv_forward and _conv_forward is called with zero bias in ConvBn module fixes: https://github.com/pytorch/pytorch/issues/48514 Test Plan: Reviewers: Subscribers: Tasks: Tags: [ghstack-poisoned] --- torch/nn/modules/conv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torch/nn/modules/conv.py b/torch/nn/modules/conv.py index 01f6c69daa23..a3aceca46a5a 100644 --- a/torch/nn/modules/conv.py +++ b/torch/nn/modules/conv.py @@ -381,7 +381,7 @@ def __init__( in_channels, out_channels, kernel_size, stride, padding, dilation, False, _pair(0), groups, bias, padding_mode) - def _conv_forward(self, input, weight, bias): + def _conv_forward(self, input: Tensor, weight: Tensor, bias: Optional[Tensor]): if self.padding_mode != 'zeros': return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode), weight, bias, self.stride, From 99eeb3246d3f3fba0d47ddded413be47f15cbfbf Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 30 Nov 2020 10:13:51 -0800 Subject: [PATCH 3/5] Update on "[quant][fix] Add bias once in conv_fused" Summary: Previously _conv_forward will add self.bias to the result, so bias is added twice in qat ConvBn module this PR added a bias argument to _conv_forward and _conv_forward is called with zero bias in ConvBn module fixes: https://github.com/pytorch/pytorch/issues/48514 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: [D25222215](https://our.internmc.facebook.com/intern/diff/D25222215) [ghstack-poisoned] --- test/quantization/test_qat_module.py | 2 +- torch/nn/intrinsic/qat/modules/conv_fused.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/quantization/test_qat_module.py b/test/quantization/test_qat_module.py index f33719ac3c3f..2d81d292d782 100644 --- a/test/quantization/test_qat_module.py +++ b/test/quantization/test_qat_module.py @@ -52,7 +52,7 @@ def __init__(self, self.register_buffer('num_batches_tracked', torch.tensor(0, dtype=torch.long)) self.activation_post_process = self.qconfig.activation() self.weight_fake_quant = self.qconfig.weight() - self.zero_bias = nn.Parameter(torch.Tensor(out_channels)) + self.zero_bias = torch.Tensor(out_channels) if bias: self.bias = nn.Parameter(torch.Tensor(out_channels)) else: diff --git a/torch/nn/intrinsic/qat/modules/conv_fused.py b/torch/nn/intrinsic/qat/modules/conv_fused.py index 4dd2da681ccd..627abf956a41 100644 --- a/torch/nn/intrinsic/qat/modules/conv_fused.py +++ b/torch/nn/intrinsic/qat/modules/conv_fused.py @@ -43,7 +43,7 @@ def __init__(self, self.freeze_bn = freeze_bn if self.training else True self.bn = _BN_CLASS_MAP[dim](out_channels, eps, momentum, True, True) self.weight_fake_quant = self.qconfig.weight() - self.zero_bias = Parameter(torch.Tensor(out_channels)) + self.zero_bias = torch.Tensor(out_channels) if bias: self.bias = Parameter(torch.Tensor(out_channels)) else: From b82c77286e7380a1f854b98813a0e6a224ee1f37 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 30 Nov 2020 10:22:31 -0800 Subject: [PATCH 4/5] Update on "[quant][fix] Add bias once in conv_fused" Summary: Previously _conv_forward will add self.bias to the result, so bias is added twice in qat ConvBn module this PR added a bias argument to _conv_forward and _conv_forward is called with zero bias in ConvBn module fixes: https://github.com/pytorch/pytorch/issues/48514 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: [D25222215](https://our.internmc.facebook.com/intern/diff/D25222215) [ghstack-poisoned] --- test/quantization/test_qat_module.py | 2 +- torch/nn/intrinsic/qat/modules/conv_fused.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/quantization/test_qat_module.py b/test/quantization/test_qat_module.py index 2d81d292d782..cb0eab60598c 100644 --- a/test/quantization/test_qat_module.py +++ b/test/quantization/test_qat_module.py @@ -52,7 +52,7 @@ def __init__(self, self.register_buffer('num_batches_tracked', torch.tensor(0, dtype=torch.long)) self.activation_post_process = self.qconfig.activation() self.weight_fake_quant = self.qconfig.weight() - self.zero_bias = torch.Tensor(out_channels) + self.zero_bias = torch.zeros(out_channels) if bias: self.bias = nn.Parameter(torch.Tensor(out_channels)) else: diff --git a/torch/nn/intrinsic/qat/modules/conv_fused.py b/torch/nn/intrinsic/qat/modules/conv_fused.py index 627abf956a41..6ab402528d71 100644 --- a/torch/nn/intrinsic/qat/modules/conv_fused.py +++ b/torch/nn/intrinsic/qat/modules/conv_fused.py @@ -43,7 +43,7 @@ def __init__(self, self.freeze_bn = freeze_bn if self.training else True self.bn = _BN_CLASS_MAP[dim](out_channels, eps, momentum, True, True) self.weight_fake_quant = self.qconfig.weight() - self.zero_bias = torch.Tensor(out_channels) + self.zero_bias = torch.zeros(out_channels) if bias: self.bias = Parameter(torch.Tensor(out_channels)) else: From 17e2dbb8b874b96a5b4d5f17149eaf70cf18151c Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 30 Nov 2020 14:23:57 -0800 Subject: [PATCH 5/5] Update on "[quant][fix] Add bias once in conv_fused" Summary: Previously _conv_forward will add self.bias to the result, so bias is added twice in qat ConvBn module this PR added a bias argument to _conv_forward and _conv_forward is called with zero bias in ConvBn module fixes: https://github.com/pytorch/pytorch/issues/48514 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: [D25222215](https://our.internmc.facebook.com/intern/diff/D25222215) [ghstack-poisoned] --- torch/nn/modules/conv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/torch/nn/modules/conv.py b/torch/nn/modules/conv.py index 81897b747fa8..f319aa1d733e 100644 --- a/torch/nn/modules/conv.py +++ b/torch/nn/modules/conv.py @@ -245,7 +245,7 @@ def __init__( in_channels, out_channels, kernel_size, stride, padding, dilation, False, _single(0), groups, bias, padding_mode) - def _conv_forward(self, input, weight, bias): + def _conv_forward(self, input: Tensor, weight: Tensor, bias: Optional[Tensor]): if self.padding_mode != 'zeros': return F.conv1d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode), weight, bias, self.stride,