PaddlePaddle / X2Paddle

Deep learning model converter for PaddlePaddle. (『飞桨』深度学习模型转换工具)
http://www.paddlepaddle.org/
Apache License 2.0
731 stars 164 forks source link

使用onnx2paddle,转换onnx的BiLSTM模型出错 #803

Open likestudy opened 2 years ago

likestudy commented 2 years ago

感谢您参与 X2Paddle 社区! 问题模版为了 X2Paddle 能更好的迭代,例如新功能发布、 RoadMaps 和错误跟踪. :smile_cat:

问题描述

使用onnx2paddle将onnx的BiLSTM模型转换为paddle模型报错,转换失败。

使用onnx2paddle转化模型报错:

原ONNX模型转化时opset_version=11:

In transformed code:
    File "model\pd_model\x2paddle_code.py", line 78, in forward
        x2paddle_onnx__LSTM_47 = paddle.reshape(x=x2paddle_onnx__LSTM_47, shape=[2, 1, 384])
        x2paddle_onnx__LSTM_48 = paddle.reshape(x=x2paddle_onnx__LSTM_48, shape=[2, 1, 384])
        x2paddle_onnx__Transpose_181, (x2paddle_182, x2paddle_183) = self.lstm0(x2paddle_onnx__LSTM_64, (x2paddle_onnx__LSTM_47, x2paddle_onnx__LSTM_48))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
        x2paddle_onnx__Transpose_181 = paddle.reshape(x=x2paddle_onnx__Transpose_181, shape=[0, 0, -1, 384])
        x2paddle_onnx__Transpose_181 = paddle.transpose(x=x2paddle_onnx__Transpose_181, perm=[0, 2, 1, 3])
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\fluid\dygraph\layers.py", line 917, in __call__
    return self._dygraph_call_func(*inputs, **kwargs)
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\fluid\dygraph\layers.py", line 907, in _dygraph_call_func
    outputs = self.forward(*inputs, **kwargs)
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\nn\layer\rnn.py", line 1061, in forward
    return self._cudnn_impl(inputs, initial_states, sequence_length)
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\nn\layer\rnn.py", line 1036, in _cudnn_impl
    type="rnn", inputs=inputs, outputs=outputs, attrs=attrs)
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\fluid\dygraph\layer_object_helper.py", line 52, in append_op
    stop_gradient=stop_gradient)
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\fluid\framework.py", line 3184, in append_op
    attrs=kwargs.get("attrs", None))
    File "D:\Software\Professional\Anaconda2\envs\pytorch1.5\lib\site-packages\paddle\fluid\framework.py", line 2344, in __init__
    self.desc.infer_shape(self.block.desc)
    ValueError: (InvalidArgument) The second dimension size (representing for batch size) of Input and PreState should be equal. But received -1 and 1.
  [Hint: Expected in_dims[1] == pre_state_dims[i][1], but received in_dims[1]:-1 != pre_state_dims[i][1]:1.] (at C:\home\workspace\Paddle_release\paddle\fluid\operators\rnn_op.cc:66)
  [operator < rnn > error]

原ONNX模型转化时opset_version=9:

Converting node 21 ...     Traceback (most recent call last):
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\op_mapper\onnx2paddle\opset9\opset.py", line 101, in run_mapping
    res = func(*args, **kwargs)
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\op_mapper\onnx2paddle\opset9\opset.py", line 2372, in TopK
    val_k = self.graph.get_input_node(node, idx=1, copy=True)
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\decoder\onnx_decoder.py", line 353, in get_input_node
    ipt_node = super(ONNXGraph, self).get_node(node.inputs[idx], copy)
IndexError: list index out of range
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\convert.py", line 219, in onnx2paddle
    mapper = ONNXOpMapper(model)
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\op_mapper\onnx2paddle\onnx_op_mapper.py", line 44, in __init__
    func(node)
  File "XXX\Anaconda2\envs\pytorch1.5\lib\site-packages\x2paddle\op_mapper\onnx2paddle\opset9\opset.py", line 104, in run_mapping
    node.name[9:], node.layer_type))
Exception: convert failed node:onnx__Cast_50_p0, op_type is TopK
Convert torch model to paddle model failed
INFO:common:Convert torch model to paddle model failed

使用pytorch2paddle转化torch模型到paddle模型同样失败

========= 4 OPs are not supported yet ===========
========== aten::sort ============
========== aten::_pack_padded_sequence ============
========== aten::_pad_packed_sequence ============
========== aten::linear ============

具体信息

onnx2paddle代码:

        onnx2paddle(model_path=os.path.join(config.model_save_path, config.static_onnx_path),
                    save_dir=os.path.join(config.model_save_path, config.paddle_model_dir),
                    convert_to_lite=False) 
wjj19950828 commented 2 years ago

@likestudy 感谢反馈,辛苦把torch转换相关脚本以及模型组网、参数也打包一起上传吧~

另外可以描述一下为什么会有转到Paddle 部署的需求吗,感谢~

likestudy commented 2 years ago

@wjj19950828 torch模型转化ONNX以及转化paddle的脚本等均已上传至: 链接:https://pan.baidu.com/s/1UcdjIwp9OgPoEZtDeeRMqQ 提取码:as63。

您直接运行convert_model.py,便可调用model下的pytorch_model.bin生成bilstm.onnx,以便进一步转化为paddle模型。

因为看到paddle介绍在推理端有很多优化,所以想将模型转化为paddle模型进行推理,十分感谢您的帮助。

wjj19950828 commented 2 years ago

@likestudy 您好,目前问题已经修复,拉取此PR代码,源码安装:https://github.com/PaddlePaddle/X2Paddle/pull/805

使用onnxsim简化下onnx模型,再进行转换

python -m onnxsim bilstm.onnx bilstm_sim.onnx
x2paddle --framework=onnx --model=bilstm_sim.onnx --save_dir=pd_model

另外,对于这种简单模型,建议使用PaddleNLP直接训练、预测,降低转换带来的性能损失

参考:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/examples/lexical_analysis