PyTorch自定义BiLSTM多动态输入无法转换为ONNX应如何处理?
问题解答
- 关于seq_length定义:你必须先定义seq_length,它是构造dummy输入时使用的临时序列长度参考值,可直接设置为训练阶段的最大序列长度即可,比如
seq_length = 128。由于你已经配置了dynamic_axes启用动态轴,这个固定值仅作为导出阶段的形状参考,不会限制ONNX模型推理时的实际输入序列长度。 - 现有转换思路的问题:整体方向是对的,但存在3处错误会导致导出失败:
- 第二个dummy输入
dummy_input_2(对应text_len参数)形状和取值不合理:text_len的作用是记录每个样本的实际序列长度,形状应为[batch_size],而非[seq_length];同时text_len为长度统计值,不需要计算梯度,且取值不能超过对应样本的序列长度,用随机生成的浮点数转long可能出现负数、超范围的无效值,触发pad_packed_sequence逻辑报错。 - 不需要给dummy输入设置
requires_grad=True,如果仅导出用于推理的ONNX模型,该参数完全不必要。 - dynamic_axes配置缺了batch维度的动态支持:目前仅配置了序列长度的动态轴,若要支持可变batch大小推理,还需要给输入、输出的batch维度(第0维)增加动态配置。
- 第二个dummy输入
- 修正后的转换代码如下:
import torch # 1、定义seq_length,取训练时的最大序列长度即可 seq_length = 128 batch_size = 1 # 临时batch参考值,后续可动态调整 # 2、构造合理的dummy输入,vocab_size替换为你的实际词表大小 dummy_input_x = torch.randint(low=0, high=vocab_size, size=(batch_size, seq_length)).long() dummy_text_len = torch.tensor([seq_length]).long() # 单样本的长度就是当前dummy的序列长度 # 3、完善dynamic_axes配置,同时支持可变batch、可变序列长度 dynamic_axes = { 'input_x' : {0: 'batch_size', 1 : 'seq_len'}, 'text_len' : {0 : 'batch_size'}, 'output': {0: 'batch_size'} } # 4、执行导出 torch.onnx.export( model, args=(dummy_input_x, dummy_text_len), f='model.onnx', input_names=['input_x', 'text_len'], output_names=['output'], dynamic_axes=dynamic_axes, opset_version=13 # 建议指定>=13的opset,对RNN相关算子支持更好 )
注意替换代码中的vocab_size为你实际使用的词表大小,若导出时触发算子不支持的报错,可尝试调高opset_version的数值。
内容的提问来源于stack exchange,提问作者AlwaysNewbie
相关产品推荐
相关产品推荐

