[SAMPLES][GNA] Update C++ speech sample with new config API (#10357)

* [SAMPLES][GNA] Update speech sample with new cofig API

* Review comments

* Some additional checks
This commit is contained in:
Nadezhda Ageeva authored and GitHub committed 2022-02-16 13:23:50 +03:00
1 parent 2e71fccd82
commit fc5a416423
4 files changed
+138 -49

No files matched your search

+30 -27
View File
@@ -19,7 +19,7 @@
// clang-format off
#include <openvino/openvino.hpp>
#include <gna/gna_config.hpp>
#include <openvino/runtime/intel_gna/properties.hpp>
#include <samples/args_helper.hpp>
#include <samples/slog.hpp>
@@ -141,8 +141,15 @@ int main(int argc, char* argv[]) {
if (useGna) {
std::string gnaDevice =
useHetero ? FLAGS_d.substr(FLAGS_d.find("GNA"), FLAGS_d.find(",") - FLAGS_d.find("GNA")) : FLAGS_d;
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_DEVICE_MODE] =
gnaDevice.find("_") == std::string::npos ? "GNA_AUTO" : gnaDevice;
auto parse_gna_device = [&](const std::string& device) -> ov::intel_gna::ExecutionMode {
ov::intel_gna::ExecutionMode mode;
std::stringstream ss(device);
ss >> mode;
return mode;
};
gnaPluginConfig[ov::intel_gna::execution_mode.name()] = gnaDevice.find("_") == std::string::npos
? ov::intel_gna::ExecutionMode::AUTO
: parse_gna_device(gnaDevice);
}
if (FLAGS_pc) {
genericPluginConfig.emplace(ov::enable_profiling(true));
@@ -151,23 +158,23 @@ int main(int argc, char* argv[]) {
if (!FLAGS_rg.empty()) {
slog::warn << "Custom scale factor will be used for imported gna model: " << FLAGS_rg << slog::endl;
}
auto scaleFactorInput = parse_scale_factors(FLAGS_sf);
if (numInputFiles != scaleFactorInput.size()) {
auto scale_factors_per_input = parse_scale_factors(model->inputs(), FLAGS_sf);
if (numInputFiles != scale_factors_per_input.size()) {
std::string errMessage(
"Incorrect command line for multiple inputs: " + std::to_string(scaleFactorInput.size()) +
"Incorrect command line for multiple inputs: " + std::to_string(scale_factors_per_input.size()) +
" scale factors provided for " + std::to_string(numInputFiles) + " input files.");
throw std::logic_error(errMessage);
}
for (size_t i = 0; i < scaleFactorInput.size(); ++i) {
slog::info << "For input " << i << " using scale factor of " << scaleFactorInput[i] << slog::endl;
std::string scaleFactorConfigKey = GNA_CONFIG_KEY(SCALE_FACTOR) + std::string("_") + std::to_string(i);
gnaPluginConfig[scaleFactorConfigKey] = scaleFactorInput[i];
for (auto&& sf : scale_factors_per_input) {
slog::info << "For input " << sf.first << " using scale factor of " << sf.second << slog::endl;
}
gnaPluginConfig[ov::intel_gna::scale_factors_per_input.name()] = scale_factors_per_input;
} else {
// "static" quantization with calculated scale factor
if (!FLAGS_rg.empty()) {
slog::info << "Using scale factor from provided imported gna model: " << FLAGS_rg << slog::endl;
} else {
std::map<std::string, float> scale_factors_per_input;
for (size_t i = 0; i < numInputFiles; i++) {
auto inputFileName = inputFiles[i].c_str();
std::string name;
@@ -187,30 +194,26 @@ int main(int argc, char* argv[]) {
numFrames * numFrameElements);
slog::info << "Using scale factor of " << floatScaleFactor << " calculated from first utterance."
<< slog::endl;
std::string scaleFactorConfigKey =
GNA_CONFIG_KEY(SCALE_FACTOR) + std::string("_") + std::to_string(i);
gnaPluginConfig[scaleFactorConfigKey] = std::to_string(floatScaleFactor);
scale_factors_per_input[model->input(i).get_any_name()] = floatScaleFactor;
}
gnaPluginConfig[ov::intel_gna::scale_factors_per_input.name()] = scale_factors_per_input;
}
}
if (FLAGS_qb == 8) {
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_PRECISION] = "I8";
} else {
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_PRECISION] = "I16";
}
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_EXEC_TARGET] = FLAGS_exec_target;
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_COMPILE_TARGET] = FLAGS_compile_target;
gnaPluginConfig[GNA_CONFIG_KEY(COMPACT_MODE)] = CONFIG_VALUE(NO);
IE_SUPPRESS_DEPRECATED_START
gnaPluginConfig[GNA_CONFIG_KEY(PWL_MAX_ERROR_PERCENT)] = std::to_string(FLAGS_pwl_me);
IE_SUPPRESS_DEPRECATED_END
gnaPluginConfig[ov::hint::inference_precision.name()] = (FLAGS_qb == 8) ? ov::element::i8 : ov::element::i16;
auto parse_target = [&](const std::string& target) -> ov::intel_gna::HWGeneration {
return (target == "GNA_TARGET_2_0") ? ov::intel_gna::HWGeneration::GNA_2_0
: (target == "GNA_TARGET_3_0") ? ov::intel_gna::HWGeneration::GNA_3_0
: ov::intel_gna::HWGeneration::UNDEFINED;
};
gnaPluginConfig[ov::intel_gna::execution_target.name()] = parse_target(FLAGS_exec_target);
gnaPluginConfig[ov::intel_gna::compile_target.name()] = parse_target(FLAGS_compile_target);
gnaPluginConfig[ov::intel_gna::memory_reuse.name()] = false;
gnaPluginConfig[ov::intel_gna::pwl_max_error_percent.name()] = FLAGS_pwl_me;
// -----------------------------------------------------------------------------------------------------
// --------------------------- Write model to file --------------------------------------------------
// Embedded GNA model dumping (for Intel(R) Speech Enabling Developer Kit)
if (!FLAGS_we.empty()) {
IE_SUPPRESS_DEPRECATED_START
gnaPluginConfig[InferenceEngine::GNAConfigParams::KEY_GNA_FIRMWARE_MODEL_IMAGE] = FLAGS_we;
IE_SUPPRESS_DEPRECATED_END
gnaPluginConfig[ov::intel_gna::firmware_model_image_path.name()] = FLAGS_we;
}
// -----------------------------------------------------------------------------------------------------
// --------------------------- Step 2. Loading model to the device ------------------------------------------
+2 -1
View File
@@ -90,7 +90,8 @@ static const char quantization_bits_message[] = "Optional. Weight bits for quant
static const char scale_factor_message[] =
"Optional. User-specified input scale factor for quantization (use with -q user). "
"If the network contains multiple inputs, provide scale factors by separating them with "
"commas.";
"commas. "
"For example: <input_name1>:<sf1>,<input_name2>:<sf2> or just <sf> to be applied to all inputs";
/// @brief message for batch size argument
static const char batch_size_message[] = "Optional. Batch size 1-8 (default 1)";
+104 -21
View File
@@ -361,30 +361,113 @@ void sum_performance_counters(std::map<std::string, ov::ProfilingInfo> const& pe
}
/**
* @brief Parse scale factors
* @param str reference to user-specified input scale factor for quantization, can be separated by comma
* @return vector scale factors
* @brief Split string by delimeter
* @param s input string
* @param delim delimeter
* @return vector of chunks
*/
std::vector<std::string> parse_scale_factors(const std::string& str) {
std::vector<std::string> scaleFactorInput;
std::vector<std::string> split(const std::string& s, char delim) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string item;
if (!str.empty()) {
std::string outStr;
std::istringstream stream(str);
int i = 0;
while (getline(stream, outStr, ',')) {
auto floatScaleFactor = std::stof(outStr);
if (floatScaleFactor <= 0.0f) {
throw std::logic_error("Scale factor for input #" + std::to_string(i) +
" (counting from zero) is out of range (must be positive).");
}
scaleFactorInput.push_back(outStr);
i++;
}
} else {
throw std::logic_error("Scale factor need to be specified via -sf option if you are using -q user");
while (getline(ss, item, delim)) {
result.push_back(item);
}
return scaleFactorInput;
return result;
}
/**
* @brief Concat strings using delimeter
* @param chunks input chunks
* @param delim delimeter
* @return concatenated string
*/
std::string concat(const std::vector<std::string>& chunks, char delim) {
std::stringstream ss;
for (auto&& chunk : chunks) {
if (!ss.str().empty()) {
ss << delim;
}
ss << chunk;
}
return ss.str();
}
/**
* @brief Check whether name is present in node vector
* @param nodes nodes
* @param node_name name
* @return false or true
*/
bool check_name(const ov::OutputVector& nodes, const std::string& node_name) {
std::vector<std::string> any_names;
bool count = false;
for (auto& node : nodes) {
any_names.push_back(node.get_any_name());
auto names = node.get_names();
count = std::count(names.begin(), names.end(), node_name);
if (count)
break;
}
if (!count) {
std::stringstream ss;
ss << "Incorrect node name '" + node_name << "'! ";
ss << "Try one of the following names: [ ";
for (auto&& name : any_names) {
ss << name << " ";
}
ss << "]";
throw std::logic_error(ss.str());
}
return count;
}
/**
* @brief Parse scale factors per input
* Format : <input_name1>:<sf1>,<input2>:<sf2> or just <sf>
* @param inputs model inputs
* @param values_string values_string input string
* @return map of scale factors per input
*/
std::map<std::string, float> parse_scale_factors(const ov::OutputVector& inputs, const std::string& values_string) {
auto get_sf = [&](const std::string& sf_string, const std::string& input_name = "") -> float {
float sf;
try {
sf = std::stof(sf_string);
} catch (...) {
throw std::logic_error("Can't get float scale factor from: " + sf_string);
}
if (sf <= 0.0f) {
throw std::logic_error("Scale factor for input '" + input_name +
"' (counting from zero) is out of range (must be positive).");
}
return sf;
};
std::map<std::string, float> result;
auto scale_factor_strings = split(values_string, ',');
for (auto& scale_factor_string : scale_factor_strings) {
auto values = split(scale_factor_string, ':');
if (values.size() == 1) {
if (scale_factor_strings.size() != 1) {
throw std::logic_error("Unrecognized scale factor format! "
"Please specify <input_name1>:<sf1>,<input_name2>:<sf2> or "
"just <sf> to be applied to all inputs");
}
auto scale_factor = get_sf(values.at(0));
for (auto& input : inputs) {
result[input.get_any_name()] = scale_factor;
}
} else if (values.size() > 0) {
auto sf_sting = values.back();
values.pop_back();
// input name can contain port, concat back
auto input_name = concat(values, ':');
check_name(inputs, input_name);
result[input_name] = get_sf(sf_sting, input_name);
}
}
return result;
}
/**
@@ -26,6 +26,8 @@ test_data = get_tests(cmd_params={'i': [os.path.join('ark', 'dev93_10.ark')],
'o': ['res_output.ark'],
'r': [os.path.join('ark', 'dev93_scores_10.ark')],
'qb': [8, 16],
'sf': ["Parameter:2175.43", "2175.43"],
'q': ["static", "user"],
'd': ['GNA_SW_EXACT']},
use_device=False
)