【MindSpore易点通】如何使用溢出检测工具定位精度问题

一、问题背景

开发人员在调试模型时可能会遇到一些精度异常情况,如loss无法收敛、精度不达标等,原因可能是计算过程中发生了溢出。为了识别计算过程是否发生了溢出,可以使用溢出检测工具监测网络前反向过程中每个算子的溢出情况。

溢出检测工具一旦检测到计算过程中有溢出,便会通过[WARNING]消息告知用户具体哪个算子计算时发生了溢出,并保存该算子对应的输入和输出数据(通过Dump方式保存),供用户分析。

注:当前溢出检测工具仅支持检测上溢出,暂不支持检测下溢出。

**上溢出:**数值超出最大表示范围。如表示区间为0~65504,那么当进行50000 + 50000的操作时,则会发生上溢出,输出结果可能是65500。

**下溢出:**数值小于最小表示精度。如最小表示精度为6e-8,那么当进行8e-8 / 10的操作时,则会发生下溢出,输出结果可能是0。

二、溢出检测工具使用流程

2.1、示例代码

以下代码对FP16格式的数据进行40000+41000的求和操作,理论结果为81000,但超过了FP16的最大表示值65504,因此求和计算过程中将发生上溢出。

下面将以该代码为示例,展示溢出检测工具的使用流程。

import mindspore.nn as nn
import numpy as npfrom mindspore 
import Tensorfrom mindspore 
import contextimport mindspore.ops as ops

context.set_context(reserve_class_name_in_scope=False)
class PrintDemo(nn.Cell):
        def __init__(self):
            super(PrintDemo, self).__init__()

        def construct(self, input_pra):
            out = input_pra.sum()
            return out

def test():
    input_x = Tensor(np.array([40000, 0, 41000]).astype(np.float16))
    input_pra = Tensor(input_x)
    net = PrintDemo()
    net(input_pra)

    return net(input_pra)

print(test())

2.2、创建配置文件data_dump.json

溢出检测是异步Dump下的一个子功能;通过修改data_dump.json文件中op_debug_mode 的值开启溢出检测工具。

{
    "common_dump_settings": {
        "dump_mode": 0,
        "path": "/absolute_path/",
        "net_name": "ResNet50",
        "iteration": "0|5-8|100-120",
        "input_output": 0,
        "kernels": ["Default/Conv-op12"],
        "support_device": [0,1,2,3,4,5,6,7],
        "op_debug_mode": 3
    }
}

  • dump_mode:设置成0即可,表示Dump出该网络中的所有算子数据。
  • path:Dump保存数据的绝对路径。此流程执行完毕后,此网络中若有算子溢出则会在路径path下生成该算子的Dump数据。
  • net_name:自定义的网络名称,随便填,例如:”ResNet50”。
  • iteration:指定需要进行溢出检测的迭代。类型为str,用“|”分离要保存的不同区间的step的数据。如”0|5-8|100-120”表示Dump第1个,第6个到第9个, 第101个到第121个step的数据。指定“all”,表示Dump所有迭代的数据。这里推荐设置成“all”。
  • input_output:设置成0,表示Dump出算子的输入和算子的输出;设置成1,表示Dump出算子的输入;设置成2,表示Dump出算子的输出。
  • kernels:算子的名称列表。使用溢出检测工具时不用特别关注。
  • support_device:设置成[0,1,2,3,4,5,6,7]即可,表示开启溢出检测的device id。
  • op_debug_mode:设置成3即可,表示开启全部溢出检测功能。
  • op_debug_mode:该属性用于算子溢出调试,设置成0,表示不开启溢出;设置成1,表示开启AiCore溢出检测;设置成2,表示开启Atomic溢出检测;设置成3,表示开启全部溢出检测功能。在Dump数据的时候请设置成0,若设置成其他值,则只会Dump溢出算子的数据。

2.3、设置环境变量

export MINDSPORE_DUMP_CONFIG={Absolute path of data_dump.json}

在网络脚本执行前,设置好环境变量;否则溢出检测工具将不生效。

在分布式场景下,该环境变量需要在调用mindspore.communication.init之前配置。

2.4、执行训练

正常启动训练即可。

**注:**可以在训练脚本中设置context.set_context(reserve_class_name_in_scope=False),避免Dump文件名称过长导致Dump数据文件生成失败。

2.5、若发生溢出,告知用户并自动保存溢出算子数据

若算子有溢出,则溢出检测工具会将算子溢出信息通过打屏日志[WARNING]显示,溢出检测工具执行流程以及溢出信息展示如下图中红框所示:

2.6、解析保存的溢出算子数据

步骤一:找到在json文件中所配置的"path": "/absolute_path/"路径下所生成rank_x文件夹下算子数据文件。使用run包中提供的msaccucmp.py解析Dump出来的文件。不同的环境上msaccucmp.py文件所在的路径可能不同,可以通过find命令进行查找:

find ${run_path} -name "msaccucmp.py"

run_path:run包的安装路径,如/usr/local/Ascend

步骤二:找到msaccucmp.py后,到/absolute_path目录下,运行如下命令解析Dump数据:

python ${The absolute path of msaccucmp.py} convert -d {file path of dump} -out {file path of output}

解析完成后,会生成input与output文件,具体格式如以下所示:

ReduceSum.Default_ReduceSum-op0.2.7.1641535332858320.input.0.npy
ReduceSum.Default_ReduceSum-op0.2.7.1641535332858320.output.0.npy

注:input.0.npy文件为ReduceSum算子的输入,即代码中的input_x;output.0.npy文件为所存储数据为算子运行后计算的结果。

步骤三:解析npy文件分析溢出情况。通过numpy.load("file_name")工具加载out文件可以读取到对应数据。

1、使用加载工具解析input.0.npy文件。

import numpy
numpy.load("ReduceSum.Default_ReduceSum-op0.2.7.1641535332858320.input.0.npy")

根据解析文件可以看到该文件所存储的数据为input.0.npy文件为ReduceSum算子的输入,即代码中的input_x;

2、使用加载工具解析output.0.npy文件,解析方法以及代码如上所示,故在此不再赘述;

文件解析后的结果为[65500.],即算子溢出后的输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值