Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler error in importing tflite #1284

Open
UrviZala opened this issue Dec 27, 2024 · 1 comment
Open

Compiler error in importing tflite #1284

UrviZala opened this issue Dec 27, 2024 · 1 comment

Comments

@UrviZala
Copy link

Describe the bug
---------- compile ----------
Simplify...
[ tflite skip ]
Set options...
Compiling...
Unhandled exception. System.NotImplementedException: The method or operation is not implemented.
at Nncase.Importer.TFLite.TFLiteImporter.VisitMatMul(Operator& op, Boolean isFullyConnected)
at Nncase.Importer.TFLite.TFLiteImporter.Visit(Operator& op)
at Nncase.Importer.TFLite.TFLiteImporter.ConvertOp()
at Nncase.BaseImporter.Import()
at Nncase.Importers.ImportTFLite(Stream tflite, CompileSession compileSession)
at Nncase.Compiler.Interop.CApi.CompilerImportTFLiteModule(IntPtr compilerHandle, IntPtr streamHandle)

To Reproduce
Run main code, model should be present in same folder.
Line contain
Uploading facenet_512.zip…
error is compiler.import_tflite(model_content, import_options)(line no.160)

Expected behavior
model should convert successfully from .tflite to .kmodel

Origin model and code
tflite model is attached and main code for python is

import nncase
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

import onnxruntime as rt
import onnx
import onnxsim
import os

def get_cosine(vec1, vec2):
"""
result compare
"""
return cosine_similarity(vec1.reshape(1, -1), vec2.reshape(1, -1))

def read_model_file(model_file):
"""
read model
"""
with open(model_file, 'rb') as f:
model_content = f.read()
return model_content

def parse_model_input_output(model_file):
"""
parse onnx model
"""
onnx_model = onnx.load(model_file)
input_all = [node.name for node in onnx_model.graph.input]
input_initializer = [node.name for node in onnx_model.graph.initializer]
input_names = list(set(input_all) - set(input_initializer))
input_tensors = [
node for node in onnx_model.graph.input if node.name in input_names]

# input
inputs = []
for _, e in enumerate(input_tensors):
    onnx_type = e.type.tensor_type
    input_dict = {}
    input_dict['name'] = e.name
    input_dict['dtype'] = onnx.mapping.TENSOR_TYPE_TO_NP_TYPE[onnx_type.elem_type]
    input_dict['shape'] = [i.dim_value for i in onnx_type.shape.dim]
    inputs.append(input_dict)

return onnx_model, inputs

def model_simplify(model_file):
"""
simplify model
"""
if model_file.split('.')[-1] == "onnx":
onnx_model, inputs = parse_model_input_output(model_file)
onnx_model = onnx.shape_inference.infer_shapes(onnx_model)
input_shapes = {}
for input in inputs:
input_shapes[input['name']] = input['shape']

    onnx_model, check = onnxsim.simplify(onnx_model, input_shapes=input_shapes)
    assert check, "Simplified ONNX model could not be validated"

    model_file = os.path.join(os.path.dirname(model_file), 'simplified.onnx')
    onnx.save_model(onnx_model, model_file)
    print("[ onnx done ]")
elif model_file.split('.')[-1] == "tflite":
    print("[ tflite skip ]")
else:
    raise Exception(f"Unsupported type {model_file.split('.')[-1]}")

return model_file

def run_kmodel(kmodel_path, input_data):
print("\n---------start run kmodel---------")
print("Load kmodel...")
model_sim = nncase.Simulator()
with open(kmodel_path, 'rb') as f:
model_sim.load_model(f.read())

print("Set input data...")
for i, p_d in enumerate(input_data):
    model_sim.set_input_tensor(i, nncase.RuntimeTensor.from_numpy(p_d))

print("Run...")
model_sim.run()

print("Get output result...")
all_result = []
for i in range(model_sim.outputs_size):
    result = model_sim.get_output_tensor(i).to_numpy()
    all_result.append(result)
print("----------------end-----------------")
return all_result

