# Ascend模型精度预检工具
## 版本过渡提示
当前版本预检维护到2024/09/30,准备于2024/09/30下线,相关目录att/debug/accuracy_tools/api_accuracy_checker将于2024/09/30删除。新版本的预检已经合到att/debug/accuracy_tools/atat目录下。
Ascend模型精度预检工具能在昇腾NPU上扫描用户训练模型中所有API,输出精度情况的诊断和分析。工具通过dump模型中所有的API前反向信息;构造相应的API单元测试,将NPU输出与标杆(CPU高精度)比对,从而计算对应的精度指标,该过程称为run_ut;将NPU环境下dump的预检数据拷贝至GPU环境,同样执行run_ut;最后通过新精度标准比对法将NPU和GPU的预检结果进行比对,从而找出NPU中存在精度问题的API。
**新精度标准比对法**:依据新精度标准,对不同的API采取不同的比对算法进行比对(包括绝对阈值法,标杆比对法、二进制一致法、ULP误差比对法和双千指标法),最终给定预检判定结果。
**真实数据模式**:精度预检工具支持随机生成模式和真实数据模式,即在预检dump时可以选择由工具构造随机数进行输入获得dump数据或选择获取真实输入数据进行预检dump操作;随机生成模式执行效率高,可以快速获得结果,但数据精度低,只能大致判断精度问题;真实数据模式执行效率略低于随机生成模式,但是数据精度高,可以准确判断精度问题。
工具支持PyTorch版本:1.11.0/2.0/2.1/2.2。
## 工具特性
- 落盘数据小。
- 支持随机生成模式和真实数据模式。
- 单API测试,排除整网中的累计误差问题。
## 预检流程
精度预检操作流程如下:
1. 在NPU和GPU环境下分别安装预检工具。详见“**工具安装**”。
2. 在NPU环境下dump预检数据。详见“**dump预检数据**”。
3. 将NPU环境下dump的预检数据拷贝至GPU环境。
4. 在NPU和GPU环境下分别执行run_ut,生成结果用于最终api_precision_compare操作的输入。详见“**run_ut预检操作**”。
5. 将NPU和GPU执行run_ut生成的`accuracy_checking_details_{timestamp}.csv`结果文件拷贝至同一环境下。
6. 运行api_precision_compare.py,输出结果为预检操作的最终结果。详见“**预检结果比对**”。
## 工具安装
1. 将att仓代码下载到本地,并配置环境变量。假设下载后att仓路径为 $ATT_HOME,环境变量应配置为:
```bash
export PYTHONPATH=$PYTHONPATH:$ATT_HOME/debug/accuracy_tools/
```
2. 安装依赖。
```bash
pip3 install tqdm rich pyyaml pandas einops
```
## 预检操作
### dump预检数据
#### dump操作
在训练脚本(如main.py)中加入以下代码导入工具dump模块,启动训练即可自动抓取网络所有API信息。
- 若训练脚本中的代码不是通过torch.utils.data.dataloader来加载数据或在部分流水并行、张量并行场景下,工具的开关无法在每张卡上自动打开,导致多卡训练dump结果只有一组json,那么需要在训练代码中添加打开工具开关的调用。
在训练代码中添加数据dump操作如下:
```Python
import api_accuracy_checker.dump as DP
# 需要先修改enable_dataloader参数值为False
# 关闭torch.utils.data.dataloader加载数据时,下列代码须在训练step代码内添加
DP.dump.start() # 开启工具dump模块
...
DP.dump.stop() # 控制dump结束
DP.dump.step() # 在DP.dump.stop()后加入DP.dump.step()即可指定需要dump的step
```
上述代码要添加在迭代内,如对于[ModelLink](https://gitee.com/ascend/ModelLink)的LLAMA2-7B可以添加在training.py中train函数的iteration循环内。
- 如果训练脚本是通过torch.utils.data.dataloader方式加载数据。
首先,需要开启torch.utils.data.dataloader加载数据,操作如下:
```bash
cd att/debug/accuracy_tools/api_accuracy_checker
vi config.yaml
# 修改enable_dataloader参数值为True
```
其次,在训练脚本中加入以下代码导入工具dump模块,启动训练即可自动抓取网络所有API信息。
```python
import api_accuracy_checker.dump
```
工具默认抓取训练的**第二个迭代**并且在第二个迭代后会报错退出训练进程,可通过target_iter参数配置。
**报错信息如下,这个报错仅用于停止训练,属于正常现象**:
```bash
Exception: Model pretest: exit after iteration 1.
```
若报错信息不一致,可能是由于服务器的其他错误信息覆盖导致,可以尝试查找报错信息中的Exception。
dump信息默认会存盘到“./step1”路径下(相对于启动训练的路径),包括:
- forward_info_{pid}.json:前向API信息文件。
- backward_info_{pid}.json:反向API信息文件。
- stack_info_{pid}.json:调用栈信息文件。
forward_info与stack_info中的key值一一对应,用户可根据forward_info中API的key在stack_info中查询到其调用栈及代码行位置。
若有需要,用户可以通过msCheckerConfig.update_config来配置dump路径以及开启**真实数据模式**、指定dump某个step或配置**API dump白名单**,详见“**msCheckerConfig.update_config**”。
#### 真实数据模式
预检工具默认为随机数据模式,如果想要完全复刻整网的API运行情况,可以使用真实数据模式,添加以下代码即可:
```python
from api_accuracy_checker.dump import msCheckerConfig
msCheckerConfig.update_config(real_data=True)
```
#### API dump白名单
精度预检工具可以对指定API进行预检操作,可以在dump时的训练脚本中直接添加白名单参数,只dump指定的API数据,示例代码如下:
```python
from api_accuracy_checker.dump import msCheckerConfig
msCheckerConfig.update_config(white_list=["conv1d", "conv2d"])
```
配置的API名称须存在于[support_wrap_ops.yaml](./hook_module/support_wrap_ops.yaml)文件下。
#### 工具支持的API列表
预检工具维护固定的API支持列表,若需要删除或增加dump的API,可以在[support_wrap_ops.yaml](./hook_module/support_wrap_ops.yaml)文件内手动修改,如下示例:
```bash
functional: # functional为算子类别,找到对应的类别,在该类别下按照下列格式删除或添加API
- conv1d
- conv2d
- conv3d
```
#### msCheckerConfig.update_config
**功能说明**
配置精度预检dump时的属性。
可选配置。
**函数原型**
```python
msCheckerConfig.update_config(dump_path="./", real_data=False, target_iter=[1], white_list=[], enable_dataloader=False)
```
**参数说明**
| 参数名称 | 说明 | 是否必选 |
| ----------------- | ------------------------------------------------------------ | -------- |
| dump_path | 设置dump路径,默认为当前目录。若指定目录不存在,则自动创建。 | 否 |
| real_data | 真实数据模式,可取值True或False,默认为False,表示随机数据模式,配置为True后开启真实数据模式,dump信息增加forward_real_data和backward_real_data目录,目录下保存每个API输入的具体数值。 | 否 |
| target_iter | 指定dump某个step的数据,默认为[1],须指定为训练脚本中存在的step。target_iter为list格式,可配置逐个step,例如:target_iter=[0,1,2];也可以配置step范围,例如:target_iter=list(range(0,9)),表示dump第0到第8个step。 | 否 |
| white_list | API dump白名单,指定dump具体API数据,也可以直接配置预检的API白名单,详细请参见“**API预检白名单**”。参数示例:white_list=["conv1d", "conv2d"]。默认未配置白名单,即dump全量API数据。 | 否 |
| enable_dataloader | 自动dump数