使用converter_lite转换包含Dropout算子的模型至MindSpore模型失败

1****系统环境

硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU

MindSpore版本: mindspore=2.2.13

执行模式(PyNative/ Graph):不限

Python版本: Python=3.9

操作系统平台: 不限

2****报错信息

2.1****问题描述

使用Mindspore构建只包含单个Dropout算子的模型,格式分别为ONNX和MINDIR,无法正确使用converter_lite工具转换为.ms格式。

import numpy as np
import mindspore
from mindspore import Parameter, ops, Tensor, nn

class Dropout(nn.Cell):

  def __init__(self):
    super(Dropout, self).__init__()
    self.Dropout = ops.Dropout(keep_prob=0.8)

  def construct(self, x):
    return self.Dropout(x)

dropout = Dropout()
dummy_input = Tensor(np.random.rand(2000, 1600), mindspore.float32)

mindspore.export(dropout, dummy_input, file_name="demo10", file_format="MINDIR")复制

执行下面命令

./converter_lite --fmk=MINDIR --trainModel=true --modelFile=demo10.mindir --outputFile=demo10复制

有以下报错(trainModel参数是否存在都会导致同样的报错):

2.1****报错信息

[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.393.679 [mindspore/lite/tools/common/graph_util.cc:133] GetShapeVectorAndIdxFromCNode] Abstract is not abstract tensor. Default/Dropout-op6
[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.393.727 [mindspore/lite/tools/common/graph_util.cc:236] TraceOutput] Get node shape failed.
[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.393.745 [mindspore/lite/tools/common/graph_util.cc:661] GetFuncGraphOutputsInfo] Trace output failed.
[ERROR] CORE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.393.784 [mindspore/core/utils/log_adapter.cc:433] operator^] Runtime error for null exception handler.
[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.394.005 [mindspore/lite/tools/converter/converter.cc:1324] RunConverter] Exception occurred: Failure info [Get outputs info of funcgraph failed].

----------------------------------------------------
- Framework Unexpected Exception Raised:
----------------------------------------------------
This exception is caused by framework's unexpected error. Please create an issue at https://gitee.com/mindspore/mindspore/issues to get help.

----------------------------------------------------
- C++ Call Stack: (For framework developers)
----------------------------------------------------
mindspore/lite/tools/common/func_graph_utils.cc:83 GetFuncGraphOutputNames

[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.394.038 [mindspore/lite/tools/converter/converter.cc:1328] RunConverter] Convert model failed
[ERROR] LITE(32309,ffff9357b010,converter_lite):2024-08-13-15:04:46.394.061 [mindspore/lite/tools/converter/cxx_api/converter.cc:374] Convert] Convert model failed, ret=Common error code.
ERROR [mindspore/lite/tools/converter/converter_lite/main.cc:104] main] Convert failed. Ret: Common error code.
Convert failed. Ret: Common error code.复制

3****根因分析

看报错信息是convert工具在处理output的时候遇到了不支持的类型

GetShapeVectorAndIdxFromCNode] Abstract is not abstract tensor

然后查看API

应该是mask的输出比较特殊导致convert处理失败。

4****解决方案

1.算子使用ops.dropout, 因为该算子只有一个输出

import numpy as np  
import mindspore  
from mindspore import Parameter, ops, Tensor, nn  
  
class Dropout(nn.Cell):  
  
  def __init__(self):  
    super(Dropout, self).__init__()  
  
  def construct(self, x):  
    return ops.dropout(x, p=0.2)  
  
dropout = Dropout()  
dummy_input = Tensor(np.random.rand(2000, 1600), mindspore.float32)  
  
mindspore.export(dropout, dummy_input, file_name="demo10", file_format="MINDIR")  

2.不将Dropout的输出mask作为网络输出

import numpy as np  
import mindspore  
from mindspore import Parameter, ops, Tensor, nn  
  
  
mindspore.set_context(device_target="CPU")  
class Dropout(nn.Cell):  
  
  def __init__(self):  
    super(Dropout, self).__init__()  
    self.Dropout = ops.Dropout(keep_prob=0.8)  
  
  def construct(self, x):  
    x, _ = self.Dropout(x)  
    return x  
  
dropout = Dropout()  
dummy_input = Tensor(np.random.rand(2000, 1600), mindspore.float32)  
  
mindspore.export(dropout, dummy_input, file_name="demo11", file_format="MINDIR")