refactor(netrans): 优化api结构

This commit is contained in:
xujiao 2025-11-21 15:53:14 +08:00
parent 14a433dc43
commit fa5dfc8817
28 changed files with 26 additions and 1611 deletions

View File

@ -1,113 +0,0 @@
#!/usr/bin/env python3
from argparse import ArgumentParser
import os
import sys
from quantize_types import QuantizerType
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
def load_net(model_filename, quantized, 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"
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 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:
print('{} does not exist'.format(model_quantize))
sys.exit(1)
return net
def dump(net, model_filename, quantized='asymu8', use_hybrid=False):
nn = VSInn()
if not use_hybrid:
quantize_file = model_filename + '_' + quantized + ".quantize"
model = model_filename + ".json"
output_dir = 'dump/{}_{}/'.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 = 'dump/{}_{}/'.format(model_filename, quantized + "_hy")
if quantized != "float32":
print_params(nn.dump, model=model, data=model_filename + ".data", quantize=quantize_file,
with_input_meta=model_filename + "_inputmeta.yml", output_path=output_dir)
else:
print_params(nn.dump, model=model, data=model_filename + ".data",
with_input_meta=model_filename + "_inputmeta.yml", output_path=output_dir)
nn.dump(net, output_path=output_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("--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
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 net
net = load_net(model_filename, quantized, use_hybrid)
#dump
dump(net, model_filename, quantized, use_hybrid)
if __name__ == "__main__":
main()

View File

@ -1,217 +0,0 @@
#!/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()

View File

@ -1,157 +0,0 @@
#!/usr/bin/env python3
from argparse import ArgumentParser
import os
import sys
from quantize_types import QuantizerType
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, 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:
print('{} does not exist'.format(model_quantize))
sys.exit(1)
return net
def inference(net, model_filename, quantized='asymu8', iterations=1, use_hybrid=False):
nn = VSInn()
if not use_hybrid:
quantize_file = model_filename + '_' + quantized + ".quantize"
model = model_filename + ".json"
output_dir = 'wksp/{}_{}/golden/'.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/{}_{}/golden/'.format(model_filename, quantized + "_hy")
if quantized != "float32":
print_params(nn.inference, model=model, data=model_filename + ".data", quantize=quantize_file,
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=post, output_path=output_dir,
iterations=iterations)
else:
print_params(nn.inference, model=model, data=model_filename + ".data", quantize=quantize_file,
with_input_meta=model_filename + "_inputmeta.yml", postprocess_file=post, output_path=output_dir,
iterations=iterations)
tensors = nn.inference(net, output_path=output_dir, iterations=iterations)
golden_unified = output_dir + "unified"
if os.path.exists(golden_unified) is False:
os.system("mkdir {}".format(golden_unified))
input_layers = net.get_input_layers(ign_variable=True)
inputs = [l.get_output().url for l in input_layers]
output_layers = net.get_output_layers()
outputs = [l.get_output().url for l in output_layers]
for url, tensor in tensors:
if url in inputs:
input_name = url.replace('@', '').replace(':', '_').replace('/', '_')
shape = tensor.shape
for j in range(len(shape)):
input_name = input_name + "_" + str(shape[j])
input_name = "iter_{}_".format(iterations - 1) + input_name + ".tensor"
if not use_hybrid:
wksp_dir = 'wksp/{}_{}/'.format(model_filename, quantized)
else:
wksp_dir = 'wksp/{}_{}/'.format(model_filename, quantized + "_hy")
os.system("mv {}/{} {}".format(output_dir, input_name, wksp_dir))
print("move {} to {}".format(input_name, wksp_dir))
elif url in outputs:
output_name = url.replace('@', '').replace(':', '_').replace('/', '_')
shape = tensor.shape
for j in range(len(shape)):
output_name = output_name + "_" + str(shape[j])
output_name = "iter_{}_".format(iterations - 1) + output_name + ".tensor"
os.system("mv {}/{} {}/".format(output_dir, output_name, golden_unified))
print("move {} to {}".format(output_name, golden_unified))
# remove the file .qnt.tensor
files = os.listdir(output_dir)
for file in files:
if file.endswith(".qnt.tensor"):
os.remove(os.path.join(os.path.abspath(output_dir), file))
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("--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
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 net
net = load_net(model_filename, quantized, use_hybrid)
#inference
inference(net, model_filename, quantized, iterations, use_hybrid)
if __name__ == "__main__":
main()

View File

@ -1,362 +0,0 @@
#!/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 = True
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()

9
src/netrans/__init__.py Normal file
View File

@ -0,0 +1,9 @@
"""
Netrans - PNNA AI 编译器
模型转换和量化工具包
"""
from .netrans import Netrans
__version__ = "6.42.3"
__all__ = ["Netrans"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +1,8 @@
#!/usr/bin/env python3
from argparse import ArgumentParser
from utils import *
from .utils import *
from ruamel.yaml import YAML
from quantize_types import QuantizerType
from .quantize_types import QuantizerType
def update_preprocess(model_name, qtype):
"""

View File

@ -2,9 +2,9 @@
from argparse import ArgumentParser
import os
import sys
from quantize_types import QuantizerType
from utils import *
from measure import *
from .quantize_types import QuantizerType
from .utils import *
from .measure import *
import importlib
try:

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
from utils import *
from .utils import *
from argparse import ArgumentParser
import numpy as np
import os

View File

@ -9,16 +9,15 @@ from typing import Optional, Callable, Any
from dataclasses import dataclass
from functools import wraps
from utils import get_modelfile_name, chdir
from quantize_types import QuantizerType
from importer import importer, preprocess, postprocess
from quantize import quantize
from export_nbg import export_nbg as export_nbg_acuity
from add_prepost_to_graph import update_preprocess, update_postprocess
from quantize_hybrid import quantize as quantize_hybrid
# 导入必要的模块
from .utils import get_modelfile_name, chdir
from .quantize_types import QuantizerType
from .importer import importer, preprocess, postprocess
from .quantize import quantize
from .export_nbg import export_nbg as export_nbg_acuity
from .add_prepost_to_graph import update_preprocess, update_postprocess
# quantize_hybrid 可选,如果不需要可以注释掉
# from .quantize_hybrid import quantize as quantize_hybrid
import os
from functools import wraps

View File

@ -1,9 +1,9 @@
#!/usr/bin/env python3
from utils import *
from .utils import *
from argparse import ArgumentParser
import os
import sys
from quantize_types import QuantizerType
from .quantize_types import QuantizerType
import importlib
try:

View File

@ -1,213 +0,0 @@
#!/usr/bin/env python3
# This script for experiental use only
from __future__ import division
from argparse import ArgumentParser
import os
import sys
import pandas as pd
import openpyxl
from openpyxl.styles import Alignment
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
def read_hw_config_file(hw_config_file):
hw_config = {}
with open(hw_config_file, 'r') as f:
for conf in f.readlines():
if not conf.strip():
continue
conf = conf.strip("\'").strip('\n').split(":")
hw_config[conf[0].strip()] = conf[1].strip()
return hw_config
def cal_layer_param_total(param):
nums = param.strip("[").strip("]").split(",")
total = 0
for num in nums:
total = total + int(num)
return total, len(nums)
def cal_mac_total_util(args, mac_total, core_count, cycle_total):
quantized = args.quantized
if "symi16" == quantized or "dfpi16" == quantized:
const = 48
elif "fp16" == quantized:
const = 96
else:
const = 192
mac_util_total = round(mac_total / (core_count * const * cycle_total) * 100, 2)
return mac_util_total
def profile(args):
model_filename = args.model
quantized = args.quantized
hw_config_file = args.hw_config
viv_sdk = (None if args.viv_sdk is None else args.viv_sdk)
nn = VSInn()
net = nn.create_net()
model = model_filename + ".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)
else:
print("{} file does not exists.".format(postprocess))
sys.exit(1)
if quantized != "float32":
model_quantize = model_filename + '_' + quantized + ".quantize"
if os.path.exists(model_quantize) is True:
nn.load_model_quantize(net, model_quantize)
else:
print('{} does not exist'.format(model_quantize))
sys.exit(1)
hw_config = read_hw_config_file(hw_config_file)
output_dir = 'wksp/{}_{}/model'.format(model_filename, quantized)
output_dir = os.path.join(output_dir, os.path.split(output_dir)[1])
print_params(nn.profile, model=model_filename + ".json", data=model_filename + ".data",
quantize=model_filename + '_' + quantized + '.quantize',
with_input_meta=model_filename + "_inputmeta.yml", hw_config=hw_config, output_path=output_dir, viv_sdk=viv_sdk)
results = nn.profile(net, hw_config, output_path=output_dir, viv_sdk=viv_sdk)
layers = net.get_layers()
output_dir = os.path.split(output_dir)[0]
profile_log_file = os.path.join(output_dir, "profile_log_{}.xlsx".format(model_filename))
log = []
header = ["UID", "Cycle", "Hardware", "DDRReadBW", "DDRWriteBW", "AXISRAMReadBW", "AXISRAMWriteBW", "Kernel Read BW", "In Image Read BW",
"MAC", "out_shape"]
cycle_total = 0
ddr_read_bw_total = 0
ddr_write_bw_total = 0
axi_read_bw_total = 0
axi_write_bw_total = 0
mac_total = 0
for lid, l in results['Layers'].items():
param = l['parameters']
if len(param) > 1:
share_uids = param["share_uids"].strip("[").strip("]")
if len(share_uids) == 0:
continue
uid = layers[lid].uid
cycle = param['cycle'].strip("[").strip("]")
cycle_layer_total, core_count = cal_layer_param_total(cycle)
cycle_total = cycle_total + cycle_layer_total
hardware = param['HARDWARE']
ddr_read_bw = param['DDRReadBW'].strip("[").strip("]")
ddr_read_bw_layer_total, _ = cal_layer_param_total(ddr_read_bw)
ddr_read_bw_total += ddr_read_bw_total
ddr_write_bw = param['DDRWriteBW'].strip("[").strip("]")
ddr_write_bw_layer_total, _ = cal_layer_param_total(ddr_write_bw)
ddr_write_bw_total += ddr_write_bw_layer_total
axi_read_bw = param['AXISRAMReadBW'].strip("[").strip("]")
axi_read_bw_layer_total, _ = cal_layer_param_total(axi_read_bw)
axi_read_bw_total += axi_read_bw_total
axi_write_bw = param['AXISRAMWriteBW'].strip("[").strip("]")
axi_write_bw_layer_total, _ = cal_layer_param_total(axi_write_bw)
axi_write_bw_total += axi_write_bw_layer_total
kernel_read_bw = param['kernelReadBW'].strip("[").strip("]")
inImage_read_bw = param['inImageReadBW'].strip("[").strip("]")
mac = param['MAC'].strip("[").strip("]")
mac_layer_total, _ = cal_layer_param_total(mac)
mac_total = mac_total + mac_layer_total
out_shape = param['output_shapes']
l_log = [uid, cycle, hardware, ddr_read_bw, ddr_write_bw, axi_read_bw, axi_write_bw, kernel_read_bw,
inImage_read_bw, mac, out_shape]
if "MACUtil" in param.keys():
macUtil = param['MACUtil']
if "MACUtil" not in header:
header.insert(len(header) - 1, "MACUtil")
l_log.insert(len(l_log) - 1, macUtil)
log.append(l_log)
fps = round(1e9 / cycle_total, 2)
mac_util_total = cal_mac_total_util(args, mac_total, core_count, cycle_total)
profile_stats_info = "Profile Stats Info"
profile_info_header = ["MAC", "CoreCount", "CycleCount", "DDRReadBW(Bytes)", "DDRWriteBW(Bytes)", "TotalBW(Bytes)",
"AXISRAMReadBW(Bytes)", "AXISRAMWriteBW(Bytes)", "fps(@1G)", "MAC_Util"]
profile_info = [mac_total, core_count, cycle_total, ddr_read_bw_total, ddr_write_bw_total,
ddr_read_bw_total + ddr_write_bw_total, axi_read_bw_total, axi_write_bw_total, fps, mac_util_total]
log = pd.DataFrame(columns=header, data=log)
with pd.ExcelWriter(profile_log_file, engine='openpyxl') as writer:
log.to_excel(writer, index=False, sheet_name='sheet1', startcol=0, startrow=4)
wb = openpyxl.load_workbook(profile_log_file, data_only=True)
ws = wb['sheet1']
ws.merge_cells(start_row=1, start_column=2, end_row=1, end_column=len(profile_info_header)+1)
ws.cell(1, 2).value = profile_stats_info
ws.cell(1, 2).alignment = Alignment(vertical='center', horizontal='center')
start_col = 2
for i in range(len(profile_info_header)):
ws.cell(2, start_col + i).value = profile_info_header[i]
ws.cell(3, start_col + i).value = profile_info[i]
wb.save(profile_log_file)
if os.path.exists(output_dir) is True:
profile_dir = 'wksp/{}_{}/profile'.format(model_filename, quantized)
if os.path.exists(profile_dir) is True:
os.system("rm -rf {}".format(profile_dir))
os.rename(output_dir, profile_dir)
os.system("mv ./*.profile.json {}".format(profile_dir))
def main():
options = ArgumentParser()
options.add_argument("model", type=str, help="Model directory")
options.add_argument("quantized", type=str,
help="Quantization type",
choices=['float32', 'asymi4', 'symi4', 'pcqsymi4', 'asymu4', 'asymi8', 'symi8',
'pcqi8', 'asymu8', 'symi16', 'dfpi16', 'fp16', 'qbfp16', 'Ai16Wi8', 'Ai16Wpcqi8', 'Ai16Wpcqi8', 'Ai8Wpcqi4'])
options.add_argument("hw_config", type=str,
help="A txt file that describes the hardware configuration. Its contents are as follows:"
"VSIMULATOR_CONFIG: VIP9000NANODI_PID0X10000020"
"NN_EXT_DDR_READ_BW_LIMIT: 16"
"NN_EXT_DDR_WRITE_BW_LIMIT: 16"
"NN_EXT_VIP_SRAM_SIZE: 262144")
options.add_argument("--viv_sdk", type=str, required=False,
help="The file path of the directory that contains the binary SDK of VSimulator. "
"During the execution, VSimulator generates NBG files. For example, the file path may be "
"'/home/xxx/Verisilicon/VivanteIDEx.x.x/*cmdtools' if VivanteIDE is installed.")
args = options.parse_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)
args.model = model_filename
#export
profile(args)
if __name__ == "__main__":
main()

View File

@ -1,173 +0,0 @@
#!/usr/bin/env python3
from utils import *
from argparse import ArgumentParser
import collections
import os
import sys
import quantize as quant
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
import acuitylib as acuity
# get lids in sub-model only
def extract_sub_graph_layer(net, cust_qnt_layers):
with open(cust_qnt_layers, 'r') as inter_file:
lines = inter_file.readlines()
sub_graph_lids = []
for line in lines:
line = line.strip()
if line == '':
continue
if line.startswith("--inputs"):
inputs = line.split()[1].strip('\"').strip('\'').split("#")
outputs = line.split()[-1].strip("\'").strip("\"").split("#")
assert len(inputs) == len(outputs)
for i in range(len(inputs)):
sub_graph_lids.append(
acuity.utils.extract_subgraph_layers_id(net, inputs[i].split(","), outputs[i].split(",")))
else:
sub_graph_lids.append(line.strip().strip('\"').strip('\''))
hybrid_layers = []
for lid in sub_graph_lids:
if isinstance(lid, list):
for l in lid:
hybrid_layers.append(l)
else:
hybrid_layers.append(lid)
return hybrid_layers
def hybrid_i16_dict(hybrid_layers):
hybrid_i16_layer = collections.OrderedDict()
for l in hybrid_layers:
hybrid_i16_layer[l] = "dynamic_fixed_point-i16"
return hybrid_i16_layer
def hybrid_fp32_dict(hybrid_layers):
hybrid_fp32_layer = collections.OrderedDict()
for l in hybrid_layers:
hybrid_fp32_layer[l] = "float32"
return hybrid_fp32_layer
def quantize(args):
model_filename = args.model
quantized = args.quantized
iterations = args.iterations
algorithm = args.algorithm
if "symi16x8" == quantized:
hybrid_qtype = "float32"
else:
hybrid_qtype = args.hybrid_qtype
compute_entropy = args.entropy
cust_qnt_layers = args.cust_qnt_layers
algorithms = ["normal", "kl_divergence", "moving_average", "auto"]
quantized_output = model_filename + '_' + quantized + '_hy.quantize'
if os.path.exists(quantized_output) is True:
print("delete the {}".format(quantized_output))
os.system("rm -rf {}".format(quantized_output))
nn = VSInn()
net = nn.create_net()
model = model_filename + ".json"
data = model_filename + ".data"
inputmeta = model_filename + "_inputmeta.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)
nn.set_device(device='CPU')
quantized_net = quant.quantize(net=net, model_filename=model_filename, quantized=quantized,
iterations=iterations, compute_entropy=compute_entropy)
if cust_qnt_layers is not None and hybrid_qtype is not None:
if os.path.exists(cust_qnt_layers):
hybrid_layers = extract_sub_graph_layer(net, cust_qnt_layers)
if hybrid_qtype == 'dfpi16':
customized_quantize_layers = hybrid_i16_dict(hybrid_layers)
elif hybrid_qtype == 'float32':
customized_quantize_layers = hybrid_fp32_dict(hybrid_layers)
quantized_net.tensor_mgr.quantize_tab.customized_quantize_layers = customized_quantize_layers
print_params(nn.quantize, model=model_filename + ".json", data=model_filename + ".data",
quantize=model_filename + '_' + quantized + '.quantize', with_input_meta=model_filename + "_inputmeta.yml",
quantizer="dynamic_fixed_point", qtype="int16", algorithm=algorithms[algorithm], hybrid=True, iterations=1)
quantized_net = nn.quantize(quantized_net, quantizer="dynamic_fixed_point", qtype="int16",
algorithm=algorithms[algorithm], hybrid=True, iterations=iterations)
else:
print("Please enter the layer names in json that you want to quantize to dfpi16.")
sys.exit(1)
model_file_name = quantized_output + '.json'
nn.save_model(quantized_net, model_file_name)
nn.save_model_quantize(quantized_net, quantized_output)
def main():
options = ArgumentParser()
options.add_argument("model", type=str, help="Model directory")
options.add_argument("quantized", type=str,
help="Hybrid quantization type",
choices=['asymi8', 'symi8', 'pcqi8', 'asymu8', 'Ai16Wi8'])
options.add_argument("--algorithm", type=int,
help="Quantization algotithm. The corresponding relationship between numbers and algorithms is as follows:"
"[0: normal, 1:kl_divergence, 2:moving_average, 3:auto])",
default=1, choices=[0, 1, 2, 3])
options.add_argument("--iterations", type=int, help="Running iterations.", default=1)
options.add_argument("--entropy", action="store_true", help="Calculate the entropy of each layer.")
options.add_argument("--hybrid_qtype", type=str,
help="The choices of hybrid quantization type.",
choices=['dfpi16', 'float32'], default="dfpi16")
options.add_argument("--cust_qnt_layers", type=str, required=False,
help="The file that contains the layer names that you want to quantized to dfpi16."
"It supports the two formats,"
"one is that enter the input names and output names od the subgraph. such as "
"--inputs \'Conv_Conv_178_217,Conv_Conv_178_219#Input_1\' --outputs \'output1,utput0#output2\'"
"--inputs the input names of subgraph in json. "
"The input names of the same subgraph are separated with commas. "
"Input names between different subgraph are separated with hashtags."
"--outputs the output names of subgraph in json."
"The output names of the same subgraph are separated with commas."
"Output names between different subgraph are separated with hashtags."
"Other is that enter the layer name in json of each layer that you want to quantized to dfpi16. Put only one layer name per row."
)
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)
args.model = model_filename
#quantize
quantize(args)
if __name__ == "__main__":
main()

View File

@ -1,114 +0,0 @@
# -*- coding: utf-8 -*-
import os
from pathlib import Path
from setuptools import setup, find_packages
# 把 build_src 加入临时路径,方便收集顶层脚本
BASE = Path(__file__).parent
SRC_DIR = BASE / "build_src"
os.sys.path.insert(0, str(SRC_DIR))
# 1. 收集 acuitylib 包(含所有 .so 与子目录)
acuitylib_packages = find_packages(
where=str(SRC_DIR),
include=["acuitylib", "acuitylib.*"]
)
# 2. 收集顶层脚本 -> 打包成 netrans 包
# 每个 .py 文件对应一个模块,用户 import netrans.dump 即可
netrans_modules = [
"add_prepost_to_graph",
"dump",
"export_nbg",
"export",
"importer",
"inference",
"load",
"measure",
"netrans",
"profiler",
"quantize_hybrid",
"quantize",
"quantize_types",
"summary",
"utils"
]
# [f"netrans.{f.stem}" for f in SRC_DIR.glob("*.py")
# ]
# 3. 收集所有 .so 文件,作为 package_data
so_files = []
for so in (SRC_DIR / "acuitylib").rglob("*.so"):
so_files.append(str(so.relative_to(SRC_DIR / "acuitylib")))
setup(
name="Netrans",
version="0.1.0",
description="Netrans inference SDK",
# long_description=(BASE / "README.md").read_text(encoding="utf-8"),
# long_description_content_type="text/markdown",
author="Your Name",
author_email="you@example.com",
url="https://github.com/yourname/Netrans",
license="Proprietary", # 按需修改
python_requires=">=3.8",
# 关键:告诉 setuptools 去哪里找包
package_dir={
"": "build_src", # 所有包都在 build_src 下
},
packages=acuitylib_packages ,#+ ["netrans"], # 把 netrans 空包也加进去
py_modules=netrans_modules, # 顶层脚本变成 netrans.xxx
py_modules = [
"add_prepost_to_graph",
"dump",
"export_nbg",
"export",
"importer",
"inference",
"load",
"measure",
"netrans",
"profiler",
"quantize_hybrid",
"quantize",
"quantize_types",
"summary",
"utils"
],# The list of strings you provided is assigning module names to the `py_modules`
# attribute in the `setup()` function call. This attribute specifies individual
# module names that should be included in the distribution package as standalone
# modules.
[
"add_prepost_to_graph",
"dump",
"export_nbg",
"export",
"importer",
"inference",
"load",
"measure",
"netrans",
"profiler",
"quantize_hybrid",
"quantize",
"quantize_types",
"summary",
"utils"
],
# 把 .so 打进 acuitylib 包里
package_data={
"acuitylib": so_files,
},
include_package_data=True,
zip_safe=False, # .so 需要文件系统路径
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.8",
],
)

View File

@ -1,138 +0,0 @@
#!/usr/bin/env python3
import sys
import ruamel.yaml as yaml
import os
import numpy as np
from scipy import spatial
from argparse import ArgumentParser
from collections import OrderedDict
from quantize_types import QuantizerType
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
def cal_cosine(tensor1, tensor2):
sim = 1 - spatial.distance.cosine(tensor1.flatten(), tensor2.flatten())
return sim
def summary(model_filename, quantized, iterations=1):
quantized_format = QuantizerType.get_options()
if quantized not in quantized_format:
print("Please enter the correct quantization format.")
print(list(quantized_format))
sys.exit(1)
model = model_filename + ".json"
data = model_filename + ".data"
inputmeta = model_filename + "_inputmeta.yml"
postprocess = model_filename + "_postprocess_file.yml"
model_quantize = model_filename + '_' + quantized + ".quantize"
with open(model_quantize) as f:
quantize_dict = yaml.load(f)
quant_tmpdir = model_filename + '_' + quantized + '_tmp.quantize'
quant_output_dir = "wksp/{}_{}/golden/unified".format(model_filename, quantized)
fp32_output_dir = "wksp/{}_float32/golden/".format(model_filename)
new_quantize_dict = {}
new_quantize_dict['version'] = 2
new_quantize_dict['customized_quantize_layers'] = {}
result = {}
for quant_params in list(quantize_dict.keys()):
quant_param_dict = quantize_dict[quant_params]
if isinstance(quant_param_dict, dict):
new_quantize_dict[quant_params] = {}
quant_param_dict_key_dict = OrderedDict()
for quant_url in list(quant_param_dict.keys()):
quant_lid = quant_url.split(":")
if quant_lid[0] not in quant_param_dict_key_dict.keys():
quant_param_dict_key_dict[quant_lid[0]] = []
quant_param_dict_key_dict[quant_lid[0]].append(quant_lid[1])
for quant_lid in list(quant_param_dict_key_dict.keys()):
vals = quant_param_dict_key_dict[quant_lid]
for port in vals:
quant_key = quant_lid + ":" + port
new_quantize_dict[quant_params][quant_key] = quant_param_dict[quant_key]
with open(quant_tmpdir, 'w') as outfile:
yaml.dump(new_quantize_dict, outfile, default_flow_style=False)
# new_quantize_dict[quant_params] = {}
nn = VSInn()
net = nn.create_net()
nn.load_model(net, model)
nn.load_model_data(net, data)
nn.load_model_inputmeta(net, inputmeta)
nn.load_model_quantize(net, quant_tmpdir)
nn.load_model_outputmeta(net, postprocess)
tensors = nn.inference(net, output_path=quant_output_dir, iterations=iterations)
# postprocess + accuracy test
accuracy_all = 0
output_layers = net.get_output_layers()
outputs = [l.lid for l in output_layers]
for i in range(0, iterations):
gt_tensor = []
quant_tensor = []
for url, tensor in tensors:
for lid in outputs:
if lid in url:
output_name = url.replace('@', '').replace(':', '_').replace('/', '_')
shape = tensor.shape
for j in range(len(shape)):
output_name = output_name + "_" + str(shape[j])
output_name = "iter_" + str(i) + "_" + output_name + ".tensor"
if i == (iterations - 1):
gt_tensor.append(np.loadtxt(os.path.join(fp32_output_dir + "unified", output_name)))
else:
gt_tensor.append(np.loadtxt(os.path.join(fp32_output_dir, output_name)))
quant_tensor.append(np.loadtxt(os.path.join(quant_output_dir, output_name)))
gt_tensor = np.concatenate(gt_tensor, 0)
quant_tensor = np.concatenate(quant_tensor, 0)
accuracy = cal_cosine(gt_tensor, quant_tensor)
accuracy_all += accuracy
# print(quant_tmpdir,'ave psnr:',psnr_all/100)
ave_acc = accuracy_all / iterations
print('quant layers:', new_quantize_dict[quant_params].keys())
print('ave cosine sim:', quant_lid, ave_acc)
result[quant_lid] = float(ave_acc)
print('result', result)
result_dir = 'result_' + str(iterations) + '.yaml'
result = OrderedDict(sorted(result.items(), key=lambda kv: kv[1], reverse=True))
with open(result_dir, 'w', encoding='utf8') as outfile2:
yaml.dump(result, outfile2, Dumper=yaml.RoundTripDumper, default_flow_style=False)
def main():
options = ArgumentParser()
options.add_argument("model", type=str, help="Model directory")
options.add_argument("quantized", type=str, help="Quantization type, including float, " + ', '.join(list(QuantizerType.get_options()))
+ ", \'float\' means not quantized.")
options.add_argument("--iterations", type=int, required=False,
help="Iteration number",
default=1)
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
summary(model_filename, quantized, iterations)
if __name__ == '__main__':
main()

View File

@ -1,106 +0,0 @@
#!/usr/bin/env python3
from quantize_types import QuantizerType
from importer import *
from quantize import *
from export import *
from inference import *
from measure import *
from utils import *
from argparse import ArgumentParser
import os
import sys
import importlib
try:
importlib.import_module("acuitylib")
except:
ACUITY_PATH = os.environ['ACUITY_PATH']
sys.path.append(ACUITY_PATH)
def parse_args():
options = ArgumentParser()
options.add_argument("model", type=str, help="Model directory")
options.add_argument("--quantized", type=str, required=False, default="asymu8", help="Quantization type, including float32, " + ', '.join(list(QuantizerType.get_options()))
+ ", \'float32\' means not quantized.")
options.add_argument("--algorithm", type=int,
help="Quantization algotithm. The corresponding relationship between numbers and algorithms is as follows:"
"[0: normal, 1:kl_divergence, 2:moving_average, 3:auto])",
default=1, choices=[0, 1, 2, 3])
options.add_argument("--iterations", type=int, help="Running iterations.", default=1)
options.add_argument("--entropy", action="store_true", help="Compute tensor entropy.")
options.add_argument("--mle", action="store_true", help="Minimize per layer error")
options.add_argument("--save", action="store_true", help="Save the intermediate file")
args = options.parse_args()
return args
def main():
args = 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
algorithm = args.algorithm
iterations = args.iterations
compute_entropy = args.entropy
minimize_layer_error = args.mle
save = args.save
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)
#import
net, is_quantize_model = importer(model_filename, save=save)
# pre-process
net = preprocess(net, model_filename, save=save)
# postprocess
net = postprocess(net, model_filename, save=save)
if is_quantize_model is False:
if quantized == 'float32':
net_qnt = net
else:
# quantize
net_qnt = quantize(net=net,
model_filename=model_filename,
quantized=quantized,
algorithm=algorithm,
iterations=iterations,
compute_entropy=compute_entropy,
minimize_layer_error=minimize_layer_error,
save=save)
else:
net_qnt = net
quantized = 'asymu8'
# export
export(net=net_qnt,
model_filename=model_filename,
quantized=quantized)
# inference
inference(net=net_qnt,
model_filename=model_filename,
quantized=quantized,
iterations=iterations)
# measure
measure(net=net_qnt, model_filename=model_filename, quantized=quantized)
# generate execution script
generate_exe_script(net=net_qnt, model_filename=model_filename, quantized=quantized, iterations=iterations)
# generate criterion.json
generate_criterion_json(net=net_qnt, model_filename=model_filename, quantized=quantized, iterations=iterations)
if __name__=="__main__":
main()