mindstudio-probe 1.2.2__py3-none-any.whl → 8.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/METADATA +4 -3
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/RECORD +243 -191
- msprobe/README.md +57 -21
- msprobe/core/__init__.py +17 -0
- msprobe/core/common/const.py +224 -82
- msprobe/core/common/decorator.py +50 -0
- msprobe/core/common/exceptions.py +5 -3
- msprobe/core/common/file_utils.py +274 -40
- msprobe/core/common/framework_adapter.py +169 -0
- msprobe/core/common/global_lock.py +86 -0
- msprobe/core/common/runtime.py +25 -0
- msprobe/core/common/utils.py +148 -72
- msprobe/core/common_config.py +7 -0
- msprobe/core/compare/acc_compare.py +640 -462
- msprobe/core/compare/check.py +36 -107
- msprobe/core/compare/compare_cli.py +4 -0
- msprobe/core/compare/config.py +72 -0
- msprobe/core/compare/highlight.py +217 -215
- msprobe/core/compare/layer_mapping/layer_mapping.py +4 -1
- msprobe/core/compare/merge_result/merge_result.py +12 -6
- msprobe/core/compare/multiprocessing_compute.py +227 -107
- msprobe/core/compare/npy_compare.py +32 -16
- msprobe/core/compare/utils.py +218 -244
- msprobe/{mindspore/runtime.py → core/config_check/__init__.py} +2 -4
- msprobe/{pytorch/dump/kernel_dump/kernel_config.py → core/config_check/checkers/__init__.py} +8 -16
- msprobe/core/config_check/checkers/base_checker.py +60 -0
- msprobe/core/config_check/checkers/dataset_checker.py +138 -0
- msprobe/core/config_check/checkers/env_args_checker.py +96 -0
- msprobe/core/config_check/checkers/hyperparameter_checker.py +170 -0
- msprobe/core/config_check/checkers/pip_checker.py +90 -0
- msprobe/core/config_check/checkers/random_checker.py +367 -0
- msprobe/core/config_check/checkers/weights_checker.py +147 -0
- msprobe/core/config_check/ckpt_compare/ckpt_comparator.py +74 -0
- msprobe/core/config_check/ckpt_compare/megatron_loader.py +302 -0
- msprobe/core/config_check/ckpt_compare/metrics.py +83 -0
- msprobe/core/config_check/ckpt_compare/name_mapping.yaml +12 -0
- msprobe/core/config_check/config_check_cli.py +51 -0
- msprobe/core/config_check/config_checker.py +100 -0
- msprobe/{pytorch/parse.py → core/config_check/resource/dependency.yaml} +7 -4
- msprobe/core/config_check/resource/env.yaml +57 -0
- msprobe/core/config_check/resource/hyperparameter.yaml +21 -0
- msprobe/core/config_check/utils/hyperparameter_parser.py +115 -0
- msprobe/core/config_check/utils/utils.py +107 -0
- msprobe/core/data_dump/api_registry.py +239 -0
- msprobe/core/data_dump/data_collector.py +36 -9
- msprobe/core/data_dump/data_processor/base.py +74 -53
- msprobe/core/data_dump/data_processor/mindspore_processor.py +119 -78
- msprobe/core/data_dump/data_processor/pytorch_processor.py +134 -96
- msprobe/core/data_dump/json_writer.py +146 -57
- msprobe/core/debugger/precision_debugger.py +143 -0
- msprobe/core/grad_probe/constant.py +2 -1
- msprobe/core/grad_probe/grad_compare.py +2 -2
- msprobe/core/grad_probe/utils.py +1 -1
- msprobe/core/hook_manager.py +242 -0
- msprobe/core/monitor/anomaly_processor.py +384 -0
- msprobe/core/overflow_check/abnormal_scene.py +2 -0
- msprobe/core/service.py +356 -0
- msprobe/core/single_save/__init__.py +0 -0
- msprobe/core/single_save/single_comparator.py +243 -0
- msprobe/core/single_save/single_saver.py +157 -0
- msprobe/docs/01.installation.md +6 -5
- msprobe/docs/02.config_introduction.md +89 -30
- msprobe/docs/03.config_examples.md +1 -0
- msprobe/docs/04.kernel_dump_PyTorch.md +1 -1
- msprobe/docs/05.data_dump_PyTorch.md +184 -50
- msprobe/docs/06.data_dump_MindSpore.md +193 -28
- msprobe/docs/07.accuracy_checker_PyTorch.md +13 -3
- msprobe/docs/08.accuracy_checker_online_PyTorch.md +72 -10
- msprobe/docs/09.accuracy_checker_MindSpore.md +19 -7
- msprobe/docs/10.accuracy_compare_PyTorch.md +266 -102
- msprobe/docs/11.accuracy_compare_MindSpore.md +117 -43
- msprobe/docs/12.overflow_check_PyTorch.md +5 -3
- msprobe/docs/13.overflow_check_MindSpore.md +6 -4
- msprobe/docs/14.data_parse_PyTorch.md +4 -10
- msprobe/docs/17.grad_probe.md +2 -1
- msprobe/docs/18.online_dispatch.md +3 -3
- msprobe/docs/19.monitor.md +211 -103
- msprobe/docs/21.visualization_PyTorch.md +100 -28
- msprobe/docs/22.visualization_MindSpore.md +103 -31
- msprobe/docs/23.generate_operator_PyTorch.md +9 -9
- msprobe/docs/25.tool_function_introduction.md +23 -22
- msprobe/docs/26.data_dump_PyTorch_baseline.md +14 -3
- msprobe/docs/27.dump_json_instruction.md +278 -8
- msprobe/docs/28.debugger_save_instruction.md +111 -20
- msprobe/docs/28.kernel_dump_MindSpore.md +1 -1
- msprobe/docs/29.data_dump_MSAdapter.md +229 -0
- msprobe/docs/30.overflow_check_MSAdapter.md +31 -0
- msprobe/docs/31.config_check.md +95 -0
- msprobe/docs/32.ckpt_compare.md +69 -0
- msprobe/docs/33.generate_operator_MindSpore.md +190 -0
- msprobe/docs/34.RL_collect.md +92 -0
- msprobe/docs/35.nan_analyze.md +72 -0
- msprobe/docs/FAQ.md +3 -11
- msprobe/docs/data_dump_MindSpore/data_dump_MindSpore_baseline.md +12 -1
- msprobe/docs/data_dump_MindSpore/dynamic_graph_quick_start_example.md +3 -1
- msprobe/docs/img/compare_result.png +0 -0
- msprobe/docs/img/merge_result.png +0 -0
- msprobe/docs/img/save_compare_result_sample.png +0 -0
- msprobe/docs/img/visualization/proxy.png +0 -0
- msprobe/docs/img/visualization/vis_browser_1.png +0 -0
- msprobe/docs/img/visualization/vis_match_info.png +0 -0
- msprobe/docs/img/visualization/vis_precision_info.png +0 -0
- msprobe/docs/img/visualization/vis_search_info.png +0 -0
- msprobe/docs/img/visualization/vis_show_info.png +0 -0
- msprobe/docs/img/visualization/vis_showcase.png +0 -0
- msprobe/docs/img/visualization/vis_unmatch_info.png +0 -0
- msprobe/mindspore/__init__.py +3 -3
- msprobe/mindspore/api_accuracy_checker/api_accuracy_checker.py +151 -55
- msprobe/mindspore/api_accuracy_checker/api_runner.py +25 -11
- msprobe/mindspore/api_accuracy_checker/base_compare_algorithm.py +2 -1
- msprobe/mindspore/api_accuracy_checker/bench_functions/flash_attention_score.py +580 -0
- msprobe/mindspore/api_accuracy_checker/bench_functions/fusion_operator.py +41 -0
- msprobe/mindspore/api_accuracy_checker/cmd_parser.py +4 -0
- msprobe/mindspore/api_accuracy_checker/data_manager.py +4 -3
- msprobe/mindspore/api_accuracy_checker/generate_op_script/config_op.json +9 -0
- msprobe/mindspore/api_accuracy_checker/generate_op_script/op_generator.py +451 -0
- msprobe/mindspore/api_accuracy_checker/generate_op_script/operator_replication.template +2081 -0
- msprobe/mindspore/api_accuracy_checker/multi_api_accuracy_checker.py +11 -1
- msprobe/mindspore/api_accuracy_checker/torch_mindtorch_importer.py +2 -1
- msprobe/mindspore/cell_processor.py +204 -33
- msprobe/mindspore/code_mapping/graph_parser.py +4 -21
- msprobe/mindspore/common/const.py +73 -2
- msprobe/mindspore/common/utils.py +157 -29
- msprobe/mindspore/compare/common_dir_compare.py +382 -0
- msprobe/mindspore/compare/distributed_compare.py +2 -26
- msprobe/mindspore/compare/ms_compare.py +18 -398
- msprobe/mindspore/compare/ms_graph_compare.py +20 -10
- msprobe/mindspore/compare/utils.py +37 -0
- msprobe/mindspore/debugger/debugger_config.py +59 -7
- msprobe/mindspore/debugger/precision_debugger.py +83 -90
- msprobe/mindspore/dump/cell_dump_process.py +902 -0
- msprobe/mindspore/dump/cell_dump_with_insert_gradient.py +889 -0
- msprobe/mindspore/dump/dump_tool_factory.py +18 -8
- msprobe/mindspore/dump/graph_mode_cell_dump.py +139 -0
- msprobe/mindspore/dump/graph_tensor_dump.py +123 -0
- msprobe/mindspore/dump/hook_cell/api_register.py +176 -0
- msprobe/mindspore/dump/hook_cell/hook_cell.py +22 -12
- msprobe/mindspore/dump/hook_cell/ms_hook_manager.py +88 -0
- msprobe/mindspore/dump/hook_cell/primitive_hooks.py +8 -2
- msprobe/mindspore/dump/hook_cell/support_wrap_ops.yaml +42 -26
- msprobe/mindspore/dump/jit_dump.py +35 -27
- msprobe/mindspore/dump/kernel_kbyk_dump.py +6 -3
- msprobe/mindspore/dym_loader/hook_dynamic_loader.cpp +110 -0
- msprobe/mindspore/dym_loader/hook_dynamic_loader.h +15 -16
- msprobe/mindspore/free_benchmark/api_pynative_self_check.py +22 -12
- msprobe/mindspore/free_benchmark/common/utils.py +1 -1
- msprobe/mindspore/free_benchmark/perturbation/perturbation_factory.py +4 -2
- msprobe/mindspore/free_benchmark/self_check_tool_factory.py +6 -3
- msprobe/mindspore/grad_probe/global_context.py +9 -2
- msprobe/mindspore/grad_probe/grad_analyzer.py +2 -1
- msprobe/mindspore/grad_probe/grad_stat_csv.py +3 -2
- msprobe/mindspore/grad_probe/hook.py +2 -4
- msprobe/mindspore/mindspore_service.py +111 -0
- msprobe/mindspore/monitor/common_func.py +52 -0
- msprobe/mindspore/monitor/data_writers.py +237 -0
- msprobe/mindspore/monitor/distributed/wrap_distributed.py +1 -1
- msprobe/mindspore/monitor/features.py +13 -1
- msprobe/mindspore/monitor/module_hook.py +568 -444
- msprobe/mindspore/monitor/optimizer_collect.py +331 -0
- msprobe/mindspore/monitor/utils.py +71 -9
- msprobe/mindspore/ms_config.py +16 -15
- msprobe/mindspore/overflow_check/overflow_check_tool_factory.py +5 -3
- msprobe/mindspore/task_handler_factory.py +5 -2
- msprobe/msprobe.py +19 -0
- msprobe/nan_analyze/__init__.py +14 -0
- msprobe/nan_analyze/analyzer.py +255 -0
- msprobe/nan_analyze/graph.py +189 -0
- msprobe/nan_analyze/utils.py +211 -0
- msprobe/pytorch/api_accuracy_checker/common/config.py +2 -2
- msprobe/pytorch/api_accuracy_checker/compare/api_precision_compare.py +3 -6
- msprobe/pytorch/api_accuracy_checker/compare/compare.py +36 -34
- msprobe/pytorch/api_accuracy_checker/generate_op_script/op_generator.py +15 -13
- msprobe/pytorch/api_accuracy_checker/generate_op_script/operator_replication.template +206 -4
- msprobe/pytorch/api_accuracy_checker/run_ut/multi_run_ut.py +9 -9
- msprobe/pytorch/api_accuracy_checker/run_ut/run_overflow_check.py +6 -5
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut.py +31 -9
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut_utils.py +28 -20
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/attl.py +3 -1
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/client.py +29 -13
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/device_dispatch.py +12 -2
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/server.py +45 -31
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/utils.py +154 -0
- msprobe/pytorch/attl_manager.py +65 -0
- msprobe/pytorch/bench_functions/moe_gating_top_k_softmax.py +6 -0
- msprobe/pytorch/bench_functions/npu_fusion_attention.py +27 -0
- msprobe/pytorch/common/utils.py +53 -19
- msprobe/pytorch/compare/distributed_compare.py +4 -36
- msprobe/pytorch/compare/pt_compare.py +13 -84
- msprobe/pytorch/compare/utils.py +47 -0
- msprobe/pytorch/debugger/debugger_config.py +34 -17
- msprobe/pytorch/debugger/precision_debugger.py +50 -96
- msprobe/pytorch/dump/module_dump/hook_wrapper.py +93 -0
- msprobe/pytorch/dump/module_dump/module_dump.py +15 -61
- msprobe/pytorch/dump/module_dump/module_processer.py +150 -114
- msprobe/pytorch/free_benchmark/common/utils.py +1 -1
- msprobe/pytorch/free_benchmark/compare/single_benchmark.py +1 -1
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/add_noise.py +3 -3
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/bit_noise.py +3 -3
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/change_value.py +1 -1
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/improve_precision.py +1 -1
- msprobe/pytorch/free_benchmark/result_handlers/check_handler.py +1 -1
- msprobe/pytorch/function_factory.py +1 -1
- msprobe/pytorch/grad_probe/grad_monitor.py +2 -2
- msprobe/pytorch/grad_probe/grad_stat_csv.py +3 -2
- msprobe/pytorch/hook_module/api_register.py +155 -0
- msprobe/pytorch/hook_module/hook_module.py +18 -22
- msprobe/pytorch/hook_module/jit_script_wrapper.py +33 -0
- msprobe/pytorch/hook_module/pt_hook_manager.py +68 -0
- msprobe/pytorch/hook_module/register_optimizer_hook.py +2 -1
- msprobe/pytorch/hook_module/support_wrap_ops.yaml +193 -75
- msprobe/pytorch/hook_module/utils.py +28 -2
- msprobe/pytorch/monitor/csv2tb.py +14 -4
- msprobe/pytorch/monitor/data_writers.py +259 -0
- msprobe/pytorch/monitor/distributed/wrap_distributed.py +8 -2
- msprobe/pytorch/monitor/module_hook.py +336 -241
- msprobe/pytorch/monitor/module_metric.py +17 -0
- msprobe/pytorch/monitor/optimizer_collect.py +244 -224
- msprobe/pytorch/monitor/utils.py +84 -4
- msprobe/pytorch/online_dispatch/compare.py +0 -2
- msprobe/pytorch/online_dispatch/dispatch.py +13 -2
- msprobe/pytorch/online_dispatch/dump_compare.py +8 -2
- msprobe/pytorch/online_dispatch/utils.py +3 -0
- msprobe/pytorch/parse_tool/lib/interactive_cli.py +1 -6
- msprobe/pytorch/parse_tool/lib/utils.py +5 -4
- msprobe/pytorch/pt_config.py +16 -11
- msprobe/pytorch/pytorch_service.py +70 -0
- msprobe/visualization/builder/graph_builder.py +69 -10
- msprobe/visualization/builder/msprobe_adapter.py +24 -12
- msprobe/visualization/compare/graph_comparator.py +63 -51
- msprobe/visualization/compare/mode_adapter.py +22 -20
- msprobe/visualization/graph/base_node.py +11 -4
- msprobe/visualization/graph/distributed_analyzer.py +1 -10
- msprobe/visualization/graph/graph.py +2 -13
- msprobe/visualization/graph/node_op.py +1 -2
- msprobe/visualization/graph_service.py +251 -104
- msprobe/visualization/utils.py +26 -44
- msprobe/mindspore/dump/hook_cell/api_registry.py +0 -207
- msprobe/mindspore/dump/hook_cell/wrap_api.py +0 -212
- msprobe/mindspore/dym_loader/hook_dynamic_loader.cc +0 -140
- msprobe/mindspore/monitor/anomaly_detect.py +0 -404
- msprobe/mindspore/monitor/module_spec_verifier.py +0 -94
- msprobe/mindspore/service.py +0 -543
- msprobe/pytorch/hook_module/api_registry.py +0 -166
- msprobe/pytorch/hook_module/wrap_distributed.py +0 -79
- msprobe/pytorch/hook_module/wrap_functional.py +0 -66
- msprobe/pytorch/hook_module/wrap_npu_custom.py +0 -85
- msprobe/pytorch/hook_module/wrap_tensor.py +0 -69
- msprobe/pytorch/hook_module/wrap_torch.py +0 -84
- msprobe/pytorch/hook_module/wrap_vf.py +0 -60
- msprobe/pytorch/monitor/anomaly_analyse.py +0 -201
- msprobe/pytorch/monitor/anomaly_detect.py +0 -410
- msprobe/pytorch/monitor/module_spec_verifier.py +0 -95
- msprobe/pytorch/monitor/unittest/test_monitor.py +0 -160
- msprobe/pytorch/service.py +0 -470
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/LICENSE +0 -0
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/WHEEL +0 -0
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/entry_points.txt +0 -0
- {mindstudio_probe-1.2.2.dist-info → mindstudio_probe-8.1.0.dist-info}/top_level.txt +0 -0
- /msprobe/{mindspore → core}/compare/ms_to_pt_api.yaml +0 -0
- /msprobe/{mindspore/dump → core}/kernel_dump/kernel_config.py +0 -0
- /msprobe/{pytorch/monitor/unittest → core/monitor}/__init__.py +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Copyright (c) 2024-2024, Huawei Technologies Co., Ltd.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
import pandas as pd
|
|
19
|
+
from msprobe.core.common.file_utils import create_file_in_zip, load_json
|
|
20
|
+
from msprobe.core.config_check.checkers.base_checker import BaseChecker
|
|
21
|
+
from msprobe.core.config_check.config_checker import register_checker_item, register_pre_forward_fun_list
|
|
22
|
+
from msprobe.core.config_check.utils.utils import config_checking_print, get_tensor_features
|
|
23
|
+
from msprobe.core.common.decorator import recursion_depth_decorator
|
|
24
|
+
from msprobe.core.common.framework_adapter import FmkAdp
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@recursion_depth_decorator("config_check: process_obj")
|
|
28
|
+
def process_obj(obj):
|
|
29
|
+
if FmkAdp.is_tensor(obj):
|
|
30
|
+
return get_tensor_features(obj)
|
|
31
|
+
elif isinstance(obj, (tuple, list)):
|
|
32
|
+
return {i: process_obj(x) for i, x in enumerate(obj)}
|
|
33
|
+
elif isinstance(obj, dict):
|
|
34
|
+
return {k: process_obj(v) for k, v in obj.items()}
|
|
35
|
+
else:
|
|
36
|
+
return ""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_args_and_kargs(args, kwargs):
|
|
40
|
+
processed_args = process_obj(args)
|
|
41
|
+
processed_kargs = process_obj(kwargs)
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
'args': processed_args,
|
|
45
|
+
'kwargs': processed_kargs
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@recursion_depth_decorator("config_check: compare_dataset_dicts")
|
|
50
|
+
def compare_dataset_dicts(dict1, dict2, tag=''):
|
|
51
|
+
results = []
|
|
52
|
+
# 处理 dict1 中的键
|
|
53
|
+
for key in dict1:
|
|
54
|
+
new_tag = f"{tag}.{key}" if tag else key
|
|
55
|
+
if key not in dict2:
|
|
56
|
+
result = {'tag': new_tag, 'equal': False, 'status': 'delete'}
|
|
57
|
+
results.append(result)
|
|
58
|
+
continue
|
|
59
|
+
value1 = dict1[key]
|
|
60
|
+
value2 = dict2[key]
|
|
61
|
+
if not isinstance(value1, dict):
|
|
62
|
+
continue
|
|
63
|
+
if set(value1.keys()) == {'max', 'min', 'mean', 'norm'}:
|
|
64
|
+
equal = value1 == value2
|
|
65
|
+
relative_diffs = {
|
|
66
|
+
f"{k}_relative_diff": (abs(value1[k] - value2[k]) / value1[k]) if value1[k] != 0 else None
|
|
67
|
+
for k in ['max', 'min', 'mean', 'norm']
|
|
68
|
+
}
|
|
69
|
+
result = {'tag': new_tag, 'equal': equal, 'status': 'unchanged'}
|
|
70
|
+
result.update(relative_diffs)
|
|
71
|
+
results.append(result)
|
|
72
|
+
else:
|
|
73
|
+
results.extend(compare_dataset_dicts(value1, value2, new_tag))
|
|
74
|
+
# 处理 dict2 中独有的键
|
|
75
|
+
for key in dict2:
|
|
76
|
+
if key not in dict1:
|
|
77
|
+
new_tag = f"{tag}.{key}" if tag else key
|
|
78
|
+
result = {'tag': new_tag, 'equal': False, 'status': 'added'}
|
|
79
|
+
results.append(result)
|
|
80
|
+
return results
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def compare_dataset(bench_dir, cmp_dir):
|
|
84
|
+
all_results = []
|
|
85
|
+
for step in os.listdir(bench_dir):
|
|
86
|
+
step_path_bench = os.path.join(bench_dir, step)
|
|
87
|
+
if not os.path.isdir(step_path_bench):
|
|
88
|
+
continue
|
|
89
|
+
step_path_cmp = os.path.join(cmp_dir, step)
|
|
90
|
+
for rank in os.listdir(step_path_bench):
|
|
91
|
+
rank_path_bench = os.path.join(step_path_bench, rank, 'dataset.json')
|
|
92
|
+
rank_path_cmp = os.path.join(step_path_cmp, rank, 'dataset.json')
|
|
93
|
+
if not os.path.isfile(rank_path_bench) or not os.path.isfile(rank_path_cmp):
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
dict1 = load_json(rank_path_bench)
|
|
97
|
+
dict2 = load_json(rank_path_cmp)
|
|
98
|
+
results = compare_dataset_dicts(dict1, dict2)
|
|
99
|
+
for result in results:
|
|
100
|
+
result['step'] = int(step.replace("step", ""))
|
|
101
|
+
result['rank'] = int(rank.replace("rank", ""))
|
|
102
|
+
all_results.extend(results)
|
|
103
|
+
|
|
104
|
+
df = pd.DataFrame(all_results, columns=DatasetChecker.result_header)
|
|
105
|
+
df = df.sort_values(by=['step', 'rank'], ascending=[True, True])
|
|
106
|
+
return df
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@register_checker_item("dataset")
|
|
110
|
+
class DatasetChecker(BaseChecker):
|
|
111
|
+
input_needed = "model"
|
|
112
|
+
multi_rank = True
|
|
113
|
+
|
|
114
|
+
target_name_in_zip = "dataset"
|
|
115
|
+
result_header = ['step', 'rank', 'tag', 'equal', 'max_relative_diff',
|
|
116
|
+
'min_relative_diff', 'mean_relative_diff', 'norm_relative_diff']
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def pack(pack_input):
|
|
120
|
+
output_zip_path = pack_input.output_zip_path
|
|
121
|
+
|
|
122
|
+
def collect_input(model, args, kwargs, step):
|
|
123
|
+
features = parse_args_and_kargs(args, kwargs)
|
|
124
|
+
dataset_filepath = os.path.join(DatasetChecker.target_name_in_zip,
|
|
125
|
+
f"step{step}", f"rank{FmkAdp.get_rank_id()}", "dataset.json")
|
|
126
|
+
create_file_in_zip(output_zip_path, dataset_filepath, json.dumps(features, indent=4))
|
|
127
|
+
config_checking_print(f"add first dataset input features to zip")
|
|
128
|
+
|
|
129
|
+
register_pre_forward_fun_list(collect_input)
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def compare(bench_dir, cmp_dir, output_path, fmk):
|
|
133
|
+
bench_dataset_pack_path = os.path.join(bench_dir, DatasetChecker.target_name_in_zip)
|
|
134
|
+
cmp_dataset_pack_path = os.path.join(cmp_dir, DatasetChecker.target_name_in_zip)
|
|
135
|
+
|
|
136
|
+
df = compare_dataset(bench_dataset_pack_path, cmp_dataset_pack_path)
|
|
137
|
+
pass_check = False not in df['equal'].values
|
|
138
|
+
return DatasetChecker.target_name_in_zip, pass_check, df
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) 2024-2024, Huawei Technologies Co., Ltd.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
|
|
19
|
+
import pandas as pd
|
|
20
|
+
|
|
21
|
+
from msprobe.core.common.file_utils import load_json, load_yaml, create_file_with_content, create_file_in_zip
|
|
22
|
+
from msprobe.core.config_check.checkers.base_checker import BaseChecker
|
|
23
|
+
from msprobe.core.config_check.config_checker import register_checker_item
|
|
24
|
+
from msprobe.core.config_check.utils.utils import config_checking_print
|
|
25
|
+
from msprobe.core.common.const import Const
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
dirpath = os.path.dirname(__file__)
|
|
29
|
+
env_yaml_path = os.path.join(dirpath, "../resource/env.yaml")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def collect_env_data():
|
|
33
|
+
result = {}
|
|
34
|
+
for key, value in os.environ.items():
|
|
35
|
+
result[key] = value
|
|
36
|
+
return result
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_device_type(env_json):
|
|
40
|
+
for key in env_json.keys():
|
|
41
|
+
if Const.ASCEND in key:
|
|
42
|
+
return Const.NPU_LOWERCASE
|
|
43
|
+
return Const.GPU_LOWERCASE
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def compare_env_data(npu_path, bench_path):
|
|
47
|
+
necessary_env = load_yaml(env_yaml_path)
|
|
48
|
+
cmp_data = load_json(npu_path)
|
|
49
|
+
cmp_type = get_device_type(cmp_data)
|
|
50
|
+
bench_data = load_json(bench_path)
|
|
51
|
+
bench_type = get_device_type(bench_data)
|
|
52
|
+
data = []
|
|
53
|
+
for _, value in necessary_env.items():
|
|
54
|
+
cmp_env = value.get(cmp_type)
|
|
55
|
+
bench_env = value.get(bench_type)
|
|
56
|
+
if not bench_env and not cmp_env:
|
|
57
|
+
continue
|
|
58
|
+
elif cmp_env:
|
|
59
|
+
cmp_env_name = cmp_env["name"]
|
|
60
|
+
cmp_value = cmp_data.get(cmp_env_name, value[cmp_type]["default_value"])
|
|
61
|
+
if not bench_env:
|
|
62
|
+
data.append(["only cmp has this env", cmp_env["name"], "", cmp_value, "warning"])
|
|
63
|
+
continue
|
|
64
|
+
bench_env_name = bench_env["name"]
|
|
65
|
+
bench_value = bench_data.get(bench_env_name, value[bench_type]["default_value"])
|
|
66
|
+
if cmp_value != bench_value:
|
|
67
|
+
data.append([bench_env_name, cmp_env_name, bench_value, cmp_value, "error"])
|
|
68
|
+
else:
|
|
69
|
+
bench_env_name = bench_env["name"]
|
|
70
|
+
bench_value = bench_data.get(bench_env_name) if bench_data.get(bench_env_name) else value[bench_type][
|
|
71
|
+
"default_value"]
|
|
72
|
+
data.append([bench_env_name, "only bench has this env", bench_value, "", "warning"])
|
|
73
|
+
df = pd.DataFrame(data, columns=EnvArgsChecker.result_header)
|
|
74
|
+
return df
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@register_checker_item("env")
|
|
78
|
+
class EnvArgsChecker(BaseChecker):
|
|
79
|
+
|
|
80
|
+
target_name_in_zip = "env"
|
|
81
|
+
result_header = ["bench_env_name", "cmp_env_name", "bench_value", "cmp_value", "level"]
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def pack(pack_input):
|
|
85
|
+
output_zip_path = pack_input.output_zip_path
|
|
86
|
+
env_args_dict = collect_env_data()
|
|
87
|
+
create_file_in_zip(output_zip_path, EnvArgsChecker.target_name_in_zip, json.dumps(env_args_dict, indent=4))
|
|
88
|
+
config_checking_print(f"add env args to zip")
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def compare(bench_dir, cmp_dir, output_path, fmk):
|
|
92
|
+
bench_env_data = os.path.join(bench_dir, EnvArgsChecker.target_name_in_zip)
|
|
93
|
+
cmp_env_data = os.path.join(cmp_dir, EnvArgsChecker.target_name_in_zip)
|
|
94
|
+
df = compare_env_data(bench_env_data, cmp_env_data)
|
|
95
|
+
pass_check = "error" not in df['level'].values
|
|
96
|
+
return EnvArgsChecker.target_name_in_zip, pass_check, df
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Copyright (c) 2025-2025, Huawei Technologies Co., Ltd.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
from difflib import SequenceMatcher
|
|
19
|
+
|
|
20
|
+
from typing import Union, List, Dict, Any
|
|
21
|
+
import pandas as pd
|
|
22
|
+
|
|
23
|
+
from msprobe.core.config_check.checkers.base_checker import BaseChecker
|
|
24
|
+
from msprobe.core.config_check.config_checker import register_checker_item
|
|
25
|
+
from msprobe.core.config_check.utils.utils import compare_dict, config_checking_print, update_dict
|
|
26
|
+
from msprobe.core.config_check.utils.hyperparameter_parser import ParserFactory
|
|
27
|
+
from msprobe.core.common.file_utils import (os_walk_for_files, create_file_in_zip, load_json, create_file_with_list,
|
|
28
|
+
FileOpen, load_yaml)
|
|
29
|
+
from msprobe.core.common.const import Const
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
dirpath = os.path.dirname(__file__)
|
|
33
|
+
hyperparameters_path = os.path.join(dirpath, "../resource/hyperparameter.yaml")
|
|
34
|
+
parameter_name_mapping = load_yaml(os.path.realpath(hyperparameters_path))
|
|
35
|
+
hyperparameters_dict = {}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@register_checker_item("hyperparameter")
|
|
39
|
+
class HyperparameterChecker(BaseChecker):
|
|
40
|
+
target_name_in_zip = "hyperparameters"
|
|
41
|
+
result_header = ["file_name", "bench_para", "cmp_para", "bench_value", "cmp_value", "matched_with", "level"]
|
|
42
|
+
hyperparameters_file_list = ["hyperparameters_static.json", "hyperparameters_dynamic.json"]
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def pack(pack_input):
|
|
46
|
+
shell_path = pack_input.shell_path
|
|
47
|
+
output_zip_path = pack_input.output_zip_path
|
|
48
|
+
|
|
49
|
+
if shell_path:
|
|
50
|
+
if not isinstance(shell_path, list):
|
|
51
|
+
raise TypeError("shell_path should be a list of file paths.")
|
|
52
|
+
|
|
53
|
+
hyperparameters = {}
|
|
54
|
+
parser_factory = ParserFactory()
|
|
55
|
+
for script_path in shell_path:
|
|
56
|
+
if os.path.isfile(script_path):
|
|
57
|
+
parser = parser_factory.get_parser(os.path.splitext(script_path)[1])
|
|
58
|
+
update_dict(hyperparameters, parser.run(os.path.realpath(script_path)))
|
|
59
|
+
else:
|
|
60
|
+
config_checking_print(f"Warning: Script path {script_path} is not a file.")
|
|
61
|
+
if hyperparameters:
|
|
62
|
+
create_file_in_zip(output_zip_path,
|
|
63
|
+
os.path.join(HyperparameterChecker.target_name_in_zip,
|
|
64
|
+
HyperparameterChecker.hyperparameters_file_list[0]),
|
|
65
|
+
json.dumps(hyperparameters, indent=4))
|
|
66
|
+
config_checking_print(f"add static hyperparameters args to zip")
|
|
67
|
+
else:
|
|
68
|
+
config_checking_print(f"Warning: Failed to extract hyperparameters from script {shell_path}")
|
|
69
|
+
if hyperparameters_dict:
|
|
70
|
+
create_file_in_zip(output_zip_path,
|
|
71
|
+
os.path.join(HyperparameterChecker.target_name_in_zip,
|
|
72
|
+
HyperparameterChecker.hyperparameters_file_list[1]),
|
|
73
|
+
json.dumps(vars(hyperparameters_dict), default=lambda x: None, indent=4))
|
|
74
|
+
config_checking_print(f"add dynamic hyperparameters args to zip")
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def compare(bench_dir, cmp_dir, output_path, fmk):
|
|
78
|
+
all_diffs = []
|
|
79
|
+
for file_name in HyperparameterChecker.hyperparameters_file_list:
|
|
80
|
+
bench_model_dir = os.path.join(bench_dir, HyperparameterChecker.target_name_in_zip, file_name)
|
|
81
|
+
cmp_model_dir = os.path.join(cmp_dir, HyperparameterChecker.target_name_in_zip, file_name)
|
|
82
|
+
if os.path.isfile(bench_model_dir) and os.path.isfile(cmp_model_dir):
|
|
83
|
+
bench_hyperparameters = load_json(bench_model_dir)
|
|
84
|
+
cmp_hyperparameters = load_json(cmp_model_dir)
|
|
85
|
+
all_diffs.extend(
|
|
86
|
+
HyperparameterChecker.compare_param(bench_hyperparameters, cmp_hyperparameters, file_name))
|
|
87
|
+
df = pd.DataFrame(all_diffs, columns=HyperparameterChecker.result_header)
|
|
88
|
+
pass_check = "error" not in df["level"].values
|
|
89
|
+
return HyperparameterChecker.target_name_in_zip, pass_check, df
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def compare_param(bench_params, cmp_params, file_name):
|
|
93
|
+
all_diffs = []
|
|
94
|
+
bench_param_names = bench_params.keys()
|
|
95
|
+
for bench_param_name in bench_param_names:
|
|
96
|
+
matched_cmp_param_name, matched_with = HyperparameterChecker._fuzzy_match_parameter(bench_param_name,
|
|
97
|
+
cmp_params)
|
|
98
|
+
bench_param_value = bench_params[bench_param_name]
|
|
99
|
+
if matched_cmp_param_name:
|
|
100
|
+
cmp_param_value = cmp_params[matched_cmp_param_name]
|
|
101
|
+
if bench_param_value != cmp_param_value:
|
|
102
|
+
all_diffs.append(
|
|
103
|
+
[file_name, bench_param_name, matched_cmp_param_name, bench_param_value, cmp_param_value,
|
|
104
|
+
matched_with, "error"])
|
|
105
|
+
del cmp_params[matched_cmp_param_name]
|
|
106
|
+
else:
|
|
107
|
+
all_diffs.append(
|
|
108
|
+
[file_name, bench_param_name, "Only in benchmark", bench_param_value, "", "", "warning"])
|
|
109
|
+
for cmp_param_name, cmp_param_value in cmp_params.items():
|
|
110
|
+
all_diffs.append([file_name, "Only in comparison", cmp_param_name, "", cmp_param_value, "", "warning"])
|
|
111
|
+
all_diffs.sort()
|
|
112
|
+
return all_diffs
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def apply_patches(fmk):
|
|
116
|
+
try:
|
|
117
|
+
from megatron import training
|
|
118
|
+
|
|
119
|
+
def collect_hyperparameter_wrapper(func):
|
|
120
|
+
def wrapper(*args, **kwargs):
|
|
121
|
+
global hyperparameters_dict
|
|
122
|
+
result = func(*args, **kwargs)
|
|
123
|
+
if not hyperparameters_dict:
|
|
124
|
+
hyperparameters_dict = result
|
|
125
|
+
return result
|
|
126
|
+
return wrapper
|
|
127
|
+
training.get_args = collect_hyperparameter_wrapper(training.get_args)
|
|
128
|
+
except ImportError:
|
|
129
|
+
config_checking_print("No megatron find.")
|
|
130
|
+
except Exception as e:
|
|
131
|
+
config_checking_print(f"Patch megatron method failed, detail:{str(e)}")
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def _fuzzy_match_parameter(param_name: str, available_params: Dict[str, Any]):
|
|
135
|
+
"""
|
|
136
|
+
Fuzzy matches a parameter name against available parameter names using predefined
|
|
137
|
+
mappings and string similarity.
|
|
138
|
+
"""
|
|
139
|
+
if param_name in available_params:
|
|
140
|
+
return param_name, Const.MATCH_MODE_NAME
|
|
141
|
+
|
|
142
|
+
canonical_name = None
|
|
143
|
+
for standard_name, aliases in parameter_name_mapping.items():
|
|
144
|
+
if param_name == standard_name or param_name in aliases:
|
|
145
|
+
canonical_name = standard_name
|
|
146
|
+
break
|
|
147
|
+
|
|
148
|
+
if canonical_name:
|
|
149
|
+
if canonical_name in available_params:
|
|
150
|
+
return canonical_name, Const.MATCH_MODE_MAPPING
|
|
151
|
+
for alias in parameter_name_mapping[canonical_name]:
|
|
152
|
+
if alias in available_params:
|
|
153
|
+
config_checking_print(
|
|
154
|
+
f"Matched '{param_name}' to alias '{alias}' via canonical name '{canonical_name}'")
|
|
155
|
+
return alias, Const.MATCH_MODE_MAPPING
|
|
156
|
+
|
|
157
|
+
best_match_name = None
|
|
158
|
+
best_match_ratio = 0.8
|
|
159
|
+
for available_param_name in available_params:
|
|
160
|
+
ratio = SequenceMatcher(None, param_name.lower(), available_param_name.lower()).ratio()
|
|
161
|
+
if ratio > best_match_ratio:
|
|
162
|
+
best_match_ratio = ratio
|
|
163
|
+
best_match_name = available_param_name
|
|
164
|
+
|
|
165
|
+
if best_match_name:
|
|
166
|
+
config_checking_print(
|
|
167
|
+
f"Fuzzy matched parameter '{param_name}' to '{best_match_name}' (similarity: {best_match_ratio:.2f})")
|
|
168
|
+
return best_match_name, f"{Const.MATCH_MODE_SIMILARITY}:{best_match_ratio}"
|
|
169
|
+
|
|
170
|
+
return None, None
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Copyright (c) 2024-2024, Huawei Technologies Co., Ltd.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import pandas as pd
|
|
18
|
+
try:
|
|
19
|
+
import importlib.metadata as metadata
|
|
20
|
+
except ImportError:
|
|
21
|
+
import importlib_metadata as metadata
|
|
22
|
+
|
|
23
|
+
from msprobe.core.common.file_utils import load_yaml, create_file_in_zip
|
|
24
|
+
from msprobe.core.config_check.checkers.base_checker import BaseChecker
|
|
25
|
+
from msprobe.core.config_check.config_checker import register_checker_item
|
|
26
|
+
from msprobe.core.config_check.utils.utils import config_checking_print
|
|
27
|
+
from msprobe.core.common.file_utils import FileOpen, save_excel
|
|
28
|
+
|
|
29
|
+
dirpath = os.path.dirname(__file__)
|
|
30
|
+
depend_path = os.path.join(dirpath, "../resource/dependency.yaml")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def load_pip_txt(file_path):
|
|
34
|
+
output_dir = {}
|
|
35
|
+
with FileOpen(file_path, 'r', encoding='utf-8') as file:
|
|
36
|
+
lines = file.readlines()
|
|
37
|
+
for line in lines:
|
|
38
|
+
info_list = line.strip().split("=")
|
|
39
|
+
output_dir[info_list[0]] = "" if len(info_list) != 2 else info_list[1]
|
|
40
|
+
return output_dir
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def collect_pip_data():
|
|
44
|
+
result = ""
|
|
45
|
+
packages = metadata.distributions()
|
|
46
|
+
for pkg in packages:
|
|
47
|
+
if pkg.metadata:
|
|
48
|
+
result += f"{pkg.metadata.get('Name')}={pkg.version}\n"
|
|
49
|
+
return result
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def compare_pip_data(bench_pip_path, cmp_pip_path, fmk):
|
|
53
|
+
necessary_dependency = load_yaml(depend_path)["dependency"]
|
|
54
|
+
necessary_dependency.append(fmk)
|
|
55
|
+
bench_data = load_pip_txt(bench_pip_path)
|
|
56
|
+
cmp_data = load_pip_txt(cmp_pip_path)
|
|
57
|
+
data = []
|
|
58
|
+
for package in necessary_dependency:
|
|
59
|
+
bench_version = bench_data.get(package)
|
|
60
|
+
cmp_version = cmp_data.get(package)
|
|
61
|
+
|
|
62
|
+
if bench_version != cmp_version:
|
|
63
|
+
data.append([package, bench_version if bench_version else 'None',
|
|
64
|
+
cmp_version if cmp_version else 'None',
|
|
65
|
+
"error"])
|
|
66
|
+
|
|
67
|
+
df = pd.DataFrame(data, columns=PipPackageChecker.result_header)
|
|
68
|
+
return df
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@register_checker_item("pip")
|
|
72
|
+
class PipPackageChecker(BaseChecker):
|
|
73
|
+
|
|
74
|
+
target_name_in_zip = "pip"
|
|
75
|
+
result_header = ['package', 'bench version', 'cmp version', 'level']
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def pack(pack_input):
|
|
79
|
+
output_zip_path = pack_input.output_zip_path
|
|
80
|
+
pip_data = collect_pip_data()
|
|
81
|
+
create_file_in_zip(output_zip_path, PipPackageChecker.target_name_in_zip, pip_data)
|
|
82
|
+
config_checking_print(f"add pip info to zip")
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def compare(bench_dir, cmp_dir, output_path, fmk):
|
|
86
|
+
bench_pip_path = os.path.join(bench_dir, PipPackageChecker.target_name_in_zip)
|
|
87
|
+
cmp_pip_path = os.path.join(cmp_dir, PipPackageChecker.target_name_in_zip)
|
|
88
|
+
df = compare_pip_data(bench_pip_path, cmp_pip_path, fmk)
|
|
89
|
+
pass_check = "error" not in df['level'].values
|
|
90
|
+
return PipPackageChecker.target_name_in_zip, pass_check, df
|