mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-25 19:48:11 +00:00
Cjian/pad ops bug (#13930)
This commit is contained in:
parent
fe827c3891
commit
b8d941f065
2 changed files with 83 additions and 14 deletions
|
|
@ -70,8 +70,8 @@ class QPad(QuantOperatorBase):
|
|||
quantized_input_value.scale_name,
|
||||
quantized_input_value.zp_name,
|
||||
)
|
||||
self.quantizer.new_nodes += [pad_value_qnodes]
|
||||
node.input[2] = pad_value_qnodes.output[0]
|
||||
self.quantizer.new_nodes.extend(pad_value_qnodes)
|
||||
node.input[2] = pad_value_qnodes[0].output[0]
|
||||
else:
|
||||
node.input.extend([quantized_input_value.zp_name]) # pad zero_point for original zero
|
||||
|
||||
|
|
|
|||
|
|
@ -187,22 +187,37 @@ class TestOpQuatizerPad(unittest.TestCase):
|
|||
atol=0.05,
|
||||
activation_type=QuantType.QUInt8,
|
||||
weight_type=QuantType.QUInt8,
|
||||
extra_options={},
|
||||
extra_options=None,
|
||||
):
|
||||
if extra_options is None:
|
||||
extra_options = {}
|
||||
np.random.seed(108)
|
||||
tag_pad_mode = pad_mode if pad_mode is not None else "none"
|
||||
tag_constant_value = "" if constant_value is None else "_value"
|
||||
model_fp32_path = "qop_pad_{}_fp32_{}{}.onnx".format(quantize_mode, tag_pad_mode, tag_constant_value)
|
||||
data_reader = self.input_feeds(1, {"input": [1, 8, 33, 33]})
|
||||
self.construct_model_conv_pad(
|
||||
model_fp32_path,
|
||||
[1, 8, 33, 33],
|
||||
[16, 8, 3, 3],
|
||||
[1, 16, 31, 31],
|
||||
pad_mode,
|
||||
[0, 0, 1, 2, 0, 0, 3, 4],
|
||||
constant_value=constant_value,
|
||||
)
|
||||
edge_case = "dual_feed" in extra_options and extra_options["dual_feed"] and constant_value is not None
|
||||
if edge_case:
|
||||
data_reader = self.input_feeds(1, {"input": [1, 8, 33, 33], "padding_value": [1]})
|
||||
self.construct_edge_case_model(
|
||||
model_fp32_path,
|
||||
[1, 8, 33, 33],
|
||||
[16, 8, 3, 3],
|
||||
[1, 16, 31, 31],
|
||||
pad_mode,
|
||||
[0, 0, 1, 2, 0, 0, 3, 4],
|
||||
constant_value=constant_value,
|
||||
)
|
||||
else:
|
||||
data_reader = self.input_feeds(1, {"input": [1, 8, 33, 33]})
|
||||
self.construct_model_conv_pad(
|
||||
model_fp32_path,
|
||||
[1, 8, 33, 33],
|
||||
[16, 8, 3, 3],
|
||||
[1, 16, 31, 31],
|
||||
pad_mode,
|
||||
[0, 0, 1, 2, 0, 0, 3, 4],
|
||||
constant_value=constant_value,
|
||||
)
|
||||
|
||||
activation_proto_qtype = TensorProto.UINT8 if activation_type == QuantType.QUInt8 else TensorProto.INT8
|
||||
activation_type_str = "u8" if (activation_type == QuantType.QUInt8) else "s8"
|
||||
|
|
@ -229,7 +244,8 @@ class TestOpQuatizerPad(unittest.TestCase):
|
|||
if quantize_mode != "static":
|
||||
kwargs = {"DynamicQuantizeLinear": 1} if activation_type == QuantType.QUInt8 else {"QuantizeLinear": 1}
|
||||
else:
|
||||
kwargs = {"DequantizeLinear": 2, "QuantizeLinear": 1}
|
||||
# edge case will have 2 graph inputs
|
||||
kwargs = {"DequantizeLinear": 2, "QuantizeLinear": 2 if edge_case else 1}
|
||||
check_op_type_count(self, model_i8_path, **kwargs)
|
||||
# check node input/output type if such node exists in the graph
|
||||
qnode_io_qtypes = {
|
||||
|
|
@ -335,6 +351,59 @@ class TestOpQuatizerPad(unittest.TestCase):
|
|||
# def test_dynamic_mode_constant_value_s8s8(self):
|
||||
# self.verify_quantize_with_pad_mode('constant', constant_value=3.75, quantize_mode='dynamic', activation_type=QuantType.QInt8,
|
||||
# weight_type=QuantType.QInt8, extra_options={'ActivationSymmetric': True})
|
||||
def construct_edge_case_model(
|
||||
self,
|
||||
output_model_path,
|
||||
conv_input_shape,
|
||||
conv_weight_shape,
|
||||
pad_input_shape,
|
||||
pad_mode,
|
||||
pad_dims,
|
||||
constant_value=None,
|
||||
):
|
||||
# (input)
|
||||
# \
|
||||
# Conv (padding_value)
|
||||
# / \ /
|
||||
# Identity Pad
|
||||
# / \
|
||||
# (identity_out) (output)
|
||||
rank = len(pad_input_shape)
|
||||
self.assertEqual(rank * 2, len(pad_dims))
|
||||
|
||||
input_tensor = helper.make_tensor_value_info("input", TensorProto.FLOAT, conv_input_shape)
|
||||
conv_weight_arr = np.random.randint(-1, 2, conv_weight_shape).astype(np.float32)
|
||||
conv_weight_initializer = onnx.numpy_helper.from_array(conv_weight_arr, name="conv1_weight")
|
||||
conv_node = onnx.helper.make_node("Conv", ["input", "conv1_weight"], ["conv_output"], name="conv_node")
|
||||
|
||||
identity_out = helper.make_tensor_value_info("identity_out", TensorProto.FLOAT, pad_input_shape)
|
||||
identity_node = helper.make_node("Identity", ["conv_output"], ["identity_out"], name="IdentityNode")
|
||||
|
||||
pad_dims_initializer = helper.make_tensor("pad_dims", TensorProto.INT64, [2 * rank], pad_dims)
|
||||
output_shape = [sum(e) for e in list(zip(pad_input_shape, pad_dims[:rank], pad_dims[rank:]))]
|
||||
output_tensor = helper.make_tensor_value_info("output", TensorProto.FLOAT, output_shape)
|
||||
pad_inputs = ["conv_output", "pad_dims"]
|
||||
initializers = [conv_weight_initializer, pad_dims_initializer]
|
||||
constant_value_tensor = helper.make_tensor_value_info("padding_value", TensorProto.FLOAT, [1])
|
||||
pad_inputs.extend(["padding_value"])
|
||||
kwargs = {"mode": pad_mode} if pad_mode is not None else {}
|
||||
pad_node = helper.make_node("Pad", pad_inputs, ["output"], name="pad_node", **kwargs)
|
||||
|
||||
graph = helper.make_graph(
|
||||
[conv_node, identity_node, pad_node],
|
||||
"TestOpQuantizerPad_test_model",
|
||||
[input_tensor, constant_value_tensor],
|
||||
[identity_out, output_tensor],
|
||||
initializer=initializers,
|
||||
)
|
||||
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
|
||||
model.ir_version = 7 # use stable onnx ir version
|
||||
onnx.save(model, output_model_path)
|
||||
|
||||
def test_static_mode_constant_value_edge_case(self):
|
||||
self.verify_quantize_with_pad_mode(
|
||||
"constant", constant_value=0.1, quantize_mode="static", extra_options={"dual_feed": True}
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Reference in a new issue