Source code for torch.ao.nn.quantized.modules.conv
# mypy: allow-untyped-defsr"""Quantized convolution modules."""fromtypingimportClassVar,List,Optional,Typeimporttorchimporttorch.ao.nn.intrinsicasnniimporttorch.ao.nn.intrinsic.qatasnniqatimporttorch.nnasnnimporttorch.nn.functionalasFfromtorch._opsimportopsfromtorch.nn.common_typesimport_size_1_tfromtorch.nn.modules.utilsimport_pair,_single,_triplefromtorch.nn.utilsimportfuse_conv_bn_weightsfrom.utilsimport_quantize_weight,WeightedQuantizedModule__all__=["Conv1d","Conv2d","Conv3d","ConvTranspose1d","ConvTranspose2d","ConvTranspose3d",]_SUPPORTED_PADDING={"zeros","reflect"}def_reverse_repeat_padding(padding:List[int])->List[int]:_reversed_padding_repeated_twice:List[int]=[]N=len(padding)foridxinrange(N):_reversed_padding_repeated_twice.extend(padding[N-idx-1]for_inrange(2))return_reversed_padding_repeated_twiceclass_ConvNd(WeightedQuantizedModule):def__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode="zeros",device=None,dtype=None,):# All subclasses have this signature - See PR #49702sraiseNotImplementedErrordef_init(self,in_channels,out_channels,kernel_size,stride,padding,dilation,transposed,output_padding,groups,bias,padding_mode="zeros",device=None,dtype=None,)->None:factory_kwargs={"device":device,"dtype":dtype}super().__init__()ifin_channels%groups!=0:raiseValueError("in_channels must be divisible by groups")ifout_channels%groups!=0:raiseValueError("out_channels must be divisible by groups")self.in_channels=in_channelsself.out_channels=out_channelsself.kernel_size=kernel_sizeself.stride=strideself.padding=paddingself.dilation=dilationself.transposed=transposedself.output_padding=output_paddingself.groups=groupsifpadding_modenotin_SUPPORTED_PADDING:raiseValueError(f"'padding_mode' {padding_mode} is not supported by quantized convolution")self.padding_mode=padding_mode# Initialize as NCHW. set_weight will internally transpose to NHWC.ifself.transposed:weight_shape=[in_channels,out_channels//self.groups]else:weight_shape=[out_channels,in_channels//self.groups]qweight=torch._empty_affine_quantized(weight_shape+list(kernel_size),scale=1,zero_point=0,dtype=torch.qint8,**{k:vfork,vinfactory_kwargs.items()ifk!="dtype"},)bias_float=(torch.zeros(out_channels,dtype=torch.float,**{k:vfork,vinfactory_kwargs.items()ifk!="dtype"},)ifbiaselseNone)self.set_weight_bias(qweight,bias_float)self.scale=1.0self.zero_point=0defset_weight_bias(self,qweight,bias_float):raiseNotImplementedErrordefbias(self):raiseNotImplementedErrordef_weight_bias(self):raiseNotImplementedErrordefextra_repr(self):s=("{in_channels}, {out_channels}, kernel_size={kernel_size}"", stride={stride}, scale={scale}, zero_point={zero_point}")ifself.padding!=(0,)*len(self.padding):s+=", padding={padding}"ifself.dilation!=(1,)*len(self.dilation):s+=", dilation={dilation}"ifself.output_padding!=(0,)*len(self.output_padding):s+=", output_padding={output_padding}"ifself.groups!=1:s+=", groups={groups}"ifself.bias()isNone:s+=", bias=False"returns.format(**self.__dict__)# ===== Serialization methods =====# The special consideration here is that we have to unpack the weights into# their regular QTensor form for serialization. Packed weights should not# live outside the process in which they were created, rather they should be# derived from the QTensor weight.# self# |--- weight : Tensor# |--- bias : Tensor## TODO: maybe change to this when https://github.com/pytorch/pytorch/pull/32958 is landed# self# |--- _packed_params : Conv2dPackedParamsBase or Conv3dPackedParamsBasedef_save_to_state_dict(self,destination,prefix,keep_vars):super()._save_to_state_dict(destination,prefix,keep_vars)(w,b)=self._weight_bias()destination[prefix+"weight"]=wdestination[prefix+"bias"]=bdestination[prefix+"scale"]=torch.tensor(self.scale)destination[prefix+"zero_point"]=torch.tensor(self.zero_point)@torch.jit.exportdef__getstate__(self):(w,b)=self._weight_bias()return(self.in_channels,self.out_channels,self.kernel_size,self.stride,self.padding,self.dilation,self.transposed,self.output_padding,self.groups,self.padding_mode,w,b,self.scale,self.zero_point,self.training,)# ===== Deserialization methods =====# Counterpart to the serialization methods, we must pack the serialized# QTensor weight into its packed format for use by the FBGEMM ops.def_load_from_state_dict(self,state_dict,prefix,local_metadata,strict,missing_keys,unexpected_keys,error_msgs,):self.set_weight_bias(state_dict[prefix+"weight"],state_dict[prefix+"bias"])state_dict.pop(prefix+"weight")state_dict.pop(prefix+"bias")self.scale=float(state_dict[prefix+"scale"])state_dict.pop(prefix+"scale")self.zero_point=int(state_dict[prefix+"zero_point"])state_dict.pop(prefix+"zero_point")super()._load_from_state_dict(state_dict,prefix,local_metadata,False,missing_keys,unexpected_keys,error_msgs,)@torch.jit.exportdef__setstate__(self,state):self.in_channels=state[0]self.out_channels=state[1]self.kernel_size=state[2]self.stride=state[3]self.padding=state[4]self.dilation=state[5]self.transposed=state[6]self.output_padding=state[7]self.groups=state[8]self.padding_mode=state[9]self.set_weight_bias(state[10],state[11])self.scale=state[12]self.zero_point=state[13]self.training=state[14]def__deepcopy__(self,memo):new_instance=type(self).__new__(type(self))torch.nn.Module.__init__(new_instance)state=self.__getstate__()new_instance.__setstate__(state)returnnew_instancedef__copy__(self):returnself.__deepcopy__({})@classmethoddefget_qconv(cls,mod,activation_post_process,weight_post_process=None):r"""Creates a qconv object and returns it."""ifweight_post_processisNone:weight_post_process=mod.qconfig.weight()weight_post_process(mod.weight)assert(weight_post_process.dtype==torch.qint8),"Weight observer must have a dtype of qint8"qweight=_quantize_weight(mod.weight.float(),weight_post_process)# the __init__ call used is the one from derived classes and not the one from _ConvNdqconv=cls(mod.in_channels,mod.out_channels,mod.kernel_size,mod.stride,mod.padding,mod.dilation,mod.groups,mod.biasisnotNone,mod.padding_mode,)qconv.set_weight_bias(qweight,mod.bias)if(activation_post_processisNoneoractivation_post_process.dtype==torch.float):returnqconv# dynamic quantization doesn't need scale/zero_pointelse:act_scale,act_zp=activation_post_process.calculate_qparams()qconv.scale=float(act_scale)qconv.zero_point=int(act_zp)returnqconv@staticmethoddeffrom_float(cls,mod,use_precomputed_fake_quant=False):ifhasattr(mod,"weight_fake_quant"):# assert type(mod) == cls.__QAT_MODULE, " nnq." + cls.__name__ + \# ".from_float only works for " + cls.__QAT_MODULE.__name__iftype(mod)==cls._NNIQAT_CONV_BN_MODULE:mod.weight,mod.bias=fuse_conv_bn_weights(mod.weight,mod.bias,mod.bn.running_mean,mod.bn.running_var,mod.bn.eps,mod.bn.weight,mod.bn.bias,)asserthasattr(mod,"activation_post_process"),"Input QAT module must have observer attached"weight_post_process=mod.weight_fake_quantactivation_post_process=mod.activation_post_processelse:asserttype(mod)==cls._FLOAT_MODULE,(" nnq."+cls.__name__+".from_float only works for "+cls._FLOAT_MODULE.__name__+" but got:"+str(type(mod)))asserthasattr(mod,"qconfig"),"Input float module must have qconfig defined."activation_post_process=(Noneifnothasattr(mod,"activation_post_process")elsemod.activation_post_process)iftype(mod)in[cls._NNI_CONV_RELU_MODULE,cls._NNI_CONV_ADD_MODULE,cls._NNI_CONV_ADD_RELU_MODULE,]:mod=mod[0]weight_post_process=mod.qconfig.weight()returncls.get_qconv(mod,activation_post_process,weight_post_process)@classmethoddeffrom_reference(cls,ref_qconv,output_scale,output_zero_point):r"""Create a (fbgemm/qnnpack) quantized module from a reference quantized module Args: ref_qconv (Module): a reference quantized module, either produced by torch.ao.quantization utilities or provided by the user output_scale (float): scale for output Tensor output_zero_point (int): zero point for output Tensor """qconv=cls(ref_qconv.in_channels,ref_qconv.out_channels,ref_qconv.kernel_size,# type: ignore[arg-type]ref_qconv.stride,# type: ignore[arg-type]ref_qconv.padding,# type: ignore[arg-type]ref_qconv.dilation,# type: ignore[arg-type]ref_qconv.groups,ref_qconv.biasisnotNone,# type: ignore[arg-type]ref_qconv.padding_mode,device=ref_qconv.weight.device,dtype=ref_qconv.weight.dtype,)qweight=ref_qconv.get_quantized_weight()qconv.set_weight_bias(qweight,ref_qconv.bias)qconv.scale=float(output_scale)qconv.zero_point=int(output_zero_point)returnqconv
[docs]classConv1d(_ConvNd):r"""Applies a 1D convolution over a quantized input signal composed of several quantized input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.Conv1d`. .. note:: Only `zeros` is supported for the :attr:`padding_mode` argument. .. note:: Only `torch.quint8` is supported for the input data type. Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.Conv1d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> m = nn.quantized.Conv1d(16, 33, 3, stride=2) >>> input = torch.randn(20, 16, 100) >>> # quantize input to quint8 >>> # xdoctest: +SKIP >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, ... dtype=torch.quint8) >>> output = m(q_input) """_FLOAT_MODULE:ClassVar[Type[nn.Conv1d]]=nn.Conv1d_NNIQAT_CONV_BN_MODULE:ClassVar[Optional[Type[nn.Module]]]=nniqat.ConvBn1d_NNI_CONV_RELU_MODULE:ClassVar[Optional[Type[nn.Module]]]=nni.ConvReLU1d_NNI_CONV_ADD_MODULE:ClassVar[Optional[Type[nn.Module]]]=None_NNI_CONV_ADD_RELU_MODULE:ClassVar[Optional[Type[nn.Module]]]=Nonedef__init__(self,in_channels:int,out_channels:int,kernel_size:_size_1_t,stride:_size_1_t=1,padding:_size_1_t=0,dilation:_size_1_t=1,groups:int=1,bias:bool=True,padding_mode:str="zeros",device=None,dtype=None,):factory_kwargs={"device":device,"dtype":dtype}kernel_size=_single(kernel_size)stride=_single(stride)padding=paddingifisinstance(padding,str)else_single(padding)dilation=_single(dilation)# Subclasses of _ConvNd needs to call _init rather than __init__. See# discussion on PR #49702super()._init(in_channels,out_channels,kernel_size,stride,padding,dilation,False,_single(0),groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConv1d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:ifself.padding_mode=="zeros":self._packed_params=torch.ops.quantized.conv1d_prepack(w,b,self.stride,self.padding,self.dilation,self.groups)else:self._packed_params=torch.ops.quantized.conv1d_prepack(w,b,self.stride,_pair(0),self.dilation,self.groups)def_weight_bias(self):w,b=torch.ops.quantized.conv1d_unpack(self._packed_params)returnw,bdefweight(self):returnself._weight_bias()[0]defbias(self):returnself._weight_bias()[1]defforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=3:raiseValueError("Input shape must be `(N, C, L)`!")ifself.padding_mode!="zeros":# Padding in Conv1d is stored as (p, p), need to get (p,)_reversed_padding_repeated_twice=_reverse_repeat_padding(self.padding[:1])input=F.pad(input,_reversed_padding_repeated_twice,mode=self.padding_mode)returnops.quantized.conv1d(input,self._packed_params,self.scale,self.zero_point)
[docs]@classmethoddeffrom_float(cls,mod,use_precomputed_fake_quant=False):r"""Creates a quantized module from a float module or qparams_dict. Args: mod (Module): a float module, either produced by torch.ao.quantization utilities or provided by the user """return_ConvNd.from_float(cls,mod,use_precomputed_fake_quant=use_precomputed_fake_quant)
[docs]classConv2d(_ConvNd):r"""Applies a 2D convolution over a quantized input signal composed of several quantized input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.Conv2d`. .. note:: Only `zeros` is supported for the :attr:`padding_mode` argument. .. note:: Only `torch.quint8` is supported for the input data type. Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.Conv2d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> # With square kernels and equal stride >>> m = nn.quantized.Conv2d(16, 33, 3, stride=2) >>> # non-square kernels and unequal stride and with padding >>> m = nn.quantized.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2)) >>> # non-square kernels and unequal stride and with padding and dilation >>> m = nn.quantized.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1)) >>> input = torch.randn(20, 16, 50, 100) >>> # quantize input to quint8 >>> # xdoctest: +SKIP >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> output = m(q_input) """_FLOAT_MODULE:ClassVar[Type[nn.Conv2d]]=nn.Conv2d_NNIQAT_CONV_BN_MODULE:ClassVar[Optional[Type[nn.Module]]]=nniqat.ConvBn2d_NNI_CONV_RELU_MODULE:ClassVar[Optional[Type[nn.Module]]]=nni.ConvReLU2d_NNI_CONV_ADD_MODULE:ClassVar[Type[nni.ConvAdd2d]]=nni.ConvAdd2d_NNI_CONV_ADD_RELU_MODULE:ClassVar[Type[nni.ConvAddReLU2d]]=nni.ConvAddReLU2ddef__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode="zeros",device=None,dtype=None,):factory_kwargs={"device":device,"dtype":dtype}kernel_size=_pair(kernel_size)stride=_pair(stride)padding=_pair(padding)dilation=_pair(dilation)# Subclasses of _ConvNd need to call _init rather than __init__. See# discussion on PR #49702super()._init(in_channels,out_channels,kernel_size,stride,padding,dilation,False,_pair(0),groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConv2d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:ifself.padding_mode=="zeros":self._packed_params=torch.ops.quantized.conv2d_prepack(w,b,self.stride,self.padding,self.dilation,self.groups)else:self._packed_params=torch.ops.quantized.conv2d_prepack(w,b,self.stride,_pair(0),self.dilation,self.groups)def_weight_bias(self):returnself._packed_params.unpack()defweight(self):returnself._weight_bias()[0]defbias(self):returnself._weight_bias()[1]defforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=4:raiseValueError("Input shape must be `(N, C, H, W)`!")ifself.padding_mode!="zeros":_reversed_padding_repeated_twice=_reverse_repeat_padding(self.padding)input=F.pad(input,_reversed_padding_repeated_twice,mode=self.padding_mode)returnops.quantized.conv2d(input,self._packed_params,self.scale,self.zero_point)
[docs]@classmethoddeffrom_float(cls,mod,use_precomputed_fake_quant=False):r"""Creates a quantized module from a float module or qparams_dict. Args: mod (Module): a float module, either produced by torch.ao.quantization utilities or provided by the user """return_ConvNd.from_float(cls,mod,use_precomputed_fake_quant=use_precomputed_fake_quant)
[docs]classConv3d(_ConvNd):r"""Applies a 3D convolution over a quantized input signal composed of several quantized input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.Conv3d`. .. note:: Only `zeros` is supported for the :attr:`padding_mode` argument. .. note:: Only `torch.quint8` is supported for the input data type. Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.Conv3d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> # With square kernels and equal stride >>> m = nn.quantized.Conv3d(16, 33, 3, stride=2) >>> # non-square kernels and unequal stride and with padding >>> m = nn.quantized.Conv3d(16, 33, (3, 5, 5), stride=(1, 2, 2), padding=(1, 2, 2)) >>> # non-square kernels and unequal stride and with padding and dilation >>> m = nn.quantized.Conv3d(16, 33, (3, 5, 5), stride=(1, 2, 2), padding=(1, 2, 2), dilation=(1, 2, 2)) >>> input = torch.randn(20, 16, 56, 56, 56) >>> # quantize input to quint8 >>> # xdoctest: +SKIP >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> output = m(q_input) """_FLOAT_MODULE:ClassVar[Type[nn.Conv3d]]=nn.Conv3d_NNIQAT_CONV_BN_MODULE:ClassVar[Optional[Type[nn.Module]]]=nniqat.ConvBn3d_NNI_CONV_RELU_MODULE:ClassVar[Optional[Type[nn.Module]]]=nni.ConvReLU3d_NNI_CONV_ADD_MODULE:ClassVar[Optional[Type[nn.Module]]]=None_NNI_CONV_ADD_RELU_MODULE:ClassVar[Optional[Type[nn.Module]]]=Nonedef__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode="zeros",device=None,dtype=None,):assertpadding_mode!="reflect","Conv3d does not support reflection padding"factory_kwargs={"device":device,"dtype":dtype}kernel_size=_triple(kernel_size)stride=_triple(stride)padding=_triple(padding)dilation=_triple(dilation)# Subclasses of _ConvNd need to call _init rather than __init__. See# discussion on PR #49702super()._init(in_channels,out_channels,kernel_size,stride,padding,dilation,False,_triple(0),groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConv3d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:ifself.padding_mode=="zeros":self._packed_params=torch.ops.quantized.conv3d_prepack(w,b,self.stride,self.padding,self.dilation,self.groups)else:self._packed_params=torch.ops.quantized.conv3d_prepack(w,b,self.stride,_triple(0),self.dilation,self.groups)def_weight_bias(self):returnself._packed_params.unpack()defweight(self):returnself._weight_bias()[0]defbias(self):returnself._weight_bias()[1]defforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=5:raiseValueError("Input shape must be `(N, C, D, H, W)`!")ifself.padding_mode!="zeros":_reversed_padding_repeated_twice=_reverse_repeat_padding(self.padding)input=F.pad(input,_reversed_padding_repeated_twice,mode=self.padding_mode)returnops.quantized.conv3d(input,self._packed_params,self.scale,self.zero_point)
[docs]@classmethoddeffrom_float(cls,mod,use_precomputed_fake_quant=False):r"""Creates a quantized module from a float module or qparams_dict. Args: mod (Module): a float module, either produced by torch.ao.quantization utilities or provided by the user """return_ConvNd.from_float(cls,mod,use_precomputed_fake_quant=use_precomputed_fake_quant)
# === Transposed Convolutions ===class_ConvTransposeNd(_ConvNd):_FLOAT_MODULE:ClassVar[Type[nn.modules.conv._ConvNd]]def__init__(self,in_channels,out_channels,kernel_size,stride,padding,dilation,transposed,output_padding,groups,bias,padding_mode,device=None,dtype=None,):ifpadding_mode!="zeros":raiseValueError(f'Only "zeros" padding mode is supported for {self.__class__.__name__}')factory_kwargs={"device":device,"dtype":dtype}# Subclasses of _ConvNd need to call _init rather than __init__. See# discussion on PR #49702super()._init(in_channels,out_channels,kernel_size,stride,padding,dilation,transposed,output_padding,groups,bias,padding_mode,**factory_kwargs,)def_input_padding(self,kernel_size:List[int],dilation:List[int],padding:List[int])->List[int]:res=torch.jit.annotate(List[int],[])forkdxinrange(len(kernel_size)):pad=dilation[kdx]*(kernel_size[kdx]-1)-padding[kdx]res.append(pad)returnres@classmethoddeffrom_float(cls,mod,use_precomputed_fake_quant=False):r"""Creates a quantized module from a float module or qparams_dict. Args: mod (Module): a float module, either produced by torch.ao.quantization utilities or provided by the user """# derived classes override cls._FLOAT_MODULE attributemsg=(" nnq."+cls.__name__+".from_float only works for "+cls._FLOAT_MODULE.__name__# type: ignore[attr-defined])asserttype(mod)==cls._FLOAT_MODULE,msgasserthasattr(mod,"qconfig"),"Input float module must have qconfig defined."weight_post_process=mod.qconfig.weight()# type: ignore[operator, union-attr]weight_post_process(mod.weight)assert(weight_post_process.dtype==torch.qint8),"Weight observer must have a dtype of qint8"qweight=_quantize_weight(mod.weight.float(),weight_post_process)# the __init__ call used is the one from derived classes and not the one from _ConvTransposeNdqconv=cls(mod.in_channels,mod.out_channels,mod.kernel_size,# type: ignore[call-arg]mod.stride,mod.padding,mod.output_padding,mod.groups,mod.biasisnotNone,mod.dilation,mod.padding_mode,)qconv.set_weight_bias(qweight,mod.bias)if(nothasattr(mod,"activation_post_process")ormod.activation_post_process.dtype==torch.float):returnqconv# dynamic quantization doesn't need scale/zero_pointelse:act_scale,act_zp=mod.activation_post_process.calculate_qparams()# type: ignore[operator, union-attr]qconv.scale=float(act_scale)qconv.zero_point=int(act_zp)returnqconv@staticmethoddeffrom_reference(cls,ref_qconvt,output_scale,output_zero_point):r"""Create a (fbgemm/qnnpack) quantized module from a reference quantized module Args: ref_qconvt (Module): a reference quantized module, either produced by torch.ao.quantization utilities or provided by the user output_scale (float): scale for output Tensor output_zero_point (int): zero point for output Tensor """qconv=cls(ref_qconvt.in_channels,ref_qconvt.out_channels,ref_qconvt.kernel_size,# type: ignore[arg-type]ref_qconvt.stride,# type: ignore[arg-type]ref_qconvt.padding,# type: ignore[arg-type]ref_qconvt.output_padding,# type: ignore[arg-type]ref_qconvt.groups,ref_qconvt.biasisnotNone,# type: ignore[arg-type]ref_qconvt.dilation,# type: ignore[arg-type]ref_qconvt.padding_mode,device=ref_qconvt.weight.device,dtype=ref_qconvt.weight.dtype,)qweight=ref_qconvt.get_quantized_weight()qconv.set_weight_bias(qweight,ref_qconvt.bias)qconv.scale=float(output_scale)qconv.zero_point=int(output_zero_point)returnqconv
[docs]classConvTranspose1d(_ConvTransposeNd):r"""Applies a 1D transposed convolution operator over an input image composed of several input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.ConvTranspose1d`. .. note:: Currently only the QNNPACK engine is implemented. Please, set the `torch.backends.quantized.engine = 'qnnpack'` For special notes, please, see :class:`~torch.ao.nn.quantized.Conv1d` Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.ConvTranspose2d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> torch.backends.quantized.engine = 'qnnpack' >>> from torch.ao.nn import quantized as nnq >>> # With square kernels and equal stride >>> m = nnq.ConvTranspose1d(16, 33, 3, stride=2) >>> # non-square kernels and unequal stride and with padding >>> m = nnq.ConvTranspose1d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2)) >>> input = torch.randn(20, 16, 50) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> output = m(q_input) >>> # exact output size can be also specified as an argument >>> input = torch.randn(1, 16, 12) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> downsample = nnq.Conv1d(16, 16, 3, stride=2, padding=1) >>> upsample = nnq.ConvTranspose1d(16, 16, 3, stride=2, padding=1) >>> h = downsample(q_input) >>> h.size() torch.Size([1, 16, 6]) >>> # xdoctest: +SKIP("FIXME: output_size is not a parameter) >>> output = upsample(h, output_size=input.size()) >>> output.size() torch.Size([1, 16, 12]) """_FLOAT_MODULE:ClassVar[Type[nn.ConvTranspose1d]]=nn.ConvTranspose1ddef__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,output_padding=0,groups=1,bias=True,dilation=1,padding_mode="zeros",device=None,dtype=None,):factory_kwargs={"device":device,"dtype":dtype}kernel_size=_single(kernel_size)stride=_single(stride)padding=_single(padding)dilation=_single(dilation)output_padding=_single(output_padding)super().__init__(in_channels,out_channels,kernel_size,stride,padding,dilation,True,output_padding,groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConvTranspose1d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:self._packed_params=torch.ops.quantized.conv_transpose1d_prepack(w,b,self.stride,self.padding,self.output_padding,self.dilation,self.groups,)def_weight_bias(self):w,b=torch.ops.quantized.conv_transpose1d_unpack(self._packed_params)returnw,bdefweight(self):(w,_)=self._weight_bias()returnwdefbias(self):(_,b)=self._weight_bias()returnbdefforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=3:raiseValueError("Input shape must be `(N, C, L)`!")returntorch.ops.quantized.conv_transpose1d(input,self._packed_params,self.scale,self.zero_point)@classmethoddeffrom_reference(cls,ref_qconvt,output_scale,output_zero_point):return_ConvTransposeNd.from_reference(cls,ref_qconvt,output_scale,output_zero_point)
[docs]classConvTranspose2d(_ConvTransposeNd):r"""Applies a 2D transposed convolution operator over an input image composed of several input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.ConvTranspose2d`. For special notes, please, see :class:`~torch.ao.nn.quantized.Conv2d` Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.ConvTranspose2d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> # QNNPACK or FBGEMM as backend >>> torch.backends.quantized.engine = 'qnnpack' >>> # With square kernels and equal stride >>> import torch.ao.nn.quantized as nnq >>> m = nnq.ConvTranspose2d(16, 33, 3, stride=2) >>> # non-square kernels and unequal stride and with padding >>> m = nnq.ConvTranspose2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2)) >>> input = torch.randn(20, 16, 50, 100) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> output = m(q_input) >>> # exact output size can be also specified as an argument >>> input = torch.randn(1, 16, 12, 12) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> downsample = nnq.Conv2d(16, 16, 3, stride=2, padding=1) >>> upsample = nnq.ConvTranspose2d(16, 16, 3, stride=2, padding=1) >>> h = downsample(q_input) >>> h.size() torch.Size([1, 16, 6, 6]) >>> # xdoctest: +SKIP("FIXME: output_size is not a parameter) >>> output = upsample(h, output_size=input.size()) >>> output.size() torch.Size([1, 16, 12, 12]) """_FLOAT_MODULE:ClassVar[Type[nn.ConvTranspose2d]]=nn.ConvTranspose2ddef__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,output_padding=0,groups=1,bias=True,dilation=1,padding_mode="zeros",device=None,dtype=None,):factory_kwargs={"device":device,"dtype":dtype}kernel_size=_pair(kernel_size)stride=_pair(stride)padding=_pair(padding)dilation=_pair(dilation)output_padding=_pair(output_padding)super().__init__(in_channels,out_channels,kernel_size,stride,padding,dilation,True,output_padding,groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConvTranspose2d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:self._packed_params=torch.ops.quantized.conv_transpose2d_prepack(w,b,self.stride,self.padding,self.output_padding,self.dilation,self.groups,)def_weight_bias(self):w,b=torch.ops.quantized.conv2d_unpack(self._packed_params)returnw,bdefweight(self):(w,_)=self._weight_bias()returnwdefbias(self):(_,b)=self._weight_bias()returnbdefforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=4:raiseValueError("Input shape must be `(N, C, H, W)`!")returnops.quantized.conv_transpose2d(input,self._packed_params,self.scale,self.zero_point)@classmethoddeffrom_reference(cls,ref_qconvt,output_scale,output_zero_point):return_ConvTransposeNd.from_reference(cls,ref_qconvt,output_scale,output_zero_point)
[docs]classConvTranspose3d(_ConvTransposeNd):r"""Applies a 3D transposed convolution operator over an input image composed of several input planes. For details on input arguments, parameters, and implementation see :class:`~torch.nn.ConvTranspose3d`. .. note:: Currently only the FBGEMM engine is implemented. Please, set the `torch.backends.quantized.engine = 'fbgemm'` For special notes, please, see :class:`~torch.ao.nn.quantized.Conv3d` Attributes: weight (Tensor): packed tensor derived from the learnable weight parameter. scale (Tensor): scalar for the output scale zero_point (Tensor): scalar for the output zero point See :class:`~torch.nn.ConvTranspose3d` for other attributes. Examples:: >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE) >>> torch.backends.quantized.engine = 'fbgemm' >>> from torch.ao.nn import quantized as nnq >>> # With cubic kernels and equal stride >>> m = nnq.ConvTranspose3d(16, 33, 3, stride=2) >>> # non-cubic kernels and unequal stride and with padding >>> m = nnq.ConvTranspose3d(16, 33, (3, 3, 5), stride=(2, 1, 1), padding=(4, 2, 2)) >>> input = torch.randn(20, 16, 50, 100, 100) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> output = m(q_input) >>> # exact output size can be also specified as an argument >>> input = torch.randn(1, 16, 12, 12, 12) >>> q_input = torch.quantize_per_tensor(input, scale=1.0, zero_point=0, dtype=torch.quint8) >>> downsample = nnq.Conv3d(16, 16, 3, stride=2, padding=1) >>> upsample = nnq.ConvTranspose3d(16, 16, 3, stride=2, padding=1) >>> h = downsample(q_input) >>> h.size() torch.Size([1, 16, 6, 6, 6]) >>> # xdoctest: +SKIP("FIXME: output_size is not a parameter) >>> output = upsample(h, output_size=input.size()) >>> output.size() torch.Size([1, 16, 12, 12, 12]) """_FLOAT_MODULE:ClassVar[Type[nn.ConvTranspose3d]]=nn.ConvTranspose3ddef__init__(self,in_channels,out_channels,kernel_size,stride=1,padding=0,output_padding=0,groups=1,bias=True,dilation=1,padding_mode="zeros",device=None,dtype=None,):factory_kwargs={"device":device,"dtype":dtype}kernel_size=_triple(kernel_size)stride=_triple(stride)padding=_triple(padding)dilation=_triple(dilation)output_padding=_triple(output_padding)super().__init__(in_channels,out_channels,kernel_size,stride,padding,dilation,True,output_padding,groups,bias,padding_mode,**factory_kwargs,)def_get_name(self):return"QuantizedConvTranspose3d"defset_weight_bias(self,w:torch.Tensor,b:Optional[torch.Tensor])->None:self._packed_params=torch.ops.quantized.conv_transpose3d_prepack(w,b,self.stride,self.padding,self.output_padding,self.dilation,self.groups,)def_weight_bias(self):w,b=torch.ops.quantized.conv3d_unpack(self._packed_params)returnw,bdefweight(self):(w,_)=self._weight_bias()returnwdefbias(self):(_,b)=self._weight_bias()returnbdefforward(self,input):# Temporarily using len(shape) instead of ndim due to JIT issue# https://github.com/pytorch/pytorch/issues/23890iflen(input.shape)!=5:raiseValueError("Input shape must be `(N, C, T, H, W)`!")returnops.quantized.conv_transpose3d(input,self._packed_params,self.scale,self.zero_point)@classmethoddeffrom_reference(cls,ref_qconvt,output_scale,output_zero_point):return_ConvTransposeNd.from_reference(cls,ref_qconvt,output_scale,output_zero_point)
Docs
Access comprehensive developer documentation for PyTorch
To analyze traffic and optimize your experience, we serve cookies on this site. By clicking or navigating, you agree to allow our usage of cookies. As the current maintainers of this site, Facebook’s Cookies Policy applies. Learn more, including about available controls: Cookies Policy.