Fix MarkDequantizationSubgraph when Mul has Convert on both inputs (#14997)

Ticket: 100042
This commit is contained in:
Mateusz Tabaka authored and GitHub committed 2023-01-26 08:55:23 +00:00
1 parent c0f524e3bd
commit 3ad92084d6
4 files changed
+153 -27

No files matched your search

@@ -4,7 +4,9 @@
#include <openvino/opsets/opset10.hpp>
#include <openvino/pass/constant_folding.hpp>
#include <transformations/disable_decompression_convert_constant_folding.hpp>
#include <transformations/low_precision/mark_dequantization_subgraph.hpp>
#include <transformations/rt_info/decompression.hpp>
#include <transformations/rt_info/dequantization_node.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
@@ -78,8 +80,8 @@ TEST_F(TransformationTestsF, MarkDequantizationSubgraphTransformation) {
function = std::make_shared<Model>(conv, ParameterVector{parameter});
}
manager.register_pass<ov::pass::MarkDequantizationSubgraph>();
manager.register_pass<ov::pass::ConstantFolding>();
manager.register_pass<pass::MarkDequantizationSubgraph>(element::TypeVector{element::u8, element::i8});
manager.register_pass<pass::ConstantFolding>();
{
auto parameter = std::make_shared<opset10::Parameter>(element::f32, Shape{1, 16, 14, 14});
@@ -95,27 +97,27 @@ TEST_F(TransformationTestsF, MarkDequantizationSubgraphTransformation) {
auto second_convert = std::make_shared<opset10::Convert>(first_convert, element::f32);
auto zero_point = opset10::Constant::create(element::u8, Shape{}, {127});
auto convert_on_zero_point = std::make_shared<opset10::Convert>(zero_point, element::f32);
ov::pass::disable_constant_folding(convert_on_zero_point);
pass::disable_constant_folding(convert_on_zero_point);
auto subtract = std::make_shared<opset10::Subtract>(second_convert, convert_on_zero_point);
ov::mark_as_dequantization_node(subtract);
mark_as_dequantization_node(subtract);
auto scale = opset10::Constant::create(element::f32, Shape{}, {0.2});
auto multiply = std::make_shared<opset10::Multiply>(subtract, scale);
ov::mark_as_dequantization_node(multiply);
mark_as_dequantization_node(multiply);
activations = multiply;
}
std::shared_ptr<Node> weights = opset10::Constant::create(element::i8, Shape{4, 16, 1, 1}, {-2});
{
auto convert = std::make_shared<opset10::Convert>(weights, element::f32);
ov::pass::disable_constant_folding(convert);
pass::disable_constant_folding(convert);
auto zero_point = opset10::Constant::create(element::i8, Shape{}, {127});
auto convert_on_zero_point = std::make_shared<opset10::Convert>(zero_point, element::f32);
ov::pass::disable_constant_folding(convert_on_zero_point);
pass::disable_constant_folding(convert_on_zero_point);
auto subtract = std::make_shared<opset10::Subtract>(convert, convert_on_zero_point);
ov::mark_as_dequantization_node(subtract);
mark_as_dequantization_node(subtract);
auto scale = opset10::Constant::create(element::f32, Shape{}, {0.2});
auto multiply = std::make_shared<opset10::Multiply>(subtract, scale);
ov::mark_as_dequantization_node(multiply);
mark_as_dequantization_node(multiply);
weights = multiply;
}
@@ -190,8 +192,8 @@ TEST_F(TransformationTestsF, MarkDequantizationSubgraphTransformationNoZeroPoint
function = std::make_shared<Model>(conv, ParameterVector{parameter});
}
manager.register_pass<ov::pass::MarkDequantizationSubgraph>();
manager.register_pass<ov::pass::ConstantFolding>();
manager.register_pass<pass::MarkDequantizationSubgraph>(element::TypeVector{element::u8, element::i8});
manager.register_pass<pass::ConstantFolding>();
{
auto parameter = std::make_shared<opset10::Parameter>(element::f32, Shape{1, 16, 14, 14});
@@ -207,17 +209,128 @@ TEST_F(TransformationTestsF, MarkDequantizationSubgraphTransformationNoZeroPoint
auto second_convert = std::make_shared<opset10::Convert>(first_convert, element::f32);
auto scale = opset10::Constant::create(element::f32, Shape{}, {0.2});
auto multiply = std::make_shared<opset10::Multiply>(second_convert, scale);
ov::mark_as_dequantization_node(multiply);
mark_as_dequantization_node(multiply);
activations = multiply;
}
std::shared_ptr<Node> weights = opset10::Constant::create(element::i8, Shape{4, 16, 1, 1}, {-2});
{
auto convert = std::make_shared<opset10::Convert>(weights, element::f32);
ov::pass::disable_constant_folding(convert);
pass::disable_constant_folding(convert);
auto scale = opset10::Constant::create(element::f32, Shape{}, {0.2});
auto multiply = std::make_shared<opset10::Multiply>(convert, scale);
ov::mark_as_dequantization_node(multiply);
mark_as_dequantization_node(multiply);
weights = multiply;
}
auto conv = std::make_shared<opset10::Convolution>(activations,
weights,
Strides{1, 1},
CoordinateDiff{0, 0},
CoordinateDiff{0, 0},
Strides{1, 1});
function_ref = std::make_shared<Model>(conv, ParameterVector{parameter});
}
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
comparator.enable(FunctionsComparator::CmpValues::RUNTIME_KEYS);
}
TEST_F(TransformationTestsF, MarkDequantizationSubgraphTransformationNoZeroPointFP16) {
// Input graph:
//
// Parameter
// |F32
// |
// FakeQuantize
// |F32
// |
// Convert Constant Constant Constant
// |U8 |FP16 |I8 /FP16
// | | | /
// Convert Convert Convert(DCF) Convert
// \FP32 /FP32 \FP32 /F32
// \ / \ /
// Multiply Multiply
// \FP32 /FP32
// \ /
// Convolution
//
// After MarkDequantizationSubgraph all Multiply nodes from above graph
// are marked with 'DequantizationNode' attribute.
// Also 'Convert(DCF)' node from above graph is marked with 'DisableConstantFolding' attribute
{
auto parameter = std::make_shared<opset10::Parameter>(element::f32, Shape{1, 16, 14, 14});
std::shared_ptr<Node> activations =
std::make_shared<opset10::FakeQuantize>(parameter,
opset10::Constant::create(element::f32, Shape{}, {0}),
opset10::Constant::create(element::f32, Shape{}, {20}),
opset10::Constant::create(element::f32, Shape{}, {0}),
opset10::Constant::create(element::f32, Shape{}, {254}),
255);
{
auto first_convert = std::make_shared<opset10::Convert>(activations, element::u8);
auto second_convert = std::make_shared<opset10::Convert>(first_convert, element::f32);
auto scale = opset10::Constant::create(element::f16, Shape{}, {0.2});
auto scale_convert = std::make_shared<opset10::Convert>(scale, element::f32);
mark_as_decompression(scale_convert);
auto multiply = std::make_shared<opset10::Multiply>(second_convert, scale_convert);
activations = multiply;
}
std::shared_ptr<Node> weights = opset10::Constant::create(element::i8, Shape{4, 16, 1, 1}, {-2});
{
auto convert = std::make_shared<opset10::Convert>(weights, element::f32);
auto scale = opset10::Constant::create(element::f16, Shape{}, {0.2});
auto scale_convert = std::make_shared<opset10::Convert>(scale, element::f32);
mark_as_decompression(scale_convert);
auto multiply = std::make_shared<opset10::Multiply>(convert, scale_convert);
weights = multiply;
}
auto conv = std::make_shared<opset10::Convolution>(activations,
weights,
Strides{1, 1},
CoordinateDiff{0, 0},
CoordinateDiff{0, 0},
Strides{1, 1});
function = std::make_shared<Model>(conv, ParameterVector{parameter});
}
manager.register_pass<pass::MarkDequantizationSubgraph>(element::TypeVector{element::u8, element::i8});
manager.register_pass<pass::DisableDecompressionConvertConstantFolding>();
manager.register_pass<pass::ConstantFolding>();
{
auto parameter = std::make_shared<opset10::Parameter>(element::f32, Shape{1, 16, 14, 14});
std::shared_ptr<Node> activations =
std::make_shared<opset10::FakeQuantize>(parameter,
opset10::Constant::create(element::f32, Shape{}, {0}),
opset10::Constant::create(element::f32, Shape{}, {20}),
opset10::Constant::create(element::f32, Shape{}, {0}),
opset10::Constant::create(element::f32, Shape{}, {254}),
255);
{
auto first_convert = std::make_shared<opset10::Convert>(activations, element::u8);
auto second_convert = std::make_shared<opset10::Convert>(first_convert, element::f32);
auto scale = opset10::Constant::create(element::f16, Shape{}, {0.2});
auto scale_convert = std::make_shared<opset10::Convert>(scale, element::f32);
mark_as_decompression(scale_convert);
auto multiply = std::make_shared<opset10::Multiply>(second_convert, scale_convert);
mark_as_dequantization_node(multiply);
activations = multiply;
}
std::shared_ptr<Node> weights = opset10::Constant::create(element::i8, Shape{4, 16, 1, 1}, {-2});
{
auto convert = std::make_shared<opset10::Convert>(weights, element::f32);
pass::disable_constant_folding(convert);
auto scale = opset10::Constant::create(element::f16, Shape{}, {0.2});
auto scale_convert = std::make_shared<opset10::Convert>(scale, element::f32);
mark_as_decompression(scale_convert);
auto multiply = std::make_shared<opset10::Multiply>(convert, scale_convert);
mark_as_dequantization_node(multiply);
weights = multiply;
}