def compile_kmodel(model_path, dump_path, calib_data):
"""
Set compile options and ptq options.
Compile kmodel.
Dump the compile-time result to 'compile_options.dump_dir'
"""
print("\n---------- compile ----------")
print("Simplify...")
model_file = model_simplify(model_path)

print("Set options...")
# import_options
import_options = nncase.ImportOptions()

############################################
# You need to modify the parameters in the following code to fit your model.
############################################
# compile_options
compile_options = nncase.CompileOptions()
compile_options.target = "k230" #"cpu"
compile_options.dump_ir = True  # if False, will not dump the compile-time result.
compile_options.dump_asm = True
compile_options.dump_dir = dump_path
compile_options.input_file = ""

# preprocess args
compile_options.preprocess = True
if compile_options.preprocess:
    compile_options.input_type = "float32"
    compile_options.input_shape = [1,160,160,3]
    compile_options.input_range = [0,1]
    compile_options.input_layout = "NHWC"
    compile_options.swapRB = False
    compile_options.mean = [0,0,0]
    compile_options.std = [1,1,1]
    compile_options.letterbox_value = 0
    compile_options.output_layout = "NHWC"

# quantize options
ptq_options = nncase.PTQTensorOptions()
ptq_options.quant_type = "uint8" # datatype : "float32", "int8", "int16"
ptq_options.w_quant_type = "uint8"  # datatype : "float32", "int8", "int16"
ptq_options.calibrate_method = "NoClip" # "Kld"
ptq_options.finetune_weights_method = "NoFineTuneWeights"
ptq_options.dump_quant_error = False
ptq_options.dump_quant_error_symmetric_for_signed = False

# mix quantize options
# more details in docs/MixQuant.md
ptq_options.quant_scheme = ""
ptq_options.export_quant_scheme = False
ptq_options.export_weight_range_by_channel = False
############################################

ptq_options.samples_count = len(calib_data[0])
ptq_options.set_tensor_data(calib_data)

print("Compiling...")
compiler = nncase.Compiler(compile_options)
# import
model_content = read_model_file(model_file)
if model_path.split(".")[-1] == "onnx":
    compiler.import_onnx(model_content, import_options)
elif model_path.split(".")[-1] == "tflite":
    compiler.import_tflite(model_content, import_options)

compiler.use_ptq(ptq_options)

# compile
compiler.compile()
kmodel = compiler.gencode_tobytes()

# You can modify kmodel_path as needed. Pass the correct kmodel_path during inference.
kmodel_path = os.path.join(dump_path, "test.kmodel")
with open(kmodel_path, 'wb') as f:
    f.write(kmodel)
print("----------------end-----------------")
return kmodel_path

if name == "main":
# compile kmodel single input
model_path = "./facenet.tflite"
dump_path = "./tmp_onnx"

# The number of calibration sets is 2
calib_data = [[np.random.rand(1, 160, 160, 3).astype(np.float32), np.random.rand(1, 160, 160, 3).astype(np.float32)]]
kmodel_path = compile_kmodel(model_path, dump_path, calib_data)

# run kmodel(simulate)
kmodel_path = "./tmp_onnx/test.kmodel"
input_data = [np.random.rand(1, 160, 160, 3).astype(np.float32)]
# input_data[0].tofile(os.path.join(dump_path,"input_0.bin"))

result = run_kmodel(kmodel_path, input_data)

for idx, i in enumerate(result):
    print(i.shape)
    i.tofile(os.path.join(dump_path,"nncase_result_{}.bin".format(idx)))
    
onnx_model = model_path
_, input_info = parse_model_input_output(model_path)
onnx_sess = rt.InferenceSession(onnx_model)

input_dict = {}
for i, info in enumerate(input_info):
    print(info['shape'])
    input_dict[info["name"]] = input_data[i]

onnx_results = onnx_sess.run(None, input_dict)
for index, (i, j) in enumerate(zip(onnx_results, result)):
    print("result {} cosine = ".format(index), get_cosine(i, j))

Environment (please complete the following information):

  • OS: Windows 10 Pro
  • nncase version: 2.9.0
  • Python Version: 3.10.11

Additional context
Add any other context about the problem here.

@curioyang
Copy link
Member

I can't get the Zip file. Maybe you need to upload it again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants