SenseVoiceSmall-RKNN2 / convert_rknn.py
happyme531's picture
Upload 9 files
8d28ba8 verified
#!/usr/bin/env python
# coding: utf-8
import os
from rknn.api import RKNN
from math import exp
from sys import exit
import argparse
import onnxscript
from onnxscript.rewriter import pattern
import onnx.numpy_helper as onh
import numpy as np
import onnx
import onnxruntime as ort
from rknn.utils import onnx_edit
os.chdir(os.path.dirname(os.path.abspath(__file__)))
speech_length = 171
def convert_encoder():
rknn = RKNN(verbose=True)
ONNX_MODEL=f"sense-voice-encoder.onnx"
RKNN_MODEL=ONNX_MODEL.replace(".onnx",".rknn")
DATASET="dataset.txt"
QUANTIZE=False
#开局先给我来个大惊喜,rknn做第一步常量折叠的时候就会在这个子图里报错,所以要单独拿出来先跑一遍
#然后把这个子图的输出结果保存下来喂给rknn
onnx.utils.extract_model(ONNX_MODEL, "extract_model.onnx", ['speech_lengths'], ['/make_pad_mask/Cast_2_output_0'])
sess = ort.InferenceSession("extract_model.onnx", providers=['CPUExecutionProvider'])
extract_result = sess.run(None, {"speech_lengths": np.array([speech_length], dtype=np.int64)})[0]
# 删掉模型最后的多余transpose, 速度从365ms提升到350ms
ret = onnx_edit(model = ONNX_MODEL,
export_path = ONNX_MODEL.replace(".onnx", "_edited.onnx"),
# # 1, len, 25055 -> 1, 25055, 1, len # 这个是坏的, 我真服了,
# outputs_transform = {'encoder_out': 'a,b,c->a,c,1,b'},
outputs_transform = {'encoder_out': 'a,b,c->a,c,b'},
)
ONNX_MODEL = ONNX_MODEL.replace(".onnx", "_edited.onnx")
# pre-process config
print('--> Config model')
rknn.config(quantized_algorithm='normal', quantized_method='channel', target_platform='rk3588', optimization_level=3)
print('done')
# Load ONNX model
print("--> Loading model")
ret = rknn.load_onnx(
model=ONNX_MODEL,
inputs=["speech", "/make_pad_mask/Cast_2_output_0"],
input_size_list=[[1, speech_length, 560], [extract_result.shape[0], extract_result.shape[1]]],
input_initial_val=[None, extract_result],
# outputs=["output"]
)
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=QUANTIZE, dataset=DATASET, rknn_batch_size=None)
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# export
print('--> Export RKNN model')
ret = rknn.export_rknn(RKNN_MODEL)
if ret != 0:
print('Export RKNN model failed!')
exit(ret)
print('done')
# usage: python convert_rknn.py encoder|all
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("model", type=str, help="model to convert", choices=["encoder", "all"], nargs='?')
args = parser.parse_args()
if args.model is None:
args.model = "all"
if args.model == "encoder":
convert_encoder()
elif args.model == "all":
convert_encoder()
else:
print(f"Unknown model: {args.model}")
exit(1)