华为云AI开发平台ModelArtsPytorch迁移精度调优_云淘科技

基于Pytorch Adapter完成代码迁移适配后,用户需要进一步验证精度是否达标。迁移过程精度偏差的来源,一方面是昇腾设备部分算子的实现和CUDA算子有差异,另外一方面则是硬件方面的差异,如Ascend Snt9芯片上的Matmul和Conv等cube算子只支持FP16,可能会导致数值溢出,从而引起精度误差。此外,网络随机参数初始化差异以及典型场景(比如dropout和数据集shuffle等操作)都可能引入误差,所以迁移模型精度校验以及精度调优工作是至关重要的。

精度校验

迁移之后的精度校验工作是以CPU/GPU环境训练过程作为标杆的,这里的前提是在迁移前,模型已经在CPU/GPU环境达到预期训练结果。在此基础上,迁移过程的精度问题一般包括:

loss曲线与CPU/GPU差异不符合预期。
验证准确度与CPU/GPU差异不符合预期。

在迁移到NPU环境下训练时发现以上问题时,说明精度存在偏差,需要进一步做精度调优。下文将分别阐述精度诊断的整体思路和借助工具如何进行精度问题的定位。

精度调优总体思路

一般场景的训练模型都是包括随机种子、数据集shffule、网络结构dropout等操作的,目的是在网络训练阶段引入一定的随机性使得训练结果更加具有鲁棒性。然而在精度诊断或者对齐阶段需要暂时关闭这些随机特性,使得需要对齐的标杆结果是确定唯一的。针对精度问题比较有效的诊断方法有整网dump和整网的溢出检测两种方式。下图是昇腾社区针对Pytorch训练迁移场景的精度调优流程示意图,请见详情。

图1 精度调优流程

整网dump和溢出检测是通过在Pytorch模型中注入hook、dump模型训练过程的输入输出数据,比对NPU环境和标杆环境的所有输入输出发现异常信息。具体可以参见精度比对工具ptdbg-ascend。

精度调优的另一个角度可以从网络的单个API角度分析,通过提取模型中所有的API前反向信息,构造相应的API单元测试,将NPU输出与标杆比对,从而检测出精度有问题的API。具体参见精度预检工具api_accuracy_checker。

精度比对工具使用说明

ptdbg-ascend是昇腾开源的用于Pytorch框架迁移训练的精度对比工具。使用时需要两组模型运行环境,一组是基于昇腾AI芯片的NPU环境,另一组是CPU/GPU环境(标杆环境)。ptdbg-ascend通过在 PyTorch 训练脚本中插入 dump 接口,跟踪计算图中算子的前向传播与反向传播时的输入与输出,然后再compare将对比结果写出到.csv表格中。

当前支持计算Cosine(余弦相似度)、MaxAbsErr(最大绝对误差)和MaxRelativeErr(最大相对误差)这三种评价指标,通过设定相似度阈值和最大绝对偏差限来判断API运行时是否存在精度问题。

安装ptdbg_ascend工具。

下载最新的whl包至服务器,并通过pip安装ptdbg_ascend工具(工具链接)。

#shell
pip install ./ptdbg_ascend-3.1-py3-none-any.whl

获取NPU和GPU的dump数据。

在单卡场景下,Pytorch 训练脚本插入 dump 接口方式如下:

# 导入ptdbg_ascend依赖包
from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
# 在 main 函数中固定随机数
seed_all(seed=1234, mode=False)
# 设置 dump 文件保存路径
set_dump_path("./npu_dump", dump_tag='all')
# 添加hook函数和数据比对dump开关
register_hook(model, acc_cmp_dump)
# dump 开启和关闭。在一个 iter 的开始和结束位置设置
set_dump_switch("ON", mode="api_stack", filter_switch="OFF")
# ---------
# iterartion
# ---------
set_dump_switch("OFF", mode="api_stack", filter_switch="OFF")、

以上给出的是 dump 整网精度数据的方式,在迁移过程中也会碰到数值溢出问题。在ptdbg中设置检查精度溢出方式如下:

# dump 开启和关闭。在一个 iter 的开始和结束位置设置
register_hook(model, overflow_check, overflow_nums=3)
set_overflow_check_switch("ON")
# ---------
# iterartion
# ---------
set_overflow_check_switch("OFF")

这里的overflow_sum用来控制溢出次数,表示多少次溢出时停止训练。

生成精度对比表。

dump得到NPU和GPU数据的之后,会得到保存api完整输入输出Tensor的.npy文件以及保存API简单统计信息的 .pkl 文件。在compare对比时,需要分别指定NPU和GPU的pkl文件路径和 dump 数据路径(具体参数请按实际路径填写),compare.py实现如下:

# compare.py
from ptdbg_ascend import compare
dump_result_param= {
"npu_pkl_path": "${dump_data_npu}/api_stack_dump.pkl",
"bench_pkl_path":"${dump_data_gpu}/api_stack_dump.pkl",
"npu_dump_data_dir": "${dump_data_npu}/api_stack_dump/",
"bench_dump_data_dir": "${dump_data_npu}/api_stack_dump/",
"is_print_compare_log": True
}
compare(dump_result_param, "./output", stack_mode=True)

执行comapre.py对比之后会在output目录下输出compare_result_{timestamp}.csv文件。根据此文件,可以查看网络训练过程中各个API执行的输入输出以及评价指标的信息。

根据堆栈信息定位代码差异点。

在compare对比表文件NPU_Stack_Info列,有各个算子在执行时的堆栈信息。如下图所示,列出的是NPU下Torch_embedding_0_forward(代表torch的embedding算子在第 0 次执行forward阶段)的堆栈信息。

图2 堆栈信息

部分情况下也需要查看GPU训练时的堆栈信息来排除GPU和NPU是否执行的不同逻辑代码。这种情况可以根据NPU Name在dump阶段生成的.pkl文件中查找。在 ptdbg-ascend中,有支持使用API接口parse堆栈信息的方式,代码如下:

# compare.py
from ptdbg_ascend import parse
parse(". /dump_data /npu/rank0/api_stack_dump.pkl", "Torch_embedding_0_forward")

精度对齐。

ptdbg-ascend当前支持的评判指标有Cosine、MaxAbsError(可参见接口函数说明):

精度存在异常的情况包含以下三种情况:

Cosine 0.001
Cosine 1

其余情况都视为达标。精度对齐时,需要根据compare表格查找精度不达标的算子进行调整优化。由于算子间可能存在前后数据传输的相关性,一般先定位第一个不达标的算子,然后结合堆栈信息进行分析和调整,调整之后重新训练dump数据再做对比,直至模型训练的loss 曲线和在验证集上做测试的结果和GPU 标杆结果一致为止。

父主题: 训练业务昇腾迁移通用指导

同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家