下载
中文
注册

浮点异常检测

训练网络执行过程中,发生频繁浮点异常问题时,可参见本节内容进行浮点异常检测。

使用场景

在训练网络执行过程中,可能发生频繁的浮点异常情况,此时需要通过分析溢出数据,对频繁的浮点异常问题进行定界定位。
  • 对于动态loss scale场景,一般需要对loss scale值下降次数较多或者直接下降为1的情况进行浮点异常定界定位,但在训练多个step的场景下,如果只是某个step出现了溢出,则可能是正常的偶发溢出,一般在开启loss scale的情况下,会自动跳过该step的训练结果,梯度不更新,对于这种偶发溢出场景一般可以不用关注。
  • 对于静态loss scale场景,一般情况下即便是溢出较少的情况,也可能需要进行浮点异常定界定位。

    loss scale值的打印方法请参考打印loss scale值

溢出数据检测的主要流程如图1所示。

图1 溢出数据检测流程

前提条件

  1. 已完成调优前检查
  2. 已完成精度分析工具部署
  3. 进行溢出数据分析时依赖CANN Toolkit软件包中的工具,因此需要准备CANN开发环境,即Toolkit安装环境。

Dump溢出数据

以下操作在NPU训练环境执行。

  1. 修改训练脚本,打开算子溢出数据采集开关。
    # 引用precision_tool/tf_config.py
    import precision_tool.tf_config as npu_tf_config
    
    # 1. 手工迁移网络
    # 1.1 Estimator方式
    dump_config=npu_tf_config.estimator_dump_config(action='overflow')
    npu_config = NPURunConfig(dump_config=dump_config)
    # 1.2 Session run方式
    config = npu_tf_config.session_dump_config(config, action='overflow')
    sess = tf.Session(config)
    
    # 2. 自动迁移网络
    # 若脚本中未配置custom_op,则在脚本中新增如下粗体语句
    session_config = npu_tf_config.session_dump_config(session_config, action='overflow')
    # 若脚本中已配置custom_op,如下所示,则在脚本中新增下列粗体语句更新custom_op
    custom_op = session_config.graph_options.rewrite_options.custom_optimizers.add()
    custom_op.name = 'NpuOptimizer'
    custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_mix_precision")
    custom_op = npu_tf_config.update_custom_op(custom_op, action='overflow')
    
    # 2.1 Estimator方式
    run_config = tf.estimator.RunConfig(session_config=session_config,...)
    # 2.2 Session run方式
    with tf.Session(config=npu_config_proto(session_config)):
        ....
    # 2.3 tf.keras方式
    npu_keras_sess = set_keras_session_npu_config(config=session_config)
    • 除了此种方式,您也可以参考溢出数据采集的方法修改训练脚本,采集溢出数据,但配置较为复杂,且采集到数据之后,需要手工提取并放在相应目录下,用于后续数据分析。注意两种方式不能重复配置。
    • 仅支持采集AI Core算子的溢出数据。
  2. 执行训练,如果网络存在溢出,则在precision_data/overflow/dump下会生成溢出信息文件。

溢出数据分析

溢出数据分析依赖CANN Toolkit软件包中的atc工具和msaccucmp.py工具,以下操作需要在CANN开发环境,即Toolkit安装环境进行

  1. 将precision_tool和precision_data文件夹上传到Toolkit安装环境的任意目录下,目录结构示例:
    1
    2
    3
    4
    5
    6
    ├── precision_tool              
        ├── cli.py                   
        ├── ...
    ├── precision_data              
        ├── overflow                   
            ├── dump
    
  2. 安装python第三方依赖。
    pip3 install rich
  3. 修改工具precision_tool/lib/config目录下的config.py。
    # 依赖Toolkit包中的atc和msaccucmp.py工具,一般在run包安装目录,配置到父目录即可
    # 默认Toolkit包安装在/usr/local/Ascend,可以不用修改,指定目录安装则需要修改
    CMD_ROOT_PATH = '/usr/local/Ascend'
  4. 启动PrecisionTool交互命令行。

    python3 ./precision_tool/cli.py

    进入交互命令行界面:

    PrecisionTool >

    如需退出,可执行ctrl + c。

  5. 执行ac -l [limit_num] (-c)命令进行溢出数据分析。

    PrecisionTool > ac

    根据数据量大小,分析过程需要时间不同,当执行过程中出现算子溢出,则会输出如下结果。

    从上图可以看到:

    • 算子名为:bert_encoder_layer_10_intermediate_dense_mul_FusedMulAdd
    • 算子类型为:FusedMulAdd
    • 溢出status信息为:32,表示浮点计算有溢出。
    • 溢出类型为:AI Core算子溢出,另外还可能会有其他类型的算子溢出(例如DHA Atomic Add或L2 Atomic Add),建议用户优先考虑并解决AI Core算子溢出问题。
    • 算子的输入输出信息,包括shape、dtype、输入输出数据的最大值最小值。

    当出现多个算子溢出时,会出现N个溢出算子信息,默认按照算子执行顺序排序,由于后面算子溢出可能是因为前一个算子溢出导致,建议用户优先分析第一个异常算子。

  6. 执行pt (-n) [*.npy]命令,可以查看对应dump数据块的数据信息。

分析思路参考

进行溢出数据分析前,我们先了解下不同昇腾产品的浮点数据溢出模式:
  • Atlas 训练系列产品,浮点计算的溢出模式默认为“饱和模式”,且仅支持“饱和模式”。饱和模式为:计算出现溢出时,饱和为浮点数极值(+-MAX)。
  • Atlas A2 训练系列产品,浮点计算支持两种溢出模式:饱和模式与INF/NAN模式,请保持默认值INF/NAN模式。饱和模式仅用于兼容旧版本,后续不再演进,且此模式下计算精度可能存在误差。
进行溢出数据分析的大致思路为:
  1. 查看输入输出数据值。
    • 如果输入值中没有溢出值(饱和模式:65504/Nan;INF/NAN模式:Inf/Nan),输出数据中存在溢出值,则计算存在溢出。
    • 如果输入值中存在溢出值,则需要继续分析前向算子或者用户模型的常量输入是否存在异常,否则可能在计算过程中存在溢出。
  2. 查看溢出算子类型。
    • 对于自定义开发的算子,可以尝试自行进行算子溢出分析(结合算子公式和溢出值进行分析),排查自定义算子是否存在问题。
    • 对于CANN内置算子,也可以先尝试初步分析,如下为常用的分析方向:
      • 如果算子输出类型为float16,解析出的输出数据中出现类似于65504/65500(饱和模式)或者Inf/Nan(INF/Nan模式),则可以切换输出算子类型至float32计算,用户可以尝试以下两种方法:
        1. (推荐)方法一:修改混合精度模式算子黑白灰名单,调整算子精度模式,请参考修改混合精度黑白灰名单
        2. 方法二:通过keep_dtype_scope接口,指定哪些算子保持原有精度。
          from npu_bridge.npu_init import *
          with npu_scope.keep_dtype_scope():   
            y = tf.mul(x1,x2)
      • 如果输入输出数据中均未出现溢出值,则需要结合算子公式,分析数据计算过程中是否可能出现溢出。例如AvgPool先求和再平均,求和过程可能溢出,但平均后并未溢出。
  3. 如果依旧无法解决,欢迎到昇腾社区提issue求助。