使用MindSpore中的SoftMax()算子计算单一数据出错Run op inputs type is invalid! 以及定位解决

1 系统环境

硬件环境(Ascend/GPU/CPU): CPU
MindSpore版本: 1.9.0
执行模式(PyNative/ Graph): PyNative
Python版本: 3.7.5
操作系统平台:不限

2 报错信息

2.1 问题描述

针对shape为(1,)的输入,SoftMax的输出结果应该为1,但是MindSpore直接抛出异常

2.2 报错信息

Run op inputs type is invalid!

2.3 脚本代码

import mindspore as ms
    
print(ms.ops.Softmax(-1)(ms.Tensor(np.ones(1)), ms.float32))

3 根因分析

1.Softmax类报错
在1.9.0的环境下运行Softmax代码
首先明确出问题的API:ms.ops.Softmax,与这个类紧密相关的是ms.ops.softmax函数(大小写区别)
在1.9.0版本的API文档中,可以看出,ms.ops.Softmax函数输入量应该是Tensor和指定的轴:


而在报错的代码中:

print(ms.ops.Softmax(-1)(ms.Tensor(np.ones(1)), ms.float32))

我们可以看到输入的量有三个:轴-1,Tensor和dtype数据类型
因此,这与API文档相背离,所以报错。
2.使用softmax函数
Softmax类来源于softmax函数,使用softmax函数是否可以避免报错?
观察softmax的API文档,发现不支持指定数据类型,因此替换了也会报错。


3.更高版本的MindSpore会有解决办法吗
对于python类Softmax,从1.9.0到2.0.0alpha到2.0.0rc1,都是只有axis一个输入量,因此不能输入dtype这个参数。
而对于函数softmax,1.9.0和2.0.0alpha中,都不能输入dtype。
但是在2.0.0rc1最新版本中,增加了dtype这个输入项。

4 解决方案

根据根因分析:ms.ops.Softmax的输入量出现了问题,因此有以下解决方法:
1.输入量改为指定了浮点精度的MindSpore的Tensor

x = ms.Tensor(np.ones(1), ms.float32)  
print(ms.ops.Softmax(-1)(x))


2.用softmax而非Softmax实现相同效果:输入量需要先指定浮点精度

x = ms.Tensor(np.ones(1), ms.float32)  
print(ms.ops.softmax(x))


3.升级MindSpore版本,并改用2.0.0rc1中的softmax函数,这时函数支持在softmax中指定dtype

x = ms.Tensor(np.ones(1))  
print(ms.ops.softmax(x,dtype=ms.float32))

这时候,就可以不在Tensor中指定数据类型/精度,而是在softmax函数中指定dtype。


4.鉴于2.0.0rc1中已经给softmax函数指定了dtype的能力,那么可能在未来,Softmax类也可以直接支持dtype的输入,也就意味着上述报错的代码不会报错了。