netrans/script/importer.py

363 lines
16 KiB
Python
Executable File

#!/usr/bin/env python3
from utils import *
from argparse import ArgumentParser
import numpy as np
import os
import sys
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
def read_inputs_outputs_file(inputs_outputs_file):
args_dict = {
"inputs": None,
"outputs": None,
"input_size_list": None,
"size_with_batch": None,
"input_dtype_list": None,
"target_onnx_file": None,
"predef_file": None,
"mean_values": None,
"std_values": None
}
with open(inputs_outputs_file, 'r') as inter_file:
args = inter_file.readlines()
if len(args) == 1:
args = args[0].split("--")
for arg in args:
if "inputs" in arg:
args_dict["inputs"] = ' '.join(arg.split()[1:]).strip('\"').strip('\'')
elif "outputs" in arg:
args_dict["outputs"] = ' '.join(arg.split()[1:]).strip('\"').strip('\'')
elif "input-size-list" in arg:
args_dict["input_size_list"] = arg.split()[1].strip('\"').strip('\'')
elif "size-with-batch" in arg:
args_dict["size_with_batch"] = arg.split()[1].strip('\"').strip('\'')
elif "input-dtype-list" in arg:
args_dict["input_dtype_list"] = arg.split()[1].strip('\"').strip('\'')
elif "predef-file" in arg:
args_dict["predef_file"] = arg.split()[1]
elif "mean-values" in arg:
args_dict["mean_values"] = arg.split()[1].strip('\"').strip('\'')
elif "std-values" in arg:
args_dict["std_values"] = arg.split()[1].strip('\"').strip('\'')
return args_dict
def importer(modelfile_name, save=True):
nn = VSInn()
if os.path.exists(modelfile_name+'.prototxt') is True:
prototxt = modelfile_name+'.prototxt'
weights = modelfile_name+'.caffemodel'
if os.path.exists(weights) is True:
print_params(nn.load_caffe, model=prototxt, weights=weights)
net = nn.load_caffe(model=prototxt, weights=weights)
else:
print_params(nn.load_caffe, model=prototxt)
net = nn.load_caffe(model=prototxt)
elif os.path.exists(modelfile_name+'.pb') is True:
tf_model = modelfile_name+'.pb'
inputs_outputs_file = 'inputs_outputs.txt'
if os.path.exists(inputs_outputs_file) is True:
args_dict = read_inputs_outputs_file(inputs_outputs_file)
print_params(nn.load_tensorflow, model=tf_model, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"],
predef_file=args_dict["predef_file"],
mean_values = args_dict["mean_values"],
std_values = args_dict["std_values"])
net = nn.load_tensorflow(model=tf_model, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"],
predef_file=args_dict["predef_file"],
mean_values=args_dict["mean_values"],
std_values=args_dict["std_values"]
)
else:
print("{} does not exist".format(inputs_outputs_file))
sys.exit(1)
elif os.path.exists(modelfile_name+'.tflite') is True:
lite_model = modelfile_name+'.tflite'
inputs_outputs_file = 'inputs_outputs.txt'
if os.path.exists(inputs_outputs_file) is True:
args_dict = read_inputs_outputs_file(inputs_outputs_file)
print_params(nn.load_tflite, model=lite_model, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"])
net = nn.load_tflite(model=lite_model, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"])
else:
net = nn.load_tflite(lite_model)
elif os.path.exists(modelfile_name+'.cfg') is True:
darknet_file = modelfile_name+'.cfg'
weights = modelfile_name+'.weights'
if os.path.exists(weights) is True:
print_params(nn.load_darknet, model=darknet_file, weights=weights)
net = nn.load_darknet(model=darknet_file, weights=weights)
else:
print("{} does not exist".format(weights))
sys.exit(1)
elif os.path.exists(modelfile_name+'.onnx') is True:
onnx_file = modelfile_name + '.onnx'
inputs_outputs_file = 'inputs_outputs.txt'
if os.path.exists(inputs_outputs_file) is True:
args_dict = read_inputs_outputs_file(inputs_outputs_file)
print_params(nn.load_onnx, model=onnx_file, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"],
input_dtype_list=args_dict["input_dtype_list"])
net = nn.load_onnx(model=onnx_file, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"],
input_dtype_list=args_dict["input_dtype_list"])
else:
net = nn.load_onnx(model=onnx_file)
elif os.path.exists(modelfile_name+'.pt') is True:
pt_file = modelfile_name + '.pt'
inputs_outputs_file = 'inputs_outputs.txt'
if os.path.exists(inputs_outputs_file) is True:
args_dict = read_inputs_outputs_file(inputs_outputs_file)
print_params(nn.load_pytorch_by_onnx_backend, model=pt_file, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"])
net = nn.load_pytorch_by_onnx_backend(model=pt_file, inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
size_with_batch=args_dict["size_with_batch"])
else:
net = nn.load_pytorch_by_onnx_backend(model=pt_file)
elif os.path.exists(modelfile_name+".h5") is True:
keras_file = modelfile_name+'.h5'
inputs_outputs_file = 'inputs_outputs.txt'
if os.path.exists(inputs_outputs_file) is True:
args_dict = read_inputs_outputs_file(inputs_outputs_file)
print_params(nn.load_keras, model=keras_file,
inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
convert_engine="Keras")
net = nn.load_keras(model=keras_file,
inputs=args_dict["inputs"],
input_size_list=args_dict["input_size_list"],
outputs=args_dict["outputs"],
convert_engine="Keras")
else:
net = nn.load_keras(model=keras_file)
else:
print("Cannot find model :{}".format(modelfile_name))
sys.exit(1)
if nn.is_quantize_model is True:
for tensor in net.tensors:
if tensor.quant_param is not None and tensor.quant_param.qtype == 'float16':
nn.is_quantize_model = False
break
if save:
output_model = modelfile_name + '.json'
output_data = modelfile_name + '.data'
nn.save_model(net, output_model)
nn.save_model_data(net, output_data)
if nn.is_quantize_model is True:
quantize_output = modelfile_name + '_asymu8' + '.quantize'
print("!!! It's a quant model. !!!")
print("!!! To suit the naming rule , rename to {}!!!".format(quantize_output))
nn.save_model_quantize(net, quantize_output)
return net, nn.is_quantize_model
def read_channel_mean_value_file(channel_mean_value_file, channel):
mean_scale = []
with open(channel_mean_value_file, 'r') as inter_file:
line = inter_file.readline().strip()
nums = line.split()
if len(nums) == 1 and nums[0] == '':
print("No data in the {}, Please enter the correct data.".format(channel_mean_value_file))
sys.exit(1)
else:
for num in nums:
mean_scale.append(float(num))
if len(mean_scale) == (channel + 1):
mean = mean_scale[0:channel]
scale_r = mean_scale[channel]
# The scale in inputmeta.yml is equal to 1/(the scale in channel_mean_value_file)
# the scale in channel_mean_value_file is the scale of origin platform
scale = [1.0 / scale_r] * channel
elif len(mean_scale) == (channel * 2):
mean = mean_scale[0:channel]
scale_r = mean_scale[channel:]
scale = [1.0 / s for s in scale_r]
else:
print("Please enter the correct data in channel_mean_value.txt file for model preprocess.")
sys.exit(1)
return mean, scale
def preprocess(net, modelfile_name, save=True):
nn = VSInn()
inputs_shape = []
inputs_lid = []
inputs_name = []
inputs_type = []
preprocess_dict = {}
inputs = net.get_input_layers(ign_variable=True)
for l in inputs:
if l.is_op('input'):
inputs_lid.append(l.lid)
preprocess_params = {}
shape = l.params.shape
inputs_shape.append(shape)
inputs_name.append(l.name)
inputs_type.append(l.params.type)
if shape[0] == 0:
shape[0] = 1
preprocess_params['shape'] = shape
fmt = net.get_org_platform_mode()
if fmt == 'nchw':
print("The default layout of your model is nchw, please note if it needs to changed!")
preprocess_params['reverse_channel'] = fmt == 'nchw'
if len(shape) == 4:
if fmt == 'nchw':
channel = shape[1]
else:
channel = shape[-1]
if channel == 3 or channel == 1 or channel == 4:
channel_mean_value_file = 'channel_mean_value.txt'
if os.path.exists(channel_mean_value_file) is True:
mean, scale = read_channel_mean_value_file(channel_mean_value_file, channel)
else:
mean = [0] * channel
scale = [1.0] * channel
preprocess_params['mean'] = mean
preprocess_params['scale'] = scale
else:
preprocess_params['scale'] = 1.0
preprocess_dict[l.name] = preprocess_params
num = len(inputs_shape)
if num == 1:
if os.path.exists('dataset.txt') is True:
nn.set_database(net, dataset_files='dataset.txt', dataset_type="TEXT")
else:
if os.path.exists("inputs") is False:
os.system("mkdir inputs")
input = np.random.random(inputs_shape[0]).astype(inputs_type[0])
shape = '_'.join(str(inputs_shape[0][i]) for i in range(len(inputs_shape[0])))
dataset_name = '{}_{}_{}.npy'.format(inputs_lid[0], shape, 0)
dataset_name = dataset_name.replace('@', '').replace(':', '_').replace('/', '_')
dataset_name = "./inputs/" + dataset_name
if os.path.exists(dataset_name) is False:
np.save(dataset_name, input)
nn.set_database(net, dataset_files=dataset_name, dataset_type='NPY')
preprocess_dict[inputs_name[0]]['reverse_channel'] = False
else:
dataset_files = []
for i in range(num):
if os.path.exists('dataset{}.txt'.format(i)) is True:
dataset_files.append('dataset{}.txt'.format(i))
dataset_type = "TEXT"
else:
if os.path.exists("inputs") is False:
os.system("mkdir inputs")
input = np.random.random(inputs_shape[i]).astype(inputs_type[i])
shape = '_'.join(str(inputs_shape[i][j]) for j in range(len(inputs_shape[i])))
dataset_name = '{}_shape_{}.npy'.format(inputs_lid[i], shape, i)
dataset_name = dataset_name.replace('@', '').replace(':', '_').replace('/', '_')
dataset_name = "./inputs/" + dataset_name
if os.path.exists(dataset_name) is False:
np.save(dataset_name, input)
dataset_files.append(dataset_name)
dataset_type = "NPY"
preprocess_dict[inputs_name[i]]['reverse_channel'] = False
nn.set_database(net, dataset_files=dataset_files, dataset_type=dataset_type)
# preprocess
nn.set_preprocess(net, preprocess_dict)
inputmeta_serialize = nn.get_inputmeta(net)
inputmeta_serialize['databases'][0]['ports'][0]['redirect_to_output'] = False
nn.set_inputmeta(net, inputmeta_serialize)
if save:
inputmeta_yml = modelfile_name + '_inputmeta.yml'
nn.save_model_inputmeta(net, inputmeta_yml)
return net
def postprocess(net, modelfile_name, save=True):
nn = VSInn()
acuity_postprocess_list = [
{'dump_results': {'file_type': 'TENSOR'}},
{'print_topn': {'topn': 5}},
]
nn.set_acuity_postprocess(net, acuity_postprocess_list)
app_postprocess_list = []
outputs = net.get_output_layers()
net.compute_shape()
for l in outputs:
if l.is_op('output'):
app_sublist = []
app_params = {}
add_postproc_node = False
dim_num = len(l.get_output().shape.dims)
perm = []
for i in range(dim_num):
perm.append(i)
app_params['add_postproc_node'] = add_postproc_node
app_params['perm'] = perm
app_params['force_float32'] = True
app_sublist.append(l.lid)
app_sublist.append([app_params])
app_postprocess_list.append(app_sublist)
nn.set_app_postprocess(net, app_postprocess_list, set_by_lid=True)
if save:
postprocess_file_yml = modelfile_name + '_postprocess_file.yml'
nn.save_model_outputmeta(net, postprocess_file_yml)
return net
def main():
options = ArgumentParser()
options.add_argument("model", type=str, help="Model directory")
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
#import
net, _ = importer(model_filename)
#prepocess
preprocess(net, model_filename)
#postprocess
postprocess(net, model_filename)
if __name__ == "__main__":
main()