精度比对问题定位案例

问题现象

CenterNet检测模型在迁移到昇腾AI处理器上训练后,发现Loss收敛效果较GPU明显变差。迁移前后Loss曲线如下图所示。蓝色为GPU训练曲线,收敛正常;红线为NPU训练曲线,收敛效果变差。

图1 GPU训练Loss曲线与NPU训练Loss曲线对比

总体思路

在PyTorch模型迁移与训练过程中,出现loss变化收敛不一致,通过dump比对工具进行定位。检测是否存在单算子与标杆数据(GPU/CPU)存在精度差异,进行数据dump,分析dump数据比对结果,从而定位出单算子的适配与实现问题。

环境准备

请参考ptdbg_ascend工具使用说明安装ptdbg_ascend精度工具,并准备已适配NPU环境的CenterNet训练工程,点击获取链接-ModelZoo,下载CenterNet模型脚本。

Dump数据比对

  1. 进入模型脚本所在目录并打开。

    cd src
    vi main_npu_8p.py

  2. 设置dump开关。

    分别dump CPU或GPU以及NPU数据,在PyTorch训练脚本插入dump接口,示例代码如下(下面以NPU为例,CPU或GPU dump基本相同):
    from ptdbg_ascend import PrecisionDebugger
    debugger = PrecisionDebugger(dump_path="./dump_data_new/npu", hook_name="dump", step=[0])
    debugger.configure_hook(mode="api_stack")
    # 请勿将以上初始化流程插入到循环代码中
    
    # 模型初始化
    # 下面代码也可以用PrecisionDebugger.start()和PrecisionDebugger.stop()
    debugger.start()
    
    # 需要dump的代码片段1
    
    debugger.stop()
    debugger.start()
    
    # 需要dump的代码片段2
    
    debugger.stop()
    debugger.step()

  3. 执行训练脚本。分别将模型在NPU和GPU/CPU上执行训练,注意两次执行训练前,要通过dump_path指定不同的输出目录,例如在CPU上可以将输出目录修改为./dump_data_new/cpu。

    # NPU训练命令
    bash ./test/train_full_1p.sh 

    模型训练结束后,数据会落盘到输出目录。

数据比对

  1. 参考compare.py脚本示例创建并配置精度比对脚本,样例参考如下。其中dump文件夹和pkl文件请用户根据dump时设置的实际目录修改。

    from ptdbg_ascend import compare
    dump_result_param={
        "npu_pkl_path": "/home/torch_test/dump_data_new/npu/ptdbg_dump_v4.0/step0/rank0/api_stack_dump.pkl",
        "bench_pkl_path": "/home/torch_test/dump_data_new/cpu/ptdbg_dump_v4.0/step0/rank0/api_stack_dump.pkl",
        "npu_dump_data_dir": "/home/torch_test/dump_data_new/npu/ptdbg_dump_v4.0/step0/rank0/api_stack_dump",  
        "bench_dump_data_dir": "/home/torch_test/dump_data_new/cpu/ptdbg_dump_v4.0/step0/rank0/api_stack_dump" 
    }
    compare(dump_result_param, "./out", stack_mode=True)

  2. 运行数据比对脚本。

    python3 compare.py

    比对完成后会在指定的输出目录中生成对比结果文件“compare_result_timestamp.csv”,示例文件如下所示。

    图2 示例文件

分析比对结果

比对结果为csv类型文件,会包含两份Dump数据的比对信息,包括tensor shape信息,数据类型,余弦相似度,最大绝对误差,最大值,最小值,平均值等统计信息。

通常情况下,只需要通过Accuracy Reached or Not字段的值来判断计算精度是否达标,字段值为Yes为达标,No则不达标。如下图所示:

图3 比对不达标结果

可以发现lstm反向输入正常,输出异常,说明是lstm的反向实现存在问题,进而影响了后续其他节点的精度。

定位问题API为lstm的反向实现。可以联系华为工程师反馈问题和寻求解决,可进入昇腾开源社区使用issue进行沟通。