[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:
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();
|
||||
|
||||
|
||||
+4
-6
@@ -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 = {
|
||||
|
||||
Reference in new issue
Block a user