diff --git "a/debug/accuracy_tools/ptdbg_ascend/doc/ptdbg_ascend\347\262\276\345\272\246\345\267\245\345\205\267\345\212\237\350\203\275\350\257\264\346\230\216_v4.0.md" "b/debug/accuracy_tools/ptdbg_ascend/doc/ptdbg_ascend\347\262\276\345\272\246\345\267\245\345\205\267\345\212\237\350\203\275\350\257\264\346\230\216_v4.0.md"
index 23ee300d25593173f67910440ecfe9da854af05b..f13b3fe18fb23f77eb0e00581742eb988092627a 100644
--- "a/debug/accuracy_tools/ptdbg_ascend/doc/ptdbg_ascend\347\262\276\345\272\246\345\267\245\345\205\267\345\212\237\350\203\275\350\257\264\346\230\216_v4.0.md"
+++ "b/debug/accuracy_tools/ptdbg_ascend/doc/ptdbg_ascend\347\262\276\345\272\246\345\267\245\345\205\267\345\212\237\350\203\275\350\257\264\346\230\216_v4.0.md"
@@ -55,23 +55,23 @@ PyTorch训练场景的精度问题分析建议参考以下思路进行精度比
```python
from ptdbg_ascend import *
-
+
# 在main函数开始前固定随机数
seed_all()
-
+
# 配置dump数据目录路径和名称
set_dump_path("./npu_dump", dump_tag='all')
-
+
# 注册dump回调函数
register_hook(model, acc_cmp_dump)
-
+
...
-
+
# 在第一个迭代开始的位置开启dump和堆栈模式,同时为保证数据完整性开启dump bool和整型的tensor以及浮点、bool和整型的标量
set_dump_switch("ON", mode="api_stack", filter_switch="OFF")
-
+
...
-
+
# 在第一个迭代结束的位置关闭dump
set_dump_switch("OFF")
```
@@ -118,7 +118,7 @@ PyTorch训练场景的精度问题分析建议参考以下思路进行精度比
```python
from ptdbg_ascend import *
-
+
# 提取dump信息中第1次调用的API:Torch_batch_normal的堆栈信息及数据统计信息
parse("./npu_dump/all_v2.0/rank0/api_stack_dump.pkl", "Torch_batch_normal_1_forward")
```
@@ -137,17 +137,17 @@ PyTorch训练场景的精度问题分析建议参考以下思路进行精度比
```python
from ptdbg_ascend import *
-
+
# 固定随机数,开启确定性计算
seed_all(mode=True)
set_dump_path("./dump_path", dump_tag='forward')
register_hook(model, acc_cmp_dump, dump_mode='acl', dump_config='./dump.json')
-
+
# dump指定前向API的ACL级别数据、bool和整型的tensor以及浮点、bool和整型的标量
set_dump_switch("ON", mode="acl", scope=["Tensor_permute_1_forward"], filter_switch="OFF")
-
+
...
-
+
set_dump_switch("OFF")
```
@@ -155,18 +155,18 @@ PyTorch训练场景的精度问题分析建议参考以下思路进行精度比
```python
from ptdbg_ascend import *
-
+
# 固定随机数,开启确定性计算
seed_all(mode=True)
set_dump_path("./dump_path", dump_tag='backward')
register_hook(model, acc_cmp_dump, dump_mode='acl', dump_config='./dump.json')
-
+
# dump指定反向API的ACL级别数据、bool和整型的tensor以及浮点、bool和整型的标量
set_dump_switch("ON", mode="acl", scope=["Functional_conv2d_1_backward"], filter_switch="OFF")
set_backward_input(["./npu_dump/all_v2.0/rank0/api_stack_dump/Functional_conv2d_1_backward_input.0.npy"])
-
+
...
-
+
set_dump_switch("OFF")
```
@@ -454,7 +454,7 @@ PrecisionDebugger(dump_path=None, hook_name=None, rank=None, step=[], enable_dat
| rank | 指定对某张卡上的数据进行dump或溢出检测,默认未配置(表示dump所有卡的数据),须根据实际卡的Rank ID配置。应配置为大于0的正整数,且须根据实际卡的Rank ID配置,若所配置的值大于实际训练所运行的卡的Rank ID,则dump数据为空,比如当前环境Rank ID为0~7,实际训练运行0~3卡,此时若配置Rank ID为4或不存在的10等其他值,此时dump数据为空。 | 否 |
| step | 指定dump某个step的数据,默认未配置,须指定为训练脚本中存在的step。step为list格式,可配置逐个step,例如:step=[0,1,2];也可以配置step范围,例如:step=list(range(0,9)),表示dump第0到第8个step。 | 否 |
| enable_dataloader | 自动控制开关,可取值True(开启)或False(关闭),默认为False。配置为True后自动识别dump step参数指定的迭代,并在该迭代执行完成后退出训练,此时start和stop函数可不配置,开启该开关要求训练脚本是通过torch.utils.data.dataloader方式加载数据;配置为False则需要配置start和stop函数,并在最后一个stop函数后或一个step结束的位置添加debugger.step()。 | 否 |
-| model | 开启model模式,传入网络模型实例化的对象,配置该参数后,dump操作仅dump网络中init方法里调用的方法(nn.Module类),不会对所有API进行dump。参数示例: model=net,net为网络模型实例化的对象名称。默认未配置。
配置该参数时,PrecisionDebugger模块请在模型实例化之后调用。
该模式不支持“溢出检测”和“模块级精度数据dump”。 | 否 |
+| model | 开启init dump模式,传入网络模型实例化的对象,配置该参数后,dump操作仅dump网络中init方法里调用的方法(nn.Module类),不会对所有API进行dump。参数示例: model=net,net为网络模型实例化的对象名称。默认未配置。
配置该参数时,PrecisionDebugger模块请在模型实例化之后调用。
该模式不支持“溢出检测”和“模块级精度数据dump”。此模式下dump文件名前缀为网络中定义的模块名或层名。 | 否 |
### configure_hook函数(可选)
@@ -593,9 +593,9 @@ configure_hook可配置多种dump模式,示例如下:
debugger = PrecisionDebugger(dump_path="./dump_path", hook_name="overflow_check", step=[0])
debugger.configure_hook(mode="acl", acl_config="./dump.json")
```
-
+
该场景会在原有数据基础上,额外在dump.json文件配置的dump_path目录下生成一份ACL算子数据,该数据可通过“**ptdbg_ascend.parse**”工具进行解析。
-
+
仅支持NPU环境。
### start函数(可选)
@@ -854,7 +854,7 @@ register_hook(model, hook, overflow_nums=overflow_nums, dump_mode=dump_mode, dum
| model | 传入网络模型实例化的对象。参数示例: model=net,net为网络模型实例化的对象名称。 | 是 |
| hook | 注册工具的dump和溢出检测钩子。可取值overflow_check(表示溢出检测)和acc_cmp_dump(表示dump数据),二选一。 | 是 |
| overflow_nums | 控制溢出次数,表示第N次溢出时,停止训练,过程中检测到溢出API对应ACL数据均dump。参数示例:overflow_nums=3。配置overflow_check时可配置,默认不配置,即检测到1次溢出,训练停止,配置为-1时,表示持续检测溢出直到训练结束。 | 否 |
-| dump_mode | 控制针对溢出API的dump模式,可取值"model"、"acl"或"api"。配置为"model"时,表示开启model模式,dump操作仅dump网络中init方法里调用的方法(nn.Module类),不会对所有API进行dump,不支持“溢出检测”和“模块级精度数据dump”;配置acl时,表示dump ACL级别的溢出数据,此时set_dump_path参数不生效,dump数据目录由dump_config的.json文件配置。参数示例:dump_mode="acl"。默认不配置,即dump API级别的溢出数据。 | 否 |
+| dump_mode | 控制针对溢出API的dump模式,可取值"acl"或"api"。配置acl时,表示dump ACL级别的溢出数据,此时set_dump_path参数不生效,dump数据目录由dump_config的.json文件配置。参数示例:dump_mode="acl"。默认不配置,即dump API级别的溢出数据。 | 否 |
| dump_config | acl dump的配置文件。dump_mode="acl"时,该参数必选;dump_mode="api"或"model"时,该参数不选。参数示例:dump_config='./dump.json'。 | 否 |
**函数示例**
diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/utils.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/utils.py
index 942391d4b101f7012348cf7491d86f777f106eef..ec40e2c6c85687843abd731258347c50555386b4 100644
--- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/utils.py
+++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/utils.py
@@ -68,7 +68,7 @@ class Const:
DUMP_RATIO_MAX = 100
SUMMERY_DATA_NUMS = 256
FLOAT_EPSILON = np.finfo(float).eps
- SUPPORT_DUMP_MODE = ['api', 'acl', 'model']
+ SUPPORT_DUMP_MODE = ['api', 'acl']
ON = 'ON'
OFF = 'OFF'
BACKWARD = 'backward'
diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/dump/dump.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/dump/dump.py
index 2a00f83bf5852e32173ae274c2205e6f2fb022a7..83900eb60c4b591437b4a78a5022a91b944c458a 100644
--- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/dump/dump.py
+++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/dump/dump.py
@@ -32,8 +32,10 @@ except ImportError:
else:
is_gpu = False
-from .utils import DumpUtil, check_if_in_api_list, make_dump_data_dir, get_tensor_rank, create_dirs_if_not_exist
-from ..common.utils import print_warn_log, Const, print_info_log, modify_dump_path, check_inplace_op, CompareConst
+from .utils import DumpUtil, check_if_in_api_list, make_dump_data_dir, get_tensor_rank, create_dirs_if_not_exist,\
+ CompareException
+from ..common.utils import print_warn_log, Const, print_info_log, modify_dump_path, check_inplace_op, CompareConst,\
+ print_error_log
from ..dump.utils import check_writable
from ..common.file_check_util import FileOpen, change_mode, FileCheckConst, check_path_pattern_vaild, check_path_length
@@ -44,7 +46,7 @@ thread_lock = threading.Lock()
pkl_name = ""
rank = os.getpid()
multi_output_apis = ["_sort_", "npu_flash_attention"]
-module_count = defaultdict(int)
+module_count = {}
class APIList(list):
@@ -367,22 +369,38 @@ def dump_mode_backward_acl_dump(module, module_name, grad_path):
print_info_log("Dump %s op file." % module_name)
+def module_count_func(name, name_template):
+ module_name = name.split("_")[-3]
+ if Const.FORWARD in name_template:
+ if module_name not in module_count:
+ module_count[module_name] = [0, [0]]
+ else:
+ if module_count[module_name][-1] and \
+ module_count[module_name][0] != module_count[module_name][-1][-1]:
+ module_count[module_name][-1].pop()
+ module_count[module_name][0] += 1
+ module_count[module_name][-1].append(module_count[module_name][0])
+ index = module_count[module_name][0]
+ else:
+ index = module_count[module_name][-1].pop()
+ return index
+
+
def acc_cmp_dump(name, **kwargs):
dump_step = kwargs.get('dump_step', 1)
pid = kwargs.get('pid')
+ name_template = name
if not pid:
return RuntimeError("Not get the specified process pid.")
def acc_cmp_hook(module, in_feat, out_feat=None):
- nonlocal name
- if "_{}_" in name:
- module_name = name.split("_")[1]
- if Const.BACKWARD in name:
- index = module_count[module_name] - 1
- module_count[module_name] = index
- else:
- index = module_count[module_name]
- module_count[module_name] = index + 1
+ nonlocal name, name_template
+ if "_{}_" in name_template:
+ try:
+ index = module_count_func(name, name_template)
+ except IndexError as e:
+ print_error_log(f"Get module {name_template} index failed.")
+ raise CompareException(CompareException.INDEX_OUT_OF_BOUNDS_ERROR) from e
name = name.format(index)
if pid == os.getpid():
dump_acc_cmp(name, in_feat, out_feat, dump_step, module)
diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/hook_module/register_hook.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/hook_module/register_hook.py
index 5297ed70e21a3c42e24490bf0a178de2e2c27553..bc6b9c4949bc92abd5dac60b944c2e02a03bdfef 100644
--- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/hook_module/register_hook.py
+++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/hook_module/register_hook.py
@@ -70,10 +70,7 @@ def register_hook(model, hook, **kwargs):
if dump_mode == 'acl':
DumpUtil.dump_switch_mode = dump_mode
DumpUtil.set_acl_config(dump_config_file)
- if dump_mode == 'model':
- register_hook_core(hook, model)
- else:
- register_hook_core(hook)
+ register_hook_core(hook)
def init_overflow_nums(overflow_nums):
@@ -127,11 +124,12 @@ def register_hook_core(hook, model=None):
if not isinstance(model, torch.nn.Module):
print_error_log("The argument model must be an object of torch.nn.Module")
raise CompareException(CompareException.INVALID_PARAM_ERROR)
- for _, module in model.named_modules():
- if "torch.nn.modules" in str(module.__class__):
- prefix = "Module_" + module.__class__.__name__
- module.register_forward_hook(hook(prefix + "_{}_" + "forward"))
- module.register_backward_hook(hook(prefix + "_{}_" + "backward"))
+ for name, module in model.named_modules():
+ if module == model:
+ continue
+ prefix = name + "_" + module.__class__.__name__
+ module.register_forward_hook(hook(prefix + "_{}_" + "forward"))
+ module.register_backward_hook(hook(prefix + "_{}_" + "backward"))
else:
api_register.initialize_hook(hook)
api_register.api_modularity()