[Python Speech Sample] Change argument format (#11012)
* Change `-i` argument format * Change `-sf` argument format * Change `-o` and `-r` argument format * Fix saving file with multiple utterances * Fix flake8 D415 * fix scale factor for imported models
This commit is contained in:
parent
9dee25fa79
commit
80e7857eca
@ -2,6 +2,8 @@
|
||||
# Copyright (C) 2018-2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
from typing import List, Tuple, Union
|
||||
|
||||
|
||||
def build_arg_parser() -> argparse.ArgumentParser:
|
||||
@ -10,11 +12,12 @@ def build_arg_parser() -> argparse.ArgumentParser:
|
||||
args = parser.add_argument_group('Options')
|
||||
model = parser.add_mutually_exclusive_group(required=True)
|
||||
|
||||
args.add_argument('-h', '--help', action='help', help='Show this help message and exit.')
|
||||
model.add_argument('-m', '--model', type=str,
|
||||
help='Path to an .xml file with a trained model (required if -rg is missing).')
|
||||
model.add_argument('-rg', '--import_gna_model', type=str,
|
||||
help='Read GNA model from file using path/filename provided (required if -m is missing).')
|
||||
|
||||
args.add_argument('-h', '--help', action='help', help='Show this help message and exit.')
|
||||
args.add_argument('-i', '--input', required=True, type=str, help='Required. Path to an input file (.ark or .npz).')
|
||||
args.add_argument('-o', '--output', type=str,
|
||||
help='Optional. Output file name to save inference results (.ark or .npz).')
|
||||
@ -32,8 +35,7 @@ def build_arg_parser() -> argparse.ArgumentParser:
|
||||
args.add_argument('-qb', '--quantization_bits', default=16, type=int, choices=(8, 16), metavar='[8, 16]',
|
||||
help='Optional. Weight bits for quantization: 8 or 16 (default 16).')
|
||||
args.add_argument('-sf', '--scale_factor', type=str,
|
||||
help='Optional. The user-specified input scale factor for quantization. '
|
||||
'If the model contains multiple inputs, provide scale factors by separating them with commas.')
|
||||
help='Optional. The user-specified input scale factor for quantization.')
|
||||
args.add_argument('-wg', '--export_gna_model', type=str,
|
||||
help='Optional. Write GNA model to file using path/filename provided.')
|
||||
args.add_argument('-we', '--export_embedded_gna_model', type=str,
|
||||
@ -51,12 +53,6 @@ def build_arg_parser() -> argparse.ArgumentParser:
|
||||
help='Optional. Enables performance report (specify -a to ensure arch accurate results).')
|
||||
args.add_argument('-a', '--arch', default='CORE', type=str.upper, choices=('CORE', 'ATOM'), metavar='[CORE, ATOM]',
|
||||
help='Optional. Specify architecture. CORE, ATOM with the combination of -pc.')
|
||||
args.add_argument('-iname', '--input_layers', type=str,
|
||||
help='Optional. Layer names for input blobs. The names are separated with ",". '
|
||||
'Allows to change the order of input layers for -i flag. Example: Input1,Input2')
|
||||
args.add_argument('-oname', '--output_layers', type=str,
|
||||
help='Optional. Layer names for output blobs. The names are separated with ",". '
|
||||
'Allows to change the order of output layers for -o flag. Example: Output1:port,Output2:port.')
|
||||
args.add_argument('-cw_l', '--context_window_left', type=int, default=0,
|
||||
help='Optional. Number of frames for left context windows (default is 0). '
|
||||
'Works only with context window models. '
|
||||
@ -72,7 +68,27 @@ def build_arg_parser() -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
def parse_arg_with_names(arg_string: Union[str, None], separator: str = '=') -> Tuple[List[str], List[str]]:
|
||||
keys = []
|
||||
values = []
|
||||
|
||||
if isinstance(arg_string, str):
|
||||
for parameter in re.split(', |,', arg_string):
|
||||
if separator in parameter:
|
||||
key, value = parameter.split(separator)
|
||||
keys.append(key)
|
||||
values.append(value)
|
||||
else:
|
||||
values.append(parameter)
|
||||
|
||||
return keys, values
|
||||
|
||||
|
||||
def check_arg_with_names(arg: Tuple[List[str], List[str]]) -> bool:
|
||||
return True if len(arg[0]) == 0 and len(arg[1]) > 1 else False
|
||||
|
||||
|
||||
def parse_args(separator: str = '=') -> argparse.Namespace:
|
||||
"""Parse and validate command-line arguments."""
|
||||
parser = build_arg_parser()
|
||||
args = parser.parse_args()
|
||||
@ -86,4 +102,32 @@ def parse_args() -> argparse.Namespace:
|
||||
if args.pwl_me < 0.0 or args.pwl_me > 100.0:
|
||||
parser.error('Invalid value for -pwl_me argument. It must be greater than 0.0 and less than 100.0')
|
||||
|
||||
args.input = parse_arg_with_names(args.input, separator)
|
||||
if check_arg_with_names(args.input):
|
||||
parser.error(
|
||||
'Invalid format for -i/--input argment. Please specify the parameter like this '
|
||||
f'<input_name1>{separator}<file1.ark/.npz>,<input_name2>{separator}<file2.ark/.npz> or just <file.ark/.npz> in case of one input.',
|
||||
)
|
||||
|
||||
args.scale_factor = parse_arg_with_names(args.scale_factor, separator)
|
||||
if check_arg_with_names(args.scale_factor):
|
||||
parser.error(
|
||||
'Invalid format for -sf/--scale_factor argment. Please specify the parameter like this '
|
||||
f'<input_name1>{separator}<sf1>,<input_name2>{separator}<sf2> or just <sf> to be applied to all inputs.',
|
||||
)
|
||||
|
||||
args.output = parse_arg_with_names(args.output, separator)
|
||||
if check_arg_with_names(args.output):
|
||||
parser.error(
|
||||
'Invalid format for -o/--output argment. Please specify the parameter like this '
|
||||
f'<output_name1>{separator}<output1.ark/.npz>,<output_name2>{separator}<output2.ark/.npz> or just <output.ark/.npz> in case of one output.',
|
||||
)
|
||||
|
||||
args.reference = parse_arg_with_names(args.reference, separator)
|
||||
if check_arg_with_names(args.reference):
|
||||
parser.error(
|
||||
'Invalid format for -r/--reference argment. Please specify the parameter like this '
|
||||
f'<output_name1>{separator}<reference1.ark/.npz>,<output_name2>{separator}<reference2.ark/.npz> or <reference.ark/.npz> in case of one output.',
|
||||
)
|
||||
|
||||
return args
|
||||
|
@ -3,7 +3,6 @@
|
||||
# Copyright (C) 2018-2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import re
|
||||
import sys
|
||||
from io import BytesIO
|
||||
from timeit import default_timer
|
||||
@ -16,9 +15,9 @@ from openvino.runtime import Core, InferRequest, Layout, Type, set_batch
|
||||
from arg_parser import parse_args
|
||||
from file_options import read_utterance_file, write_utterance_file
|
||||
from utils import (GNA_ATOM_FREQUENCY, GNA_CORE_FREQUENCY,
|
||||
compare_with_reference, get_scale_factor, log,
|
||||
parse_input_layouts, parse_outputs_from_args,
|
||||
parse_scale_factors, set_scale_factors)
|
||||
calculate_scale_factor, compare_with_reference,
|
||||
get_input_layouts, get_sorted_scale_factors, log,
|
||||
set_scale_factors)
|
||||
|
||||
|
||||
def do_inference(data: Dict[str, np.ndarray], infer_request: InferRequest, cw_l: int = 0, cw_r: int = 0) -> np.ndarray:
|
||||
@ -79,12 +78,10 @@ def main():
|
||||
model = core.read_model(args.model)
|
||||
|
||||
# --------------------------- Step 3. Apply preprocessing -------------------------------------------------------------
|
||||
if args.output_layers:
|
||||
output_layer_names, output_layer_ports = parse_outputs_from_args(args)
|
||||
model.add_outputs(list(zip(output_layer_names, output_layer_ports)))
|
||||
model.add_outputs(args.output[0] + args.reference[0])
|
||||
|
||||
if args.layout:
|
||||
layouts = parse_input_layouts(args, model.inputs)
|
||||
layouts = get_input_layouts(args.layout, model.inputs)
|
||||
|
||||
ppp = PrePostProcessor(model)
|
||||
|
||||
@ -125,23 +122,24 @@ def main():
|
||||
|
||||
# Set a GNA scale factor
|
||||
if args.import_gna_model:
|
||||
if args.scale_factor:
|
||||
log.warning(f'Custom scale factor will be used for imported GNA model: {args.import_gna_model}')
|
||||
set_scale_factors(plugin_config, parse_scale_factors(args))
|
||||
if args.scale_factor[1]:
|
||||
log.error(f'Custom scale factor can not be set for imported gna model: {args.import_gna_model}')
|
||||
return 1
|
||||
else:
|
||||
log.info(f'Using scale factor from the imported GNA model: {args.import_gna_model}')
|
||||
log.info(f'Using scale factor from provided imported gna model: {args.import_gna_model}')
|
||||
else:
|
||||
if args.scale_factor:
|
||||
set_scale_factors(plugin_config, parse_scale_factors(args))
|
||||
if args.scale_factor[1]:
|
||||
scale_factors = get_sorted_scale_factors(args.scale_factor, model.inputs)
|
||||
else:
|
||||
scale_factors = []
|
||||
|
||||
for file_name in re.split(', |,', args.input):
|
||||
for file_name in args.input[1]:
|
||||
_, utterances = read_utterance_file(file_name)
|
||||
scale_factors.append(get_scale_factor(utterances[0]))
|
||||
scale_factor = calculate_scale_factor(utterances[0])
|
||||
log.info('Using scale factor(s) calculated from first utterance')
|
||||
scale_factors.append(str(scale_factor))
|
||||
|
||||
log.info('Using scale factor(s) calculated from first utterance')
|
||||
set_scale_factors(plugin_config, scale_factors)
|
||||
set_scale_factors(plugin_config, scale_factors, model.inputs)
|
||||
|
||||
if args.export_embedded_gna_model:
|
||||
plugin_config['GNA_FIRMWARE_MODEL_IMAGE'] = args.export_embedded_gna_model
|
||||
@ -175,59 +173,39 @@ def main():
|
||||
return 0
|
||||
|
||||
# --------------------------- Step 6. Set up input --------------------------------------------------------------------
|
||||
if args.input_layers:
|
||||
input_layer_names = re.split(', |,', args.input_layers)
|
||||
else:
|
||||
input_layer_names = [_input.any_name for _input in compiled_model.inputs]
|
||||
|
||||
input_file_names = re.split(', |,', args.input)
|
||||
input_layer_names = args.input[0] if args.input[0] else [_input.any_name for _input in compiled_model.inputs]
|
||||
input_file_names = args.input[1]
|
||||
|
||||
if len(input_layer_names) != len(input_file_names):
|
||||
log.error(f'Number of model inputs ({len(compiled_model.inputs)}) is not equal '
|
||||
f'to number of ark files ({len(input_file_names)})')
|
||||
sys.exit(-3)
|
||||
return 3
|
||||
|
||||
input_file_data = [read_utterance_file(file_name) for file_name in input_file_names]
|
||||
|
||||
infer_data = [
|
||||
{
|
||||
input_layer_names[j]: input_file_data[j].utterances[i]
|
||||
for j in range(len(input_layer_names))
|
||||
for j in range(len(input_file_data))
|
||||
}
|
||||
for i in range(len(input_file_data[0].utterances))
|
||||
]
|
||||
|
||||
if args.output_layers:
|
||||
output_layer_names, output_layer_ports = parse_outputs_from_args(args)
|
||||
# If a name of output layer contains a port number then concatenate output_layer_names and output_layer_ports
|
||||
if ':' in compiled_model.outputs[0].any_name:
|
||||
output_layer_names = [f'{output_layer_names[i]}:{output_layer_ports[i]}' for i in range(len(output_layer_names))]
|
||||
else:
|
||||
output_layer_names = [compiled_model.outputs[0].any_name]
|
||||
output_layer_names = args.output[0] if args.output[0] else [compiled_model.outputs[0].any_name]
|
||||
output_file_names = args.output[1]
|
||||
|
||||
if args.output:
|
||||
output_file_names = re.split(', |,', args.output)
|
||||
reference_layer_names = args.reference[0] if args.reference[0] else [compiled_model.outputs[0].any_name]
|
||||
reference_file_names = args.reference[1]
|
||||
|
||||
if len(output_layer_names) != len(output_file_names):
|
||||
log.error('The number of output files is not equal to the number of model outputs.')
|
||||
sys.exit(-6)
|
||||
reference_file_data = [read_utterance_file(file_name) for file_name in reference_file_names]
|
||||
|
||||
if args.reference:
|
||||
reference_file_names = re.split(', |,', args.reference)
|
||||
|
||||
if len(output_layer_names) != len(reference_file_names):
|
||||
log.error('The number of reference files is not equal to the number of model outputs.')
|
||||
sys.exit(-5)
|
||||
|
||||
reference_file_data = [read_utterance_file(file_name) for file_name in reference_file_names]
|
||||
|
||||
references = [
|
||||
{
|
||||
output_layer_names[j]: reference_file_data[j].utterances[i]
|
||||
for j in range(len(output_layer_names))
|
||||
}
|
||||
for i in range(len(input_file_data[0].utterances))
|
||||
]
|
||||
references = [
|
||||
{
|
||||
reference_layer_names[j]: reference_file_data[j].utterances[i]
|
||||
for j in range(len(reference_file_data))
|
||||
}
|
||||
for i in range(len(input_file_data[0].utterances))
|
||||
]
|
||||
|
||||
# --------------------------- Step 7. Create infer request ------------------------------------------------------------
|
||||
infer_request = compiled_model.create_infer_request()
|
||||
@ -263,12 +241,12 @@ def main():
|
||||
log.info(f'Frames in utterance: {num_of_frames}')
|
||||
log.info(f'Average Infer time per frame: {avg_infer_time_per_frame * 1000:.2f}ms')
|
||||
|
||||
for name in output_layer_names:
|
||||
for name in set(reference_layer_names + output_layer_names):
|
||||
log.info('')
|
||||
log.info(f'Output blob name: {name}')
|
||||
log.info(f'Output layer name: {name}')
|
||||
log.info(f'Number scores per frame: {results[i][name].shape[1]}')
|
||||
|
||||
if args.reference:
|
||||
if name in references[i].keys():
|
||||
log.info('')
|
||||
compare_with_reference(results[i][name], references[i][name])
|
||||
|
||||
@ -294,11 +272,10 @@ def main():
|
||||
log.info('')
|
||||
log.info(f'Total sample time: {total_infer_time * 1000:.2f}ms')
|
||||
|
||||
if args.output:
|
||||
for i, name in enumerate(output_layer_names):
|
||||
data = [results[i][name] for i in range(len(input_file_data[0].utterances))]
|
||||
write_utterance_file(output_file_names[i], input_file_data[0].keys, data)
|
||||
log.info(f'File {output_file_names[i]} was created!')
|
||||
for i in range(len(output_file_names)):
|
||||
log.info(f'Saving results from "{output_layer_names[i]}" layer to {output_file_names[i]}')
|
||||
data = [results[j][output_layer_names[i]] for j in range(len(input_file_data[0].utterances))]
|
||||
write_utterance_file(output_file_names[i], input_file_data[0].keys, data)
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
log.info('This sample is an API example, '
|
||||
|
@ -2,9 +2,7 @@
|
||||
# Copyright (C) 2018-2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import logging as log
|
||||
import re
|
||||
import sys
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
@ -34,7 +32,7 @@ def compare_with_reference(result: np.ndarray, reference: np.ndarray):
|
||||
log.info(f'stdev error: {stdev_error:.7f}')
|
||||
|
||||
|
||||
def get_scale_factor(matrix: np.ndarray) -> float:
|
||||
def calculate_scale_factor(matrix: np.ndarray) -> float:
|
||||
"""Get scale factor for quantization using utterance matrix."""
|
||||
# Max to find scale factor
|
||||
target_max = 16384
|
||||
@ -45,45 +43,31 @@ def get_scale_factor(matrix: np.ndarray) -> float:
|
||||
return target_max / max_val
|
||||
|
||||
|
||||
def set_scale_factors(plugin_config: dict, scale_factors: list):
|
||||
def set_scale_factors(plugin_config: Dict[str, str], scale_factors: List[str], inputs: List[Output]):
|
||||
"""Set a scale factor provided for each input."""
|
||||
for i, scale_factor in enumerate(scale_factors):
|
||||
log.info(f'For input {i} using scale factor of {scale_factor:.7f}')
|
||||
plugin_config[f'GNA_SCALE_FACTOR_{i}'] = str(scale_factor)
|
||||
for i in range(len(inputs)):
|
||||
log.info(f'For input {inputs[i].get_any_name()} using scale factor of {scale_factors[i]}')
|
||||
plugin_config[f'GNA_SCALE_FACTOR_{i}'] = scale_factors[i]
|
||||
|
||||
|
||||
def parse_scale_factors(args: argparse.Namespace) -> list:
|
||||
"""Get a list of scale factors for input files."""
|
||||
input_files = re.split(', |,', args.input)
|
||||
scale_factors = re.split(', |,', str(args.scale_factor))
|
||||
scale_factors = list(map(float, scale_factors))
|
||||
|
||||
if len(input_files) != len(scale_factors):
|
||||
log.error(f'Incorrect command line for multiple inputs: {len(scale_factors)} scale factors provided for '
|
||||
f'{len(input_files)} input files.')
|
||||
sys.exit(-7)
|
||||
|
||||
for i, scale_factor in enumerate(scale_factors):
|
||||
if float(scale_factor) < 0:
|
||||
log.error(f'Scale factor for input #{i} (counting from zero) is out of range (must be positive).')
|
||||
sys.exit(-8)
|
||||
|
||||
return scale_factors
|
||||
|
||||
|
||||
def parse_outputs_from_args(args: argparse.Namespace) -> Tuple[List[str], List[int]]:
|
||||
"""Get a list of outputs specified in the args."""
|
||||
name_and_port = [output.split(':') for output in re.split(', |,', args.output_layers)]
|
||||
try:
|
||||
return [name for name, _ in name_and_port], [int(port) for _, port in name_and_port]
|
||||
except ValueError:
|
||||
log.error('Incorrect value for -oname/--output_layers option, please specify a port for each output layer.')
|
||||
sys.exit(-4)
|
||||
|
||||
|
||||
def parse_input_layouts(args: argparse.Namespace, inputs: List[Output]) -> Dict[str, str]:
|
||||
if args.layout[0] == '[':
|
||||
return {_input.get_any_name(): args.layout[1:-1] for _input in inputs}
|
||||
def get_input_layouts(layout_string: str, inputs: List[Output]) -> Dict[str, str]:
|
||||
if layout_string[0] == '[':
|
||||
return {_input.get_any_name(): layout_string[1:-1] for _input in inputs}
|
||||
else:
|
||||
sep = '],' if ',' in args.layout else ']'
|
||||
return dict([_input.split('[') for _input in args.layout[:-1].split(sep)])
|
||||
sep = '],' if ',' in layout_string else ']'
|
||||
return dict([_input.split('[') for _input in layout_string[:-1].split(sep)])
|
||||
|
||||
|
||||
def get_sorted_scale_factors(scale_factor_arg: Tuple[List[str], List[str]], inputs: List[Output]) -> List[str]:
|
||||
if scale_factor_arg[0]:
|
||||
res = [1 for _ in range(len(inputs))]
|
||||
input_names = [_input.get_any_name() for _input in inputs]
|
||||
|
||||
for i in range(len(scale_factor_arg[0])):
|
||||
input_index = input_names.index(scale_factor_arg[0][i])
|
||||
res[input_index] = scale_factor_arg[1][i]
|
||||
|
||||
return res
|
||||
|
||||
else:
|
||||
return [scale_factor_arg[1][0] for _ in range(len(inputs))]
|
||||
|
Loading…
Reference in New Issue
Block a user