当前仓库代码在于魔改原始WeNet源码,使其可以进行onnx导出
配置好examples/onnx/run_onnx.sh里面的config,checkpoint,output_dir
默认使用transformer
cd examples/onnx/
./run_onnx.sh
导出的模型可以使用wenet online onnx decoder代码进行测试
参考原始wenet源码
参考作业帮给出部分的方案
所有的对Tensor取size的操作均不被onnx支持,所以要把其包在@torch.jit.script指示的函数里
wenet/utils/mask.py
因onnx不支持tri算子,替换了subsequent_mask函数.
wenet/transformer/subsampling.py
对外不再使用position_encoding函数,改为position_encoding_onnx函数。原始forward_chunk调用传来的是x.size,现直接把x(Tensor)传给embedding层计算position_encoding.
wenet/transformer/encoder.py
line 123 添加了set_onnx_mode用于设置不同的代码流程
line 325 重写了一份forward_chunk_onnx函数
因为按作业帮的推送解释,onnx不能处理List[Tensor],所以对所有的cache(encoder_layer_cache、cnn_cache)均加了一维(从三维到四维),第一维是原始的List的index.
因为按作业帮的推送解释,onnx不能处理NoneType,所以在第一次处理时不能默认三个cache为None,所以要导入一份冗余的cache(本代码全部设为zeros),同时初始offset就被设为1(而不是0).
所有的cache在被处理时均被设为在时间轴上多了一(冗余)维,并携带冗余维进入encoder_layer(在每个layer层中自己切掉第一维)
subsampling_cache (batch_size=1, time, feature_dim=256)
elayers_output_cache (encoder_layer_num=12, batch_size=1, time, feature_dim=256)
conformer_cnn_cache (encoder_layer_num=12, batch_size=1, feature_dim=256, time=15) 这个15跟convolution层的self.lorder有关,self.lorder = kernel_size - 1
wenet/transformer/encoder_layer.py
wenet/transformer/embedding.py
wenet/transformer/decoder.py
wenet/transformer/decoder_layer.py
wenet/transformer/convolution.py
wenet/transformer/asr_model.py
runtime/core/decoder/torch_asr_decoder.cc runtime/core/decoder/torch_asr_decoder.h
环境配置请参考wenet
Traceback (most recent call last):
File "onnx_decoder.py", line 198, in
np.testing.assert_allclose(to_numpy(torch_outputs[i]), ort_outs[0], rtol=1e-03, atol=1e-05,err_msg='{0}'.format(i))
AssertionError:
Not equal to tolerance rtol=0.001, atol=1e-05
Mismatched elements: 761 / 2839200 (0.0268%)
Max absolute difference: 0.00216645
Max relative difference: 7.25