kendryte / nncase

Open deep learning compiler stack for Kendryte AI accelerators ✨
Apache License 2.0
747 stars 181 forks source link

可以提供一下动态shape真实能用的例子吗 #1261

Closed willdla closed 1 week ago

willdla commented 1 week ago

Describe the bug 非常痛苦 动态shape根本转不出来

To Reproduce

import nncase
import numpy as np
import onnx
import onnxsim

# from nncase_base_func import model_simplify, read_model_file, parse_model_input_output

def parse_model_input_output(model_file):
    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 if i.dim_value != 0 else d) for i, d in zip(
            onnx_type.shape.dim, [1, 3, 224, 224])]
        inputs.append(input_dict)

    return onnx_model, inputs

def onnx_simplify(model_file, dump_dir):
    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(dump_dir, 'simplified.onnx')
    onnx.save_model(onnx_model, model_file)
    return model_file

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

def compile_asr_kmodel(model_path, dump_path, calib_data):
    print("\n----------   Compiling ASR model    ----------")
    print("Simplifying ONNX model...")
    # model_file = onnx_simplify(model_path, dump_path)

    print("Setting options...")
    import_options = nncase.ImportOptions()
    # import_options.input_shape = None

    compile_options = nncase.CompileOptions()
    compile_options.target = "k230"
    compile_options.dump_ir = True
    compile_options.dump_asm = True
    compile_options.dump_dir = dump_path

    # Configure ShapeBucket options for dynamic shape
    shape_bucket_options = nncase.ShapeBucketOptions()
    shape_bucket_options.shape_bucket_enable = True
    shape_bucket_options.shape_bucket_range_info = {"input_height": [1, 128]}
    shape_bucket_options.shape_bucket_segments_count = 1
    shape_bucket_options.shape_bucket_fix_var_map = {}
    compile_options.shape_bucket_options = shape_bucket_options   

    ptq_options = nncase.PTQTensorOptions()
    ptq_options.quant_type = "uint8"
    ptq_options.w_quant_type = "uint8"
    ptq_options.calibrate_method = "Kld"
    ptq_options.finetune_weights_method = "NoFineTuneWeights"
    ptq_options.samples_count = len(calib_data[0])
    ptq_options.set_tensor_data(calib_data)

    print("Compiling...")
    compiler = nncase.Compiler(compile_options)

    model_content = read_model_file(model_path)
    compiler.import_onnx(model_content, import_options)
    compiler.use_ptq(ptq_options)

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

    kmodel_path = f"{dump_path}/asr_model_int8.kmodel"
    with open(kmodel_path, 'wb') as f:
        f.write(kmodel)
    print(f"Compiled kmodel saved to: {kmodel_path}")
    print("----------------end-----------------")
    return kmodel_path

def generate_calibration_data(model_path, num_samples=100, vocab_size=5000):
    _, input_info = parse_model_input_output(model_path)
    calib_data = []

    for info in input_info:
        shape = info['shape']
        dtype = info['dtype']

        samples = []
        for _ in range(num_samples):
            if 'speech' in info['name']:
                seq_len = np.random.randint(1, 1025)
                sample = np.random.rand(1, seq_len, 80).astype(dtype)
            elif 'text' in info['name']:
                sample = np.random.randint(0, vocab_size, (1, 4)).astype(dtype)
            else:
                sample = np.random.rand(*shape).astype(dtype)

            samples.append(sample)

        calib_data.append(samples)

    return calib_data

if __name__ == "__main__":
    model_path = "conv_model.onnx"
    dump_path = "dump"

    # Generate calibration data
    calib_data = generate_calibration_data(model_path)

    # Compile the model
    kmodel_path = compile_asr_kmodel(model_path, dump_path, calib_data)
    print(f"ASR model successfully converted to int8 kmodel: {kmodel_path}")

Expected behavior 转不出来

Origin model and code conv_model.onnx.zip

Environment (please complete the following information):

Additional context

willdla commented 1 week ago
image

群管理回复只支持matmul

only matmul and no other op type is supported