[GNA] Fix scale factor calculation for int8 convolution weights (#14320)

* [GNA] Fix input generation in convolution low precision tests

* [GNA] Fix scale factor calculation for int8 convolution weights

Co-authored-by: Szymon Irzabek <szymon.jakub.irzabek@intel.com>
This commit is contained in:
Marcin KacprzakandSzymon Irzabek authored and GitHub committed 2022-11-30 12:37:10 +00:00
1 parent c09af40b4c
commit 23d2451072
4 files changed
+50 -28

No files matched your search

@@ -14,13 +14,6 @@ namespace ov {
namespace intel_gna {
namespace frontend {
bool LayerQuantizer::IsBiasCompound(const LayerInfo& layer_info,
const QuantizedLayerParams* quant_layer_params) {
auto biases_precision = GetBiasesPrecision(layer_info, *quant_layer_params);
auto compound_bias_precision = InferenceEngine::Precision::fromType<gna_compound_bias_t>();
return (biases_precision == compound_bias_precision);
}
template <class T>
inline bool LayerQuantizer::ShouldAlwaysAllocate() {
return false;
@@ -152,7 +145,7 @@ void LayerQuantizer::QuantizeWeightsPrep(InferenceEngine::WeightableLayer& wl, Q
const auto& quantized_weights =
blob_precision != InferenceEngine::Precision::FP32 && blob_precision != InferenceEngine::Precision::FP16;
const bool& compound_bias =
IsBiasCompound(LayerInfo(wl), InferenceEngine::getInjectedData<QuantizedLayerParams>(wl));
IsBiasCompound(LayerInfo(wl), *InferenceEngine::getInjectedData<QuantizedLayerParams>(wl), gna_config);
const auto& compound_bias_ptr =
(compound_bias && wl._biases) ? wl._biases->buffer().as<gna_compound_bias_t*>() : nullptr;
@@ -263,7 +256,7 @@ void LayerQuantizer::QuantizeWeightsBiases(InferenceEngine::WeightableLayer& wl)
quant_layer_params->_weights_quant
};
auto bias_prec = GetBiasesPrecision(LayerInfo(wl), *quant_layer_params);
auto bias_prec = GetBiasesPrecision(LayerInfo(wl), *quant_layer_params, gna_config);
auto weight_prec = GetWeightsPrecision(LayerInfo(wl), *quant_layer_params, gna_config);
QuantizeBiasesPrep(bias_prec, wl, common_data);
@@ -332,8 +325,9 @@ InferenceEngine::Precision LayerQuantizer::GetOutputPrecision() {
return InferenceEngine::Precision::I32;
}
InferenceEngine::Precision LayerQuantizer::GetBiasesPrecision(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params) {
InferenceEngine::Precision GetBiasesPrecision(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params,
const Config& gna_config) {
if (layer_info.isConvolution() || layer_info.isConvolutionFilter() || layer_info.isScaleShift()) {
return InferenceEngine::Precision::I32;
}
@@ -382,6 +376,14 @@ InferenceEngine::Precision GetWeightsPrecision(const LayerInfo& layer_info,
}
}
bool IsBiasCompound(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params,
const Config& gna_config) {
auto biases_precision = GetBiasesPrecision(layer_info, quant_layer_params, gna_config);
auto compound_bias_precision = InferenceEngine::Precision::fromType<gna_compound_bias_t>();
return (biases_precision == compound_bias_precision);
}
} // namespace frontend
} // namespace intel_gna
} // namespace ov
@@ -25,12 +25,35 @@ InferenceEngine::Precision GetInputPrecision();
* @brief Returns layer's target weights precision
* @param layer_info Layer's information
* @param quant_layer_params Layer's quantization parameters
* @param gna_config GNA Plugin configuration
* @return layer's target weights precision
*/
InferenceEngine::Precision GetWeightsPrecision(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params,
const Config& gna_config);
/**
* @brief Returns layer's target biases precision
* @param layer_info Layer's information
* @param quant_layer_params Layer's quantization parameters
* @param gna_config GNA Plugin configuration
* @return layer's target biases precision
*/
InferenceEngine::Precision GetBiasesPrecision(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params,
const Config& gna_config);
/**
* @brief Checks whether layer's target biases are compound
* @param layer_info Layer's information
* @param quant_layer_params Layer's quantization parameters
* @param gna_config GNA Plugin configuration
* @return true if layer's target biases are compound
*/
bool IsBiasCompound(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params,
const Config& gna_config);
class LayerQuantizer {
const Config& gna_config;
@@ -65,10 +88,7 @@ class LayerQuantizer {
inline bool ShouldAlwaysAllocate();
size_t GetBiasSizeForLayer(InferenceEngine::WeightableLayer& wl);
bool IsBiasCompound(const LayerInfo& layer_info, const QuantizedLayerParams* quant_layer_params);
InferenceEngine::Precision GetOutputPrecision();
InferenceEngine::Precision GetBiasesPrecision(const LayerInfo& layer_info,
const QuantizedLayerParams& quant_layer_params);
public:
LayerQuantizer(const Config& gna_config);
@@ -1164,13 +1164,16 @@ bool ScaleFactorCalculator::ScaleFactorPerLayerWeightable(InferenceEngine::Weigh
THROW_GNA_EXCEPTION << "Incorrect weight value for " << wl->name << ":" << wl->type << "\n";
}
auto quant = InferenceEngine::getInjectedData<QuantizedLayerParams>(*wl);
int inputsSize = GetInputPrecision().size();
const auto weights_prec = GetWeightsPrecision(LayerInfo(wl), *quant, gna_config);
const auto is_bias_compound = IsBiasCompound(LayerInfo(wl), *quant, gna_config);
auto prevLayer = CNNNetPrevLayer(wl);
auto quantDataForInputLayer =
InferenceEngine::getInjectedData<QuantizedLayerParams>(*InferenceEngine::CNNNetPrevLayer(wl).get());
InferenceEngine::getInjectedData<QuantizedLayerParams>(*prevLayer.get());
auto quant = InferenceEngine::getInjectedData<QuantizedLayerParams>(*wl);
quant->_src_quant = quantDataForInputLayer->_dst_quant;
if (quant->_weights_quant.IsStatsSet() && !quant->_weights_quant.IsScaleSet()) {
auto getScale = [&quant](size_t i) {
return CalculateScaleFactorFromStats(quant->_weights_quant.GetLevels(),
@@ -1183,8 +1186,8 @@ bool ScaleFactorCalculator::ScaleFactorPerLayerWeightable(InferenceEngine::Weigh
}
auto multiplier = 1.0f;
if (quant->_weights_quant.GetLevels() <= std::numeric_limits<uint8_t>::max()) {
// GNA supports additional multiplier for only 8bit weights.
if (is_bias_compound) {
// GNA supports additional multiplier only for weights used in combination with compound bias.
// The multipler is used to extend dynamic range.
multiplier = MAX_OUT_MULTIPLIER;
}
@@ -1193,8 +1196,6 @@ bool ScaleFactorCalculator::ScaleFactorPerLayerWeightable(InferenceEngine::Weigh
quant->_weights_quant.SetScale(min_channel_scale * multiplier);
}
auto weights_prec = GetWeightsPrecision(LayerInfo(wl), *quant, gna_config);
if (!quant->_weights_quant.IsScaleSet()) {
size_t scaleRange = 0;
if (weights_prec == InferenceEngine::Precision::I16) {
@@ -1224,7 +1225,7 @@ bool ScaleFactorCalculator::ScaleFactorPerLayerWeightable(InferenceEngine::Weigh
// use the MAX_OUT_MULTIPLIER only for int8_t weigths with compound bias (for now handled here only with int16_t inputs)
// it gives the possibility to exetend the output dynamic range
if (weights_prec == InferenceEngine::Precision::I8 && inputsSize == 2) {
if (is_bias_compound) {
quant->_weights_quant.SetScale(quant->_weights_quant.GetScale() * MAX_OUT_MULTIPLIER);
}
@@ -1238,8 +1239,9 @@ bool ScaleFactorCalculator::ScaleFactorPerLayerWeightable(InferenceEngine::Weigh
}
quant->_weights_quant.SetScale(quant->_weights_quant.GetScale() / weights_reducer);
}
double tmp_dst_quant_scale = quant->_weights_quant.GetScale() * quant->_src_quant.GetScale();
if (weights_prec == InferenceEngine::Precision::I8) {
if (weights_prec == InferenceEngine::Precision::I8 && !(LayerInfo(wl).isConvolution() || LayerInfo(wl).isConvolutionFilter())) {
auto itt = thresholds.begin();
auto limit = std::numeric_limits<int32_t>::max();
@@ -66,10 +66,8 @@ public:
}
InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo& info) const override {
return FuncTestUtils::createAndFillBlob(info.getTensorDesc(),
-0.05f,
0.05f,
1 / inputDataResolution);
return FuncTestUtils::createAndFillBlobFloatNormalDistribution(
info.getTensorDesc(), 0.0f, 0.2f, 7235346);
}
ParameterVector createInputVector(const Type& type, const vector<std::size_t>& shapes) {
@@ -113,7 +111,7 @@ protected:
// Create network
auto inputVector = createInputVector(ngPrc, {inputShape});
auto inputFQ = createFQNode(ngPrc, inputVector[0], fqMin, fqMax, levels);
auto kernelWeights = makeConstant<float>(ngPrc, {8, 8, kernelHeight, 2}, {0.1f});
auto kernelWeights = makeConstant<float>(ngPrc, {8, 8, kernelHeight, 2}, {}, true, 1.0f, -1.0f, 7235346);
auto weightsFQ = createFQNode(ngPrc, kernelWeights, fqMin, fqMax, levels);
auto convolution = make_shared<Convolution>(inputFQ,
weightsFQ,
@@ -171,7 +169,7 @@ const vector<Shape> inputShapes = {
};
const vector<pair<float, float>> fqMinMax = {
{-8, 8}
{-1.0f, 1.0f}
};
const vector<std::size_t> levels = {