使用mindpsore.nn.conv3d在GPU上精度不足问题

1 系统环境

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

MindSpore版本:mindspore=2.1

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

Python版本:Python=3.7

操作系统平台:Linux

2 报错信息

2.1 问题描述

mindspore.nn.conv3d在GPU上存在精度不足的问题,测试conv3d时,在group不等于的场景下,用例概率性失败,失败原因为torch的output和mindspore的output在部分维度结果不一致。

2.2 脚本

import mindspore  
from mindspore import ops  
from mindspore import Tensor, nn  
from mindspore.common.api import jit  
from mindspore import context  
import numpy as np  
  
import torch  
  
  
input = np.random.uniform(size=(16,3,10,32,32))  
  
ms_input = Tensor(input, mindspore.float32)  
conv3d = nn.Conv3d(in_channels=3, out_channels=32, kernel_size=(4, 3, 3), has_bias=True, pad_mode='valid')  
ms_out = conv3d(ms_input)  
  
torch_input = torch.Tensor(input)  
m = torch.nn.Conv3d(3, 32,kernel_size=(4, 3, 3))  
torch_out = m(torch_input)  
  
  
# 失败  
y = np.subtract(ms_out.asnumpy(), torch_out.detach().numpy())  
w = np.where(np.abs(y) > 0.00004, 1, 0)  
z = np.count_nonzero(w)  

3 根因分析

由于input为随机数,因此使用np.random.seed()确定随机种子,通过固定随机数的方式确定必现的复现条件。确定复现场景后,将mindspore与torch的输出相减,记录指定精度下差异位的个数。

y = np.subtract(ms_out.numpy(), torch_out.numpy())  
  
w = np.where(np.abs(y) > 0.00004, 1, 0)  
  
z = np.count_nonzero(w)

在此案例中,精度为4*1e-5时有15个结果不一致,在默认绝对精度为1e-5的场景下,mindspore与torch不相等的结果有2500+,因此用例不通过。

继续调整atol的范围,当atol=1e-4的场景下,问题不复现。

4 解决方案

GPU平台上对于较大tensor输入的计算精度可能下降,不满足默认绝对精度值,需要针对单个用例进行调整。此处用例有1e-3的相对精度误差,但是在随机数结果较小的情况下,相对精度误差的影响没有绝对精度误差大,因此并不会缓解mindspore和torch的返回值差异。