Skip to content

Commit 6663f7b

Browse files
Support Conv2D biasadd sigmoid fusion (#1133)
1 parent 8b664b6 commit 6663f7b

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

neural_compressor/adaptor/inteltensorflow.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@
212212
'Dequantize + Conv2D + Relu6 + QuantizeV2',
213213
'Dequantize + Conv2D + BiasAdd + LeakyRelu + QuantizeV2',
214214
'Dequantize + Conv2D + LeakyRelu + QuantizeV2',
215+
'Dequantize + Conv2D + BiasAdd + Sigmoid + QuantizeV2',
216+
'Dequantize + Conv2D + Sigmoid + QuantizeV2',
215217
'Dequantize + Conv2D + BiasAdd + LeakyRelu + AddV2 + QuantizeV2',
216218
'Dequantize + Conv2D + LeakyRelu + AddV2 + QuantizeV2',
217219
'Dequantize + Conv2D + Add + QuantizeV2',

neural_compressor/adaptor/tf_utils/graph_rewriter/int8/fuse_conv_requantize.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,16 @@ def do_transformation(self):
285285
dtype_map_dict[requantize_node.attr['out_type'].type])
286286
Helper.set_attr_dtype(new_node, "Tsummand", \
287287
dtype_map_dict[requantize_node.attr['out_type'].type])
288+
elif str(quantized_node.attr['fused_ops'].list.s) == str([b"BiasAdd", b"Sigmoid"]):
289+
self.fused_ops= [b"BiasAdd", b"Sigmoid", b"Requantize"]
290+
Helper.set_attr_type_list(new_node, 'Thost_outputs', [
291+
requantize_node.attr['out_type'].type,
292+
dtypes.float32.as_datatype_enum,
293+
dtypes.float32.as_datatype_enum ])
294+
Helper.set_attr_dtype(new_node, "out_type", \
295+
dtype_map_dict[requantize_node.attr['out_type'].type])
296+
Helper.set_attr_dtype(new_node, "Tsummand", \
297+
dtype_map_dict[requantize_node.attr['out_type'].type])
288298
elif str(quantized_node.attr['fused_ops'].list.s) == str([b"BiasAdd"]):
289299
self.fused_ops= [b"BiasAdd", b"Requantize"]
290300
Helper.set_attr_type_list(new_node, 'Thost_outputs', [

neural_compressor/adaptor/tf_utils/quantize_graph/qdq/fuse_qdq_conv.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ def __init__(self, **kwargs):
5252
'DequantizeConv2DEluQuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
5353
'DequantizeConv2DBiasAddLeakyReluQuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
5454
'DequantizeConv2DLeakyReluQuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
55+
'DequantizeConv2DBiasAddSigmoidQuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
56+
'DequantizeConv2DSigmoidQuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
5557
'DequantizeConv2DBiasAddLeakyReluAddV2QuantizeV2': self.apply_newly_conv_biasadd_addn_relu_fusion,
5658
'DequantizeConv2DLeakyReluAddV2QuantizeV2': self.apply_newly_conv_biasadd_addn_relu_fusion,
5759
'DequantizeConv2DAddRelu6QuantizeV2': self.apply_newly_conv_biasadd_relu_fusion,
@@ -813,6 +815,8 @@ def apply_newly_conv_biasadd_relu_fusion(self, match_node_name):
813815
# Dequantize + Conv2D + Elu + QuantizeV2
814816
# Dequantize + Conv2D + BiasAdd + LeakyRelu + QuantizeV2
815817
# Dequantize + Conv2D + LeakyRelu + QuantizeV2
818+
# Dequantize + Conv2D + BiasAdd + Sigmoid + QuantizeV2
819+
# Dequantize + Conv2D + Sigmoid + QuantizeV2
816820
# Dequantize + Conv2D + Add + Relu6 + QuantizeV2
817821
# Dequantize + Conv2D + Add + Relu + QuantizeV2
818822
# Dequantize + DepthwiseConv2dNative + Add + Relu6 + QuantizeV2
@@ -826,7 +830,7 @@ def apply_newly_conv_biasadd_relu_fusion(self, match_node_name):
826830
matched_node = self.node_name_mapping[match_node_name[1]]
827831

828832
second_node = self.node_name_mapping[match_node_name[2]].node
829-
if second_node.op in ('Relu', 'Relu6', 'LeakyRelu', 'Elu'):
833+
if second_node.op in ('Relu', 'Relu6', 'LeakyRelu', 'Elu', 'Sigmoid'):
830834
new_match_node_name = self._insert_dummy_biasadd(match_node_name, matched_node)
831835
return self.apply_newly_conv_biasadd_relu_fusion(new_match_node_name)
832836

@@ -882,6 +886,7 @@ def apply_newly_conv_biasadd_relu_fusion(self, match_node_name):
882886
[bias_node_name] + all_input_names[2:] + control_inputs
883887
is_leakyrelu = self.node_name_mapping[relu_node_name].node.op == "LeakyRelu"
884888
is_elu = self.node_name_mapping[relu_node_name].node.op == "Elu"
889+
is_sigmoid = self.node_name_mapping[relu_node_name].node.op == "Sigmoid"
885890

886891
node_op = '_QuantizedDepthwiseConv2D'
887892
if node.op == 'Conv2D':
@@ -911,7 +916,9 @@ def apply_newly_conv_biasadd_relu_fusion(self, match_node_name):
911916
if is_leakyrelu:
912917
fused_ops = [b'BiasAdd', b'LeakyRelu']
913918
if is_elu:
914-
fused_ops = [b'BiasAdd', b'Elu']
919+
fused_ops = [b'BiasAdd', b'Elu']
920+
if is_sigmoid:
921+
fused_ops = [b'BiasAdd', b'Sigmoid']
915922
helper.set_attr_string_list(quantized_conv_node, 'fused_ops', fused_ops)
916923
helper.set_attr_type_list(quantized_conv_node, 'Thost_inputs', [
917924
input_data_type.as_datatype_enum,

test/tfnewapi/test_tensorflow_graph_qdq_conv_fusion.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,38 @@ def test_conv_biasadd_elu_fusion(self):
853853
break
854854
self.assertEqual(found_conv_fusion, True)
855855

856+
# fuse conv + biasadd + sigmoid
857+
@disable_random()
858+
def test_conv_biasadd_sigmoid_fusion(self):
859+
x = tf.compat.v1.placeholder(tf.float32, [1, 56, 56, 16], name="input")
860+
conv_weights = tf.compat.v1.get_variable("weight", [3, 3, 16, 16],
861+
initializer=tf.compat.v1.random_normal_initializer())
862+
conv = tf.nn.conv2d(x, conv_weights, strides=[1, 2, 2, 1], padding="VALID")
863+
normed = tf.compat.v1.layers.batch_normalization(conv)
864+
865+
sigmoid = tf.math.sigmoid(normed, name='op_to_store')
866+
867+
out_name = sigmoid.name.split(':')[0]
868+
with tf.compat.v1.Session() as sess:
869+
sess.run(tf.compat.v1.global_variables_initializer())
870+
output_graph_def = graph_util.convert_variables_to_constants(
871+
sess=sess,
872+
input_graph_def=sess.graph_def,
873+
output_node_names=[out_name])
874+
from neural_compressor.experimental import Quantization, common
875+
quantizer = Quantization('fake_yaml.yaml')
876+
dataset = quantizer.dataset('dummy', shape=(100, 56, 56, 16), label=True)
877+
quantizer.eval_dataloader = common.DataLoader(dataset)
878+
quantizer.calib_dataloader = common.DataLoader(dataset)
879+
quantizer.model = output_graph_def
880+
output_graph = quantizer.fit()
881+
found_conv_fusion = True
882+
883+
for i in output_graph.graph_def.node:
884+
if i.op == 'Sigmoid':
885+
found_conv_fusion = False
886+
break
887+
self.assertEqual(found_conv_fusion, True)
856888

857889
if __name__ == '__main__':
858890
unittest.main()

0 commit comments

Comments
 (0)