[LPT] Check on isQuantized fixed (#14151)
This commit is contained in:
1 parent
4b51cf5ba0
commit
f06c44115f
5 files changed
+108
-27
No files matched your search
@@ -208,7 +208,7 @@ std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>> decomposeFakeQuantize(
|
||||
}
|
||||
|
||||
//TODO: pass min levels as a parameter?
|
||||
if (levels < 2ul) {
|
||||
if (levels <= 2ul) {
|
||||
return std::make_tuple(nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,8 +253,27 @@ bool WeightableLayerTransformation::isQuantizedStatic(const std::shared_ptr<cons
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t outChannelsShapeIndex = ov::is_type<opset1::ConvolutionBackpropData>(layer) ? 1ul : 0ul;
|
||||
auto checkConstShape = [&](const std::shared_ptr<ngraph::opset1::Constant> node) {
|
||||
const auto subConstShape = node->get_shape();
|
||||
if (shape_size(subConstShape) > 1ul && shape_size(subConstShape) != subConstShape[outChannelsShapeIndex])
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
};
|
||||
|
||||
if (dequantizationOnWeights.subtract && !checkConstShape(dequantizationOnWeights.subtractConstant) ||
|
||||
dequantizationOnWeights.multiply && !checkConstShape(dequantizationOnWeights.multiplyConstant)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto deqData = dequantizationOnWeights.data.get_node_shared_ptr();
|
||||
// Quantize/Dequantize case
|
||||
if (ov::is_type<ngraph::opset1::Convert>(deqData)) {
|
||||
deqData = deqData->get_input_node_shared_ptr(0);
|
||||
}
|
||||
// TODO: LPT: is it possible to share with canBeTransformed?
|
||||
if (ov::is_type<opset1::Constant>(dequantizationOnWeights.data.get_node())) {
|
||||
if (ov::is_type<opset1::Constant>(deqData)) {
|
||||
const ngraph::element::Type weightsDataPrecision = dequantizationOnWeights.data.get_element_type();
|
||||
if (!DataPrecision::isSupported(weightsDataPrecision)) {
|
||||
return false;
|
||||
@@ -266,23 +285,15 @@ bool WeightableLayerTransformation::isQuantizedStatic(const std::shared_ptr<cons
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t outChannelsShapeIndex = ov::is_type<opset1::ConvolutionBackpropData>(layer) ? 1ul : 0ul;
|
||||
if (dequantizationOnWeights.subtract) {
|
||||
const auto subConstShape = dequantizationOnWeights.subtractConstant->get_shape();
|
||||
if (shape_size(subConstShape) > 1ul && shape_size(subConstShape) != subConstShape[outChannelsShapeIndex]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (dequantizationOnWeights.multiply) {
|
||||
const auto mulConstShape = dequantizationOnWeights.multiplyConstant->get_shape();
|
||||
if (shape_size(mulConstShape) > 1ul && shape_size(mulConstShape) != mulConstShape[outChannelsShapeIndex]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (ov::is_type<opset1::FakeQuantize>(dequantizationOnWeights.data.get_node())) {
|
||||
} else if (auto fq = ov::as_type_ptr<opset1::FakeQuantize>(deqData)) {
|
||||
for (size_t i = 1; i < fq->get_input_size(); ++i) {
|
||||
if (auto constant = ov::as_type_ptr<ngraph::opset1::Constant>(fq->get_input_node_shared_ptr(i))) {
|
||||
if (!checkConstShape(constant)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+52
-9
@@ -23,6 +23,7 @@ namespace {
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::pass;
|
||||
using namespace ngraph::builder::subgraph;
|
||||
|
||||
using const_node_ptr = const std::shared_ptr<const ngraph::Node>;
|
||||
using callback_function_type = std::function<bool(const_node_ptr&)>;
|
||||
@@ -43,6 +44,19 @@ public:
|
||||
callback_function_type callback;
|
||||
|
||||
Actual() = default;
|
||||
Actual(
|
||||
const ngraph::element::Type& precisionBeforeDequantization,
|
||||
const DequantizationOperations& dequantizationOnActivations,
|
||||
const FakeQuantizeOnWeights& fakeQuantizeOnWeights,
|
||||
const DequantizationOperations& dequantizationOnWeights,
|
||||
const std::shared_ptr<ngraph::opset1::Constant>& weights,
|
||||
const callback_function_type& callback = empty_callback) :
|
||||
precisionBeforeDequantization(precisionBeforeDequantization),
|
||||
dequantizationOnActivations(dequantizationOnActivations),
|
||||
fakeQuantizeOnWeights(fakeQuantizeOnWeights),
|
||||
dequantizationOnWeights(dequantizationOnWeights),
|
||||
weights(weights),
|
||||
callback(callback) {}
|
||||
Actual(
|
||||
const ngraph::element::Type& precisionBeforeDequantization,
|
||||
const ngraph::builder::subgraph::DequantizationOperations& dequantizationOnActivations,
|
||||
@@ -55,16 +69,16 @@ public:
|
||||
weights(weights),
|
||||
callback(callback) {}
|
||||
Actual(
|
||||
const ngraph::element::Type& precisionBeforeDequantization,
|
||||
const ngraph::builder::subgraph::DequantizationOperations& dequantizationOnActivations,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationOnWeights,
|
||||
const ngraph::element::Type& precisionBeforeDequantization,
|
||||
const ngraph::builder::subgraph::DequantizationOperations& dequantizationOnActivations,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationOnWeights,
|
||||
const std::shared_ptr<ngraph::opset1::Constant>& weights,
|
||||
const callback_function_type& callback = empty_callback) :
|
||||
precisionBeforeDequantization(precisionBeforeDequantization),
|
||||
dequantizationOnActivations(dequantizationOnActivations),
|
||||
dequantizationOnWeights(dequantizationOnWeights),
|
||||
weights(weights),
|
||||
callback(callback) {}
|
||||
precisionBeforeDequantization(precisionBeforeDequantization),
|
||||
dequantizationOnActivations(dequantizationOnActivations),
|
||||
dequantizationOnWeights(dequantizationOnWeights),
|
||||
weights(weights),
|
||||
callback(callback) {}
|
||||
};
|
||||
|
||||
class Expected {
|
||||
@@ -113,7 +127,14 @@ public:
|
||||
element::i64,
|
||||
Shape{ outputShape.size() },
|
||||
Shape{ inputChannels, outputShape[1], 1, 1 }));
|
||||
if (!testValues.actual.fakeQuantizeOnWeights.empty()) {
|
||||
if (!testValues.actual.fakeQuantizeOnWeights.empty() && !testValues.actual.dequantizationOnWeights.empty()) {
|
||||
actualWeights = ConvolutionBackpropDataFunction::getWeights(
|
||||
outputShape,
|
||||
netPrecision,
|
||||
testValues.actual.fakeQuantizeOnWeights,
|
||||
testValues.actual.dequantizationOnWeights,
|
||||
ov::as_type_ptr<opset1::Constant>(actualWeights));
|
||||
} else if (!testValues.actual.fakeQuantizeOnWeights.empty()) {
|
||||
actualWeights = ngraph::builder::subgraph::ConvolutionBackpropDataFunction::getWeights(
|
||||
outputShape,
|
||||
netPrecision,
|
||||
@@ -152,6 +173,7 @@ public:
|
||||
outputShape,
|
||||
netPrecision,
|
||||
testValues.actual.fakeQuantizeOnWeights,
|
||||
testValues.actual.dequantizationOnWeights,
|
||||
ov::as_type_ptr<opset1::Constant>(refWeights));
|
||||
} else {
|
||||
refWeights = ngraph::builder::subgraph::ConvolutionBackpropDataFunction::getWeights(
|
||||
@@ -451,6 +473,27 @@ const std::vector<ConvolutionBackpropDataTransformationTestValues> testValues =
|
||||
true
|
||||
}
|
||||
},
|
||||
// FQ + DQ version
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
// ActualValues
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, { 0.02f }},
|
||||
{ 255ul, Shape({ 8, 1, 1, 1 }), { 0.f }, { 254.f }, { -1.27f }, { 1.27f }, ngraph::element::i8 },
|
||||
{{ngraph::element::f32}, {}, { {0.01f}, ngraph::element::f32, {8, 1, 1, 1} }},
|
||||
op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector<float>{ 2.f })
|
||||
},
|
||||
// ExpectedValues
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, { 0.02f }},
|
||||
{},
|
||||
{},
|
||||
op::Constant::create(ngraph::element::i8, ngraph::Shape{}, std::vector<float>{ 2.f }),
|
||||
false
|
||||
}
|
||||
},
|
||||
// QDq version
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
|
||||
+6
@@ -27,6 +27,12 @@ public:
|
||||
const element::Type& netPrecision,
|
||||
const builder::subgraph::FakeQuantizeOnWeights& fqOnWeights,
|
||||
const std::shared_ptr<opset1::Constant>& value = nullptr);
|
||||
static std::shared_ptr<Node> getWeights(
|
||||
const Shape& shape,
|
||||
const element::Type& netPrecision,
|
||||
const builder::subgraph::FakeQuantizeOnWeights& fqOnWeights,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationOnWeights,
|
||||
const std::shared_ptr<opset1::Constant>& value = nullptr);
|
||||
static std::shared_ptr<Function> get(
|
||||
const element::Type netPrecision,
|
||||
const PartialShape& inputShape,
|
||||
|
||||
+21
@@ -88,6 +88,27 @@ std::shared_ptr<Node> ConvolutionBackpropDataFunction::getWeights(
|
||||
return dq;
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> ConvolutionBackpropDataFunction::getWeights(
|
||||
const Shape& shape,
|
||||
const element::Type& netPrecision,
|
||||
const builder::subgraph::FakeQuantizeOnWeights& fqOnWeights,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationOnWeights,
|
||||
const std::shared_ptr<opset1::Constant>& value) {
|
||||
const auto weights =
|
||||
value != nullptr
|
||||
? value
|
||||
: std::make_shared<opset1::Constant>(element::i8, shape, std::vector<float>(shape_size(shape), 1));
|
||||
const auto convert = std::make_shared<opset1::Convert>(weights, netPrecision);
|
||||
OutputVector convertedOutput(1);
|
||||
convert->constant_fold(convertedOutput, convert->input_values());
|
||||
const auto convertedWeights = convertedOutput[0].get_node_shared_ptr();
|
||||
const auto fq = makeFakeQuantizeTypeRelaxed(convertedWeights, netPrecision, fqOnWeights);
|
||||
|
||||
auto dequantizationStructure = dequantizationOnWeights;
|
||||
dequantizationStructure.setPrecision(netPrecision);
|
||||
return makeDequantization(fq, dequantizationStructure);
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> ConvolutionBackpropDataFunction::getOriginal(
|
||||
const element::Type precision,
|
||||
const element::Type netPrecision,
|
||||
|
||||
Reference in new issue
Block a user