文档
注册

数据dump比对使用指南

单机单卡场景

  1. dump整网数据。
    分别dump CPU或GPU以及NPU数据,在PyTorch训练脚本插入dump接口,示例代码如下(下面以NPU为例,CPU或GPU dump基本相同):
    from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
    # 在main函数开始前固定随机数
    seed_all() 
    
    # 配置dump数据的.pkl文件名和路径
    set_dump_path("./npu_dump.pkl", dump_tag='all') 
    
    # 注册dump回调函数
    register_hook(model, acc_cmp_dump) 
    
    ... 
    
    # 在第一个迭代开始的位置开启dump且不配置dump关闭,即dump整网数据,另外dump堆栈信息
    set_dump_switch("ON", mode="api_stack")

    dump文件目录结构如下,dump文件目录结构说明可参考dump文件目录结构

    all_v1.0
    └── rank1
        ├── api_stack_npu_dump
        │   ├── Functional_conv2d_0_forward_input.0.npy
        │   ├── Functional_conv2d_0_forward_output.npy
        │     .....
        │   ├── Torch_relu__9_forward_input.0.npy
        │   └── Torch_relu__9_forward_output.npy
        └── api_stack_npu_dump.pkl
  2. 比对整网数据。
    创建并配置精度比对脚本,以创建compare.py为例,示例代码如下:
    from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
    dump_result_param={
    "npu_pkl_path": "./api_stack_npu_dump.pkl",
    "bench_pkl_path": "./api_stack_gpu_dump.pkl",
    "npu_dump_data_dir": "./api_stack_npu_dump_20230104_13434",
    "bench_dump_data_dir": "./api_stack_gpu_dump_20230104_132544",
    "is_print_compare_log": True
    }
    compare(dump_result_param, "./output", True, stack_mode=True)
    执行比对:
    python3 compare.py
  3. 找出存在问题的API。

    在比对结果的csv文件中,通过对比dump出的数值,计算两者的余弦相似度、均方根误差和最大绝对误差,定位和排查NPU算子存在的计算精度问题。筛选出余弦相似度(Cosine)小于0.99,最大绝对值误差(MaxAbsError)大于0.001的第一个API,针对该API执行后续比对操作,分析该API存在的精度问题。以下图为例,发现第一个可能存在问题的API为67_VF_lstm_backward,则后续针对此API进行进一步dump。

    图1 比对结果csv文件样例
  4. 提取指定API的堆栈信息和dump数据统计信息。

    通过parse接口可以清晰的显示特定API的堆栈信息和dump数据统计信息,结合堆栈信息分析代码中可能存在的精度问题。

    创建并配置提取脚本,以创建parse.py为例,示例代码如下:
    from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
    # 提取dump信息中第1次调用的API:67_VF_lstm_backward的堆栈信息及数据统计信息
    parse("./npu_dump.pkl", "67_VF_lstm_backward")
    执行提取:
    python3 parse.py

    回显类似如下,用户可根据回显中的Trace back堆栈信息分析可能存在的精度问题:

    Statistic Info:
      [67_VF_lstm_backward_input.0][dtype: torch.float32][shape: [1, 3, 244, 244]][max: 4.149261951446533][min: -4.198638916015625][mean: 0.002332142787054181]
      [67_VF_lstm_backward_input.1][dtype: torch.float32][shape: [64, 3, 7, 7]][max: 0.1047200858592987][min: -0.10305210202932358][mean: 0.0004971990711055696]
      [67_VF_lstm_backward_output][dtype: torch.float32][shape: [1, 64, 122, 122]][max: 1.4602006673812866][min: -1.434123158454895][mean: -9.677638445282355e-05]
    
    Trace back(Functional_conv2d_0_forward_stack_info):
      File "npu_jd.py", line 35, in <module>
        output = model_npu(inputs)
      File "/usr/local/python3.7.5/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl
        return forward_call(*input, **kwargs)
      File "/usr/local/python3.7.5/lib/python3.7/site-packages/torchvision/models/resnet.py", line 285, in forward
        return self._forward_impl(x)
      ...
      ...
      File "/usr/local/python3.7.5/lib/python3.7/site-packages/ptdbg_ascend/hooks/wrap_functional.py", line 59, in functional_op_template
        return FunctionalOPTemplate(op_name, hook)(*args, **kwargs)
      File "/usr/local/python3.7.5/lib/python3.7/site-packages/ptdbg_ascend/hooks/module.py", line 70, in __call__
        hook_result = hook(self, input, result)

单机多卡场景

精度工具单机多卡场景下的精度比对步骤与单机单卡场景完全一致。唯一不同的是精度比对时需要使用compare_distributed函数进行比对:

  1. 创建比对脚本,例如compare_distributed.py。
    from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
    compare_distributed('npu_dump/dump_conv2d_v1.0', 'gpu_dump/dump_conv2d_v1.0', './output')
  2. 执行比对。
    python3 compare_distributed.py
  • 两次运行须用相同数量的卡,传入compare_distributed的两个文件夹下须有相同个数的rank文件夹,且不包含其他无关文件,否则将无法比对。
  • 单机多卡一般为多进程,须保证每个进程都正确调用set_dump_path,或把set_dump_path插入到import语句后,如:
    from ptdbg_ascend import register_hook, overflow_check, seed_all, set_dump_path, set_dump_switch, acc_cmp_dump
    seed_all()
    set_dump_path('./dump_resnet/myDump.pkl')

    如此可保证set_dump_path在每个进程都被调用。

  • register_hook需要在set_dump_path之后调用,也需要在每个进程上被调用,建议在搬运模型数据到卡之后调用。识别方法如下:
    • 找到训练代码中遍历epoch的for循环或遍历数据集的for循环,把register_hook放到循环开始前即可。
    • 找到训练代码中调用DDP或者DistributedDataParallel的代码行,把register_hook放到该代码行所在的代码块之后。
    • 若代码中均无以上两种情况,需要保证register_hook在模型定义之后插入,并配置rank参数,示例如下:
      register_hook(model, acc_cmp_dump, rank=rank_id)
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词