218 lines
9.4 KiB
Python
Executable File
218 lines
9.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from argparse import ArgumentParser
|
|
import os
|
|
import sys
|
|
import json
|
|
from quantize_types import QuantizerType
|
|
from measure import *
|
|
from utils import *
|
|
|
|
import importlib
|
|
try:
|
|
importlib.import_module("acuitylib")
|
|
except:
|
|
ACUITY_PATH = os.environ['ACUITY_PATH']
|
|
sys.path.append(ACUITY_PATH)
|
|
|
|
from acuitylib.vsi_nn import VSInn
|
|
|
|
post = None
|
|
|
|
def load_net(model_filename, quantized='asymu8', use_hybrid=False):
|
|
nn = VSInn()
|
|
net = nn.create_net()
|
|
if not use_hybrid:
|
|
model = model_filename + ".json"
|
|
else:
|
|
model = model_filename + "_" + quantized + "_hy.quantize.json"
|
|
data = model_filename + ".data"
|
|
inputmeta = model_filename + "_inputmeta.yml"
|
|
postprocess = model_filename + "_postprocess_file.yml"
|
|
|
|
if os.path.exists(model) is True:
|
|
nn.load_model(net, model)
|
|
else:
|
|
print("{} file does not exists.".format(model))
|
|
sys.exit(1)
|
|
|
|
if os.path.exists(data) is True:
|
|
nn.load_model_data(net, data)
|
|
else:
|
|
print("{} file does not exists.".format(data))
|
|
sys.exit(1)
|
|
|
|
if os.path.exists(inputmeta) is True:
|
|
nn.load_model_inputmeta(net, inputmeta)
|
|
else:
|
|
print("{} file does not exists.".format(inputmeta))
|
|
sys.exit(1)
|
|
|
|
if os.path.exists(postprocess) is True:
|
|
nn.load_model_outputmeta(net, postprocess)
|
|
global post
|
|
post = postprocess
|
|
|
|
if quantized != "float32":
|
|
if not use_hybrid:
|
|
model_quantize = model_filename + '_' + quantized + ".quantize"
|
|
else:
|
|
model_quantize = model_filename + '_' + quantized + "_hy.quantize"
|
|
if os.path.exists(model_quantize) is True:
|
|
nn.load_model_quantize(net, model_quantize)
|
|
else:
|
|
if quantized == "float16":
|
|
return net
|
|
print('{} does not exist'.format(model_quantize))
|
|
sys.exit(1)
|
|
return net
|
|
|
|
def export(net, model_filename, quantized='asymu8', force_remove_permute=False, use_hybrid=False):
|
|
nn = VSInn()
|
|
if not use_hybrid:
|
|
quantize_file = model_filename + '_' + quantized + ".quantize"
|
|
model = model_filename + ".json"
|
|
output_dir = 'wksp/{}_{}'.format(model_filename, quantized)
|
|
else:
|
|
# add hybrid quantize for print log
|
|
quantize_file = model_filename + '_' + quantized + "_hy.quantize"
|
|
model = model_filename + '_' + quantized + "_hy.quantize.json"
|
|
# add hybrid quantize output file name
|
|
output_dir = 'wksp/{}_{}'.format(model_filename, quantized + "_hy")
|
|
|
|
output_dir = os.path.join(output_dir, os.path.split(output_dir)[1])
|
|
if quantized != "float32":
|
|
print_params(nn.export_ovxlib, model=model, data=model_filename + ".data", quantize=quantize_file,
|
|
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=post, output_path=output_dir, save_fused_graph=True)
|
|
else:
|
|
print_params(nn.export_ovxlib, model=model, data=model_filename + ".data",
|
|
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=post, output_path=output_dir,
|
|
save_fused_graph=True)
|
|
nn.export_ovxlib(net, output_path=output_dir, dtype=quantized, save_fused_graph=True, force_remove_permute=force_remove_permute)
|
|
|
|
|
|
def generate_exe_script(net, model_filename, quantized='asymu8', iterations=1, use_hybrid=False):
|
|
if use_hybrid:
|
|
quantized = quantized + "_hy"
|
|
inputs = net.get_input_layers(ign_variable=True)
|
|
input_tensor_list = []
|
|
for l in inputs:
|
|
if l.is_op('input'):
|
|
url = l.get_output().url
|
|
input_tensor = url.replace('@', '').replace(':', '_').replace('/', '_')
|
|
shape = l.params.shape
|
|
dims = len(shape)
|
|
if dims > 0 and shape[0] == 0:
|
|
shape[0] = 1
|
|
shape = [str(i) for i in shape]
|
|
input_tensor = input_tensor + '_' + '_'.join(shape)
|
|
input_tensor = 'iter_{}_'.format(iterations - 1) + input_tensor + '.tensor'
|
|
input_tensor_list.append(input_tensor)
|
|
if len(input_tensor_list) < 1:
|
|
print("No input layer!")
|
|
return
|
|
else:
|
|
wksp_dir = 'wksp/{}_{}'.format(model_filename, quantized)
|
|
target_name = '{}_{}'.format(model_filename, quantized)
|
|
cmd_str = './{} {}.export.data'.format(
|
|
target_name.replace("_", "").replace("-", "").replace(".", "").replace(" ", "").lower(), target_name)
|
|
|
|
for i in range(len(input_tensor_list)):
|
|
cmd_str = cmd_str + ' ' + input_tensor_list[i]
|
|
os.system('echo {} > {}/cmd.sh'.format(cmd_str, wksp_dir))
|
|
os.system('chmod +x {}/cmd.sh'.format(wksp_dir))
|
|
print("The executable script cmd.sh is generated.")
|
|
|
|
|
|
def generate_criterion_json(net, model_filename, quantized='asymu8', iterations=1, use_hybrid=False):
|
|
if use_hybrid:
|
|
quantized = quantized + "_hy"
|
|
|
|
rule = dict()
|
|
rule['classification'] = False ## use normal jude
|
|
rule['rules'] = dict()
|
|
index = 0
|
|
|
|
outputs = net.get_output_layers()
|
|
net.compute_shape()
|
|
for l in outputs:
|
|
if l.is_op('output'):
|
|
url = l.get_output().url
|
|
output_tensor = url.replace('@', '').replace(':', '_').replace('/', '_')
|
|
shape = l.get_output().shape.dims
|
|
shape = [str(i) for i in shape]
|
|
output_tensor = output_tensor + '_' + '_'.join(shape)
|
|
output_tensor = 'iter_{}_'.format(iterations - 1) + output_tensor + '.tensor'
|
|
rule['rules'][index] = dict()
|
|
rule['rules'][index]['golden'] = output_tensor
|
|
# Modify 'tolerance' and 'threshold' based on actual condition
|
|
rule['rules'][index]['tolerance'] = 0.01
|
|
rule['rules'][index]['threshold'] = 0.95
|
|
index += 1
|
|
|
|
wksp_dir = 'wksp/{}_{}'.format(model_filename, quantized)
|
|
with open(os.path.join(wksp_dir, 'criterion.json'), 'w+') as f:
|
|
json.dump(rule, f, indent=4)
|
|
|
|
if os.path.exists(os.path.join(sys.path[0], "check_result.py")):
|
|
os.system("cp {}/check_result.py {}".format(sys.path[0], wksp_dir))
|
|
|
|
|
|
def main():
|
|
options = ArgumentParser()
|
|
options.add_argument("model", type=str, help="Model directory")
|
|
options.add_argument("quantized", type=str, help="Quantization type, including float32, " + ', '.join(list(QuantizerType.get_options()))
|
|
+ ", \'float32\' means not quantized.")
|
|
options.add_argument("--iterations", type=int, help="Running iterations.", default=1)
|
|
options.add_argument("--force_remove_permute", action="store_true",
|
|
help="Try to force remove permute of graph IO.\n"
|
|
"(Experimental use only) Force remove the head permute layers inserted after the input layer and "
|
|
"the tail permute layers inserted before the output layer from application. This argument is used "
|
|
"only for export of unify applications from models with NHWC layout data input/output, such as "
|
|
"TensorFlow, TensorFlow Lite, and Keras models. \n"
|
|
"For input layer, When this argument is not specified, permute layers are kept and the tensor"
|
|
"shape is in the NHWC layout. When this argument is specified, the tensor shape MAYBE in the NCHW "
|
|
"layout. Make sure that the feed data has the same layout as the first layer before "
|
|
"application deployed onto devices.\n"
|
|
" For example, for a TensorFlow model with input of (1,224,224,3) in the NHWC layout:\n"
|
|
"If this argument is not specified, the tensor with the shape (1,224,224,3) "
|
|
"NHWC layout is needed.\n"
|
|
"If this argument is specified, the tensor with the shape (1,3,224,224) "
|
|
"NCHW layout maybe needed.\n",
|
|
)
|
|
options.add_argument("--use_hybrid", action="store_true", help="if you use hybrid quantize,please set this --use_hybrid")
|
|
args = options.parse_args()
|
|
print(args)
|
|
|
|
if os.path.exists(args.model) and os.path.isdir(os.path.abspath(args.model)):
|
|
model_filename = get_modelfile_name(args.model)
|
|
if model_filename is None:
|
|
print("Please enter the path that includes the model.")
|
|
os.chdir(args.model)
|
|
else:
|
|
model_filename = args.model
|
|
quantized = args.quantized
|
|
iterations = args.iterations
|
|
force_remove_permute = args.force_remove_permute
|
|
use_hybrid = args.use_hybrid
|
|
quantized_format = QuantizerType.get_options()
|
|
if quantized not in quantized_format and quantized != 'float32':
|
|
print("Please enter the correct quantization format.")
|
|
quantized_format.insert(0, 'float32')
|
|
print(list(quantized_format))
|
|
sys.exit(1)
|
|
|
|
# load model
|
|
net = load_net(model_filename, quantized, use_hybrid)
|
|
# export
|
|
export(net, model_filename, quantized, force_remove_permute, use_hybrid)
|
|
# generate executable script
|
|
generate_exe_script(net, model_filename, quantized, iterations, use_hybrid)
|
|
# generate criterion.json
|
|
generate_criterion_json(net, model_filename, quantized, iterations, use_hybrid)
|
|
# measure
|
|
measure(net=net, model_filename=model_filename, quantized=quantized)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|