@@ -81,6 +81,27 @@ def __init__(self):
8181 self .quant_output : Optional [_QuantProperty ] = None
8282
8383
84+ def _conv_linear_quant_inputs (
85+ input_act_qspec : QuantizationSpecBase | None ,
86+ weight_qspec : QuantizationSpecBase | None ,
87+ bias_qspec : QuantizationSpecBase | None ,
88+ ) -> List [_QuantProperty ]:
89+ """Build conv/linear input quant properties, tolerating partial quant.
90+
91+ Activation-only PTQ recipes leave ``weight_qspec`` (and the bias derived
92+ from it) None; omit those QuantProperties so weight/bias stay fp32 instead of
93+ asserting a non-None weight spec. Weight-only and full configs keep the
94+ weight (and bias) quantized exactly as before.
95+ """
96+ quant_inputs : List [_QuantProperty ] = [_QuantProperty (0 , input_act_qspec )]
97+ if weight_qspec is not None :
98+ quant_inputs .append (_QuantProperty (1 , weight_qspec , mark_annotated = True ))
99+ quant_inputs .append (
100+ _QuantProperty (2 , bias_qspec , optional = True , mark_annotated = True )
101+ )
102+ return quant_inputs
103+
104+
84105class _QParams (NamedTuple ):
85106 scale : float
86107 zero_point : int
@@ -716,12 +737,9 @@ def any_or_hardtanh_min_zero(n: Node):
716737 filter_fn = any_or_hardtanh_min_zero ,
717738 ):
718739 if node .target in _conv_ops :
719- conv_weight_qspec = ensure_type (QuantizationSpec , weight_qspec ) # For MyPy
720- quant_properties .quant_inputs = [
721- _QuantProperty (0 , input_act_qspec ),
722- _QuantProperty (1 , conv_weight_qspec , mark_annotated = True ),
723- _QuantProperty (2 , bias_qspec , optional = True , mark_annotated = True ),
724- ]
740+ quant_properties .quant_inputs = _conv_linear_quant_inputs (
741+ input_act_qspec , weight_qspec , bias_qspec
742+ )
725743 elif node .target in (
726744 torch .ops .aten .relu .default ,
727745 torch .ops .aten .relu_ .default ,
@@ -738,12 +756,9 @@ def any_or_hardtanh_min_zero(n: Node):
738756 ],
739757 ):
740758 if node .target in _conv_ops :
741- conv_weight_qspec = ensure_type (QuantizationSpec , weight_qspec ) # For MyPy
742- quant_properties .quant_inputs = [
743- _QuantProperty (0 , input_act_qspec ),
744- _QuantProperty (1 , conv_weight_qspec , mark_annotated = True ),
745- _QuantProperty (2 , bias_qspec , optional = True , mark_annotated = True ),
746- ]
759+ quant_properties .quant_inputs = _conv_linear_quant_inputs (
760+ input_act_qspec , weight_qspec , bias_qspec
761+ )
747762 elif node .target in {torch .ops .aten .batch_norm .default }:
748763 quant_properties .quant_output = _QuantProperty (0 , output_act_qspec )
749764 elif not is_symmetric and _match_pattern (
@@ -766,28 +781,18 @@ def any_or_hardtanh_min_zero(n: Node):
766781 * _conv_ops ,
767782 torch .ops .aten .linear .default ,
768783 ):
769- conv_or_linear_weight_qspec = ensure_type (
770- QuantizationSpec , weight_qspec
771- ) # For MyPy
772- quant_properties .quant_inputs = [
773- _QuantProperty (0 , input_act_qspec ),
774- _QuantProperty (1 , conv_or_linear_weight_qspec , mark_annotated = True ),
775- _QuantProperty (2 , bias_qspec , optional = True , mark_annotated = True ),
776- ]
784+ quant_properties .quant_inputs = _conv_linear_quant_inputs (
785+ input_act_qspec , weight_qspec , bias_qspec
786+ )
777787 else :
778788 quant_properties .quant_output = _QuantProperty (0 , output_act_qspec )
779789 elif node .target in (
780790 * _conv_ops ,
781791 torch .ops .aten .linear .default ,
782792 ):
783- conv_or_linear_weight_qspec = ensure_type (
784- QuantizationSpec , weight_qspec
785- ) # For MyPy
786- quant_properties .quant_inputs = [
787- _QuantProperty (0 , input_act_qspec ),
788- _QuantProperty (1 , conv_or_linear_weight_qspec , mark_annotated = True ),
789- _QuantProperty (2 , bias_qspec , optional = True , mark_annotated = True ),
790- ]
793+ quant_properties .quant_inputs = _conv_linear_quant_inputs (
794+ input_act_qspec , weight_qspec , bias_qspec
795+ )
791796 quant_properties .quant_output = _QuantProperty (0 , output_act_qspec )
792797 elif node .target in (
793798 torch .ops .aten .add .Tensor ,
0 commit comments