From 5b0eccf662786ee88ea4b86432544c7630ef7d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E4=BD=B3=E7=90=AA?= Date: Fri, 15 Aug 2025 10:24:20 +0800 Subject: [PATCH] dump_hash --- .../msprobe/core/common/const.py | 3 +- .../data_processor/mindspore_processor.py | 2 +- .../msprobe/docs/02.config_introduction.md | 6 +-- .../msprobe/docs/06.data_dump_MindSpore.md | 2 +- .../docs/28.debugger_save_instruction.md | 2 +- .../mindspore/dump/kernel_kbyk_dump.py | 27 ++++++++++++ .../msprobe/mindspore/ms_config.py | 7 +-- .../test_mindspore_processor.py | 20 +++++++++ .../mindspore_ut/test_kernel_kbyk_dump.py | 43 ++++++++++++++++++- 9 files changed, 101 insertions(+), 11 deletions(-) diff --git a/debug/accuracy_tools/msprobe/core/common/const.py b/debug/accuracy_tools/msprobe/core/common/const.py index 10ebcfe20bc..69237a65fb8 100644 --- a/debug/accuracy_tools/msprobe/core/common/const.py +++ b/debug/accuracy_tools/msprobe/core/common/const.py @@ -73,8 +73,9 @@ class Const: ONLINE_DUMP_MODE = [ALL, LIST, AUTO, OFF] SUMMARY = "summary" MD5 = "md5" + HASH = "hash" VALUE = "value" - SUMMARY_MODE = ["statistics", "md5"] + SUMMARY_MODE = ["statistics", "md5", "hash"] WRITE_FLAGS = os.O_WRONLY | os.O_CREAT WRITE_MODES = stat.S_IWUSR | stat.S_IRUSR diff --git a/debug/accuracy_tools/msprobe/core/data_dump/data_processor/mindspore_processor.py b/debug/accuracy_tools/msprobe/core/data_dump/data_processor/mindspore_processor.py index bc72d32b6ae..535b1db91ac 100644 --- a/debug/accuracy_tools/msprobe/core/data_dump/data_processor/mindspore_processor.py +++ b/debug/accuracy_tools/msprobe/core/data_dump/data_processor/mindspore_processor.py @@ -194,7 +194,7 @@ class MindsporeDataProcessor(BaseDataProcessor): tensor_json.update({Const.TENSOR_STAT_INDEX: placeholder_index}) - if self.config.summary_mode == Const.MD5 and not self.config.async_dump: + if (self.config.summary_mode in (Const.MD5, Const.HASH)) and not self.config.async_dump: tensor = convert_bf16_to_fp32(tensor) # 拷贝并搬到 CPU tensor_bytes = tensor.asnumpy().tobytes() diff --git a/debug/accuracy_tools/msprobe/docs/02.config_introduction.md b/debug/accuracy_tools/msprobe/docs/02.config_introduction.md index 7b70cd859eb..3e457217ace 100644 --- a/debug/accuracy_tools/msprobe/docs/02.config_introduction.md +++ b/debug/accuracy_tools/msprobe/docs/02.config_introduction.md @@ -50,14 +50,14 @@ data_modedump 数据过滤,str 类型。否PyTorch、MSAdapter 以及 MindSpore 动态图场景:支持"all"、"forward"、"backward"、"input"和"output",除"all"外,其余参数可以自由组合。默认为["all"],即保存所有 dump 的数据。
配置示例:"data_mode": ["backward"] (仅保存反向数据)或 "data_mode": ["forward", "input"](仅保存前向的输入数据)。 MindSpore 静态图场景:L0 级别 dump 仅支持"all"、"forward"和"backward"参数;L2 级别 dump 仅支持"all"、"input"和"output"参数。且各参数只能单独配置,不支持自由组合。
配置示例:"data_mode": ["all"]。 summary_mode控制 dump 文件输出的模式,str 类型,支持 PyTorch、MSAdapter、MindSpore 动态图以及 MindSpore 静态图 L2 级别 jit_level=O2 场景和 L0 级别 jit_level=O0/O1 场景。否 - PyTorch、MSAdapter 以及 MindSpore 动态图场景:可选参数为
md5:dump 输出包含 CRC-32 值以及 API 统计信息的 dump.json 文件,用于验证数据的完整性;
statistics:dump 仅输出包含 API 统计信息的 dump.json 文件,默认值。
配置示例:"summary_mode": "md5"。 + PyTorch、MSAdapter 以及 MindSpore 动态图场景:可选参数为
hash或md5:dump 输出包含 CRC-32 值以及 API 统计信息的 dump.json 文件,用于验证数据的完整性;
statistics:dump 仅输出包含 API 统计信息的 dump.json 文件,默认值。
配置示例:"summary_mode": "hash"或"summary_mode": "md5"。 MindSpore 静态图 L2 级别 jit_level=O2 场景:支持上述配置的同时额外支持配置统计项列表,可选统计项为max、min、mean、l2norm,可从中任意选取组合搭配。其中mean、l2norm的结果为float数据格式。
MindSpore 静态图 L0 级别 jit_level=O0/O1场景:仅支持上述配置中"statistics"字段和max、min、mean、l2norm中任意组合搭配的统计项列表。
配置示例:"summary_mode": ["max", "min"]。 **说明**: -1. "summary_mode" 配置为 "md5" 时,所使用的校验算法为 CRC-32 算法。 +1. "summary_mode" 配置为 "hash"或"md5" 时,所使用的校验算法为 CRC-32 算法。 **示例**: - [PyTorch场景](03.config_examples.md#11-task-配置为-statistics) @@ -72,7 +72,7 @@ | list | 与[ 1.2 task 配置为 statistics ](#12-task-配置为-statistics)中的解释相同。 | 否 | | data_mode | 与[ 1.2 task 配置为 statistics ](#12-task-配置为-statistics)中的解释相同 | 否 | | file_format | tensor 数据的保存格式,str 类型,仅支持 MindSpore 静态图场景的 L2 级别配置该字段,其他场景不生效。可选参数:
"bin":dump 的 tensor 文件为二进制格式;
"npy":dump 的 tensor 文件后缀为 .npy,默认值。 | 否 | -| summary_mode | 控制 dump 文件输出的模式,str 类型,支持 PyTorch、MSAdapter、MindSpore 动态图。可选参数:
md5:dump 输出包含 CRC-32 值以及 API 统计信息的 dump.json 文件,用于验证数据的完整性;
statistics:dump 仅输出包含 API 统计信息的 dump.json 文件,默认值。| 否 | +| summary_mode | 控制 dump 文件输出的模式,str 类型,支持 PyTorch、MSAdapter、MindSpore 动态图。可选参数:
hash或md5:dump 输出包含 CRC-32 值以及 API 统计信息的 dump.json 文件,用于验证数据的完整性;
statistics:dump 仅输出包含 API 统计信息的 dump.json 文件,默认值。| 否 | | online_run_uta | 在线预检模式开关,bool 类型,可选参数 true(开启)、false(关闭),默认未配置,表示关闭。配置为 true 表示开启在线预检。| 否 | | nfs_patha | 在线预检模式共享存储目录路径,str 类型,用于 GPU 设备和 NPU 设备间进行通信。仅在 online_run_ut 字段配置为 true 时生效,配置该参数后 host 和 port 不生效。 | 否 | | hosta | 在线预检模式局域网场景信息接收端 IP,str 类型,用于 GPU 设备和 NPU 设备间进行通信,NPU 侧须配置为 GPU 侧的局域网 IP 地址。仅在 online_run_ut 字段配置为 true 时生效,局域网场景时,不能配置 nfs_path 参数,否则局域网场景不生效。 | 否 | diff --git a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md index 50cc4585661..25ad0597843 100644 --- a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md +++ b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md @@ -549,7 +549,7 @@ dump 结果目录结构示例如下: * `rank`:设备 ID,每张卡的数据保存在对应的 `rank{ID}` 目录下。非分布式场景下没有 rank ID,目录名称为 rank。 * `dump_tensor_data`:保存采集到的张量数据。 -* `dump.json`: 保存API或Cell前反向数据的统计量信息。包含dump数据的API名称或Cell名称,各数据的dtype、 shape、max、min、mean、L2norm(L2范数,平方根)统计信息以及当配置summary_mode="md5"时的CRC-32数据。具体介绍可参考[dump.json文件说明](./27.dump_json_instruction.md#2-mindspore-场景下的-dumpjson-文件)。 +* `dump.json`: 保存API或Cell前反向数据的统计量信息。包含dump数据的API名称或Cell名称,各数据的dtype、 shape、max、min、mean、L2norm(L2范数,平方根)统计信息以及当配置summary_mode="hash"或"md5"时的CRC-32数据。具体介绍可参考[dump.json文件说明](./27.dump_json_instruction.md#2-mindspore-场景下的-dumpjson-文件)。 * `stack.json`:API/Cell的调用栈信息。 * `construct.json`:根据model层级展示分层分级结构,level为L1时,construct.json内容为空。 diff --git a/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md b/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md index f4eb3591b20..9a86991745e 100644 --- a/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md +++ b/debug/accuracy_tools/msprobe/docs/28.debugger_save_instruction.md @@ -37,7 +37,7 @@ L0, L1, mix级别的dump能力存在盲区,网络中的非API或module的输 | 参数 | 解释 | 是否必选 | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| summary_mode | 控制 dump 文件输出的模式,str 类型。支持传入"statistics", "md5"。 细节详见[statistics任务子配置项说明](./02.config_introduction.md#12-task-配置为-statistics) | 否 | +| summary_mode | 控制 dump 文件输出的模式,str 类型。支持传入"statistics", "hash", "md5"。 细节详见[statistics任务子配置项说明](./02.config_introduction.md#12-task-配置为-statistics) | 否 | "tensor" 任务无子配置项。 diff --git a/debug/accuracy_tools/msprobe/mindspore/dump/kernel_kbyk_dump.py b/debug/accuracy_tools/msprobe/mindspore/dump/kernel_kbyk_dump.py index 91a6ab93aba..8b25b17e01b 100644 --- a/debug/accuracy_tools/msprobe/mindspore/dump/kernel_kbyk_dump.py +++ b/debug/accuracy_tools/msprobe/mindspore/dump/kernel_kbyk_dump.py @@ -20,6 +20,9 @@ from msprobe.core.common.file_utils import create_directory, save_json from msprobe.mindspore.common.log import logger from msprobe.mindspore.debugger.debugger_config import DebuggerConfig +import mindspore as ms +ms_version = ms.__version__ + class KernelKbykDump: COMMON_SETTINGS = "common_dump_settings" @@ -39,6 +42,7 @@ class KernelKbykDump: common_set["input_output"] = 0 common_set["kernels"] = [] common_set["support_device"] = [0, 1, 2, 3, 4, 5, 6, 7] + common_set["statistic_category"] = [] if config.stat_cal_mode and config.device_stat_precision_mode: e2e_set = { @@ -71,9 +75,32 @@ class KernelKbykDump: common_set["input_output"] = 1 if config.data_mode[0] == Const.OUTPUT: common_set["input_output"] = 2 + if config.summary_mode: + if isinstance(config.summary_mode, str): + if config.summary_mode == Const.STATISTICS: + common_set["statistic_category"] = ["max", "min", "avg", "l2norm"] + else: + mode = self._process_hash(config.summary_mode) + common_set["statistic_category"] = [mode] + elif isinstance(config.summary_mode, list): + mode_set = set() + for mode in config.summary_mode: + if mode == Const.MEAN: + mode = "avg" + mode = self._process_hash(mode) + mode_set.add(mode) + common_set["statistic_category"] = list(mode_set) self.dump_json[KernelKbykDump.COMMON_SETTINGS] = common_set self.dump_json[KernelKbykDump.E2E_SETTINGS] = e2e_set + + @staticmethod + def _process_hash(value): + if ms_version <= "2.7.0" and (value == Const.HASH or value == Const.MD5): + value = "md5" + elif value == Const.MD5: + value = "hash:md5" + return value def handle(self): json_path = self.dump_json[KernelKbykDump.COMMON_SETTINGS]["path"] diff --git a/debug/accuracy_tools/msprobe/mindspore/ms_config.py b/debug/accuracy_tools/msprobe/mindspore/ms_config.py index 4b73ad5bdeb..d50b177a2fc 100644 --- a/debug/accuracy_tools/msprobe/mindspore/ms_config.py +++ b/debug/accuracy_tools/msprobe/mindspore/ms_config.py @@ -59,11 +59,12 @@ class StatisticsConfig(BaseConfig): raise Exception("Config param [precision] is invalid, expected from [\"high\", \"low\"]") def _check_summary_mode(self): - muti_opt = ["md5", "max", "min", "mean", "l2norm"] + muti_opt = ["max", "min", "mean", "count", "negative zero count", "positive zero count", "nan count", + "negative inf count", "positive inf count", "zero count", "l2norm", "hash", "md5"] if isinstance(self.summary_mode, str) and self.summary_mode not in Const.SUMMARY_MODE: - raise Exception("summary_mode is invalid") + raise Exception("summary_mode is an invalid string") if isinstance(self.summary_mode, list) and not all(opt in muti_opt for opt in self.summary_mode): - raise Exception("summary_mode is invalid") + raise Exception("summary_mode contains invalid option(s)") class OverflowCheckConfig(BaseConfig): diff --git a/debug/accuracy_tools/msprobe/test/core_ut/data_dump/data_processor/test_mindspore_processor.py b/debug/accuracy_tools/msprobe/test/core_ut/data_dump/data_processor/test_mindspore_processor.py index 46cc3b44747..2a35928e0fc 100644 --- a/debug/accuracy_tools/msprobe/test/core_ut/data_dump/data_processor/test_mindspore_processor.py +++ b/debug/accuracy_tools/msprobe/test/core_ut/data_dump/data_processor/test_mindspore_processor.py @@ -91,6 +91,25 @@ class TestMindsporeDataProcessor(unittest.TestCase): self.assertIsNone(result.mean) self.assertIsNone(result.norm) + @patch.object(MindsporeDataProcessor, 'get_md5_for_tensor') + def test_analyze_tensor_hash(self, get_md5_for_tensor): + get_md5_for_tensor.return_value = "test_md5" + tensor = ms.Tensor(np.array([1, 2, 3], dtype=np.int32)) + self.config.summary_mode = 'hash' + self.config.async_dump = False + suffix = "test_tensor" + expected_result = { + 'type': 'mindspore.Tensor', + 'dtype': 'Int32', + 'shape': (3,) + } + result = self.processor._analyze_tensor(tensor, suffix) + # 删除不必要的字段 + result.pop('tensor_stat_index', None) + result.pop('md5_index', None) + + self.assertEqual(result, expected_result) + class TestOverflowCheckDataProcessor(unittest.TestCase): def setUp(self): @@ -216,3 +235,4 @@ class TestKernelDumpDataProcessor(unittest.TestCase): self.processor.enable_kernel_dump = False self.processor.reset_status() self.assertTrue(self.processor.enable_kernel_dump) + diff --git a/debug/accuracy_tools/msprobe/test/mindspore_ut/test_kernel_kbyk_dump.py b/debug/accuracy_tools/msprobe/test/mindspore_ut/test_kernel_kbyk_dump.py index 9be887eb4be..655686c2606 100644 --- a/debug/accuracy_tools/msprobe/test/mindspore_ut/test_kernel_kbyk_dump.py +++ b/debug/accuracy_tools/msprobe/test/mindspore_ut/test_kernel_kbyk_dump.py @@ -24,6 +24,9 @@ from msprobe.mindspore.debugger.debugger_config import DebuggerConfig from msprobe.mindspore.ms_config import StatisticsConfig from msprobe.mindspore.dump.kernel_kbyk_dump import KernelKbykDump +import mindspore as ms +ms_version = ms.__version__ + class TestKernelKbykDump(TestCase): @patch("msprobe.mindspore.debugger.debugger_config.create_directory") @@ -379,4 +382,42 @@ class TestKernelKbykDump(TestCase): patch("msprobe.mindspore.dump.kernel_kbyk_dump.save_json") as mock_save_json: dumper.handle() mock_info.assert_called_with("/absolute_path/kernel_kbyk_dump.json has been created.") - self.assertEqual(os.environ.get("MS_ACL_DUMP_CFG_PATH"), None) \ No newline at end of file + self.assertEqual(os.environ.get("MS_ACL_DUMP_CFG_PATH"), None) + + @patch("msprobe.mindspore.debugger.debugger_config.create_directory") + def test_handle_statistics(self, _): + json_config = { + "task": "statistics", + "dump_path": "/absolute_path", + "rank": [], + "step": [0, 2], + "level": "L2", + "statistics": { + "list": [], + "data_mode": ["all"], + "device": "host", + "summary_mode": ["hash", "md5","max"] + } + } + + common_config = CommonConfig(json_config) + task_config = StatisticsConfig(json_config["statistics"]) + config = DebuggerConfig(common_config, task_config) + dumper = KernelKbykDump(config) + self.assertEqual(dumper.dump_json["e2e_dump_settings"]["stat_calc_mode"], "host") + self.assertEqual(dumper.dump_json["common_dump_settings"]["saved_data"], "statistic") + if ms_version > "2.7.0": + self.assertEqual(dumper.dump_json["common_dump_settings"]["statistic_category"], ["hash", "hash:md5", "max"]) + else: + self.assertEqual(dumper.dump_json["common_dump_settings"]["statistic_category"], ["md5", "max"]) + os.environ["MS_ACL_DUMP_CFG_PATH"] = "path" + with patch("msprobe.mindspore.dump.kernel_kbyk_dump.create_directory"), \ + patch("msprobe.mindspore.dump.kernel_kbyk_dump.logger.info") as mock_info, \ + patch("msprobe.mindspore.dump.kernel_kbyk_dump.save_json") as mock_save_json: + dumper.handle() + self.assertIn("kernel_kbyk_dump.json", mock_save_json.call_args_list[0][0][0]) + mock_info.assert_called_with("/absolute_path/kernel_kbyk_dump.json has been created.") + + self.assertEqual(os.environ.get("MS_ACL_DUMP_CFG_PATH"), None) + if "MINDSPORE_DUMP_CONFIG" in os.environ: + del os.environ["MINDSPORE_DUMP_CONFIG"] \ No newline at end of file -- Gitee