mindstudio-probe 1.0.4__py3-none-any.whl → 1.1.1__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.0.4.dist-info → mindstudio_probe-1.1.1.dist-info}/METADATA +5 -5
- mindstudio_probe-1.1.1.dist-info/RECORD +341 -0
- {mindstudio_probe-1.0.4.dist-info → mindstudio_probe-1.1.1.dist-info}/WHEEL +1 -1
- {mindstudio_probe-1.0.4.dist-info → mindstudio_probe-1.1.1.dist-info}/entry_points.txt +0 -1
- msprobe/README.md +84 -18
- msprobe/__init__.py +16 -1
- msprobe/config.json +1 -5
- msprobe/core/advisor/advisor.py +16 -11
- msprobe/core/advisor/advisor_const.py +6 -7
- msprobe/core/advisor/advisor_result.py +12 -12
- msprobe/core/common/const.py +164 -3
- msprobe/core/common/exceptions.py +26 -4
- msprobe/core/common/file_utils.py +196 -27
- msprobe/core/common/inplace_op_checker.py +53 -0
- msprobe/core/common/inplace_ops.yaml +251 -0
- msprobe/core/common/log.py +46 -18
- msprobe/core/common/utils.py +308 -209
- msprobe/core/common_config.py +60 -38
- msprobe/core/compare/acc_compare.py +332 -94
- msprobe/core/compare/check.py +104 -22
- msprobe/core/compare/compare_cli.py +42 -5
- msprobe/core/compare/highlight.py +162 -57
- msprobe/core/compare/layer_mapping/__init__.py +19 -0
- msprobe/core/compare/layer_mapping/data_scope_parser.py +235 -0
- msprobe/core/compare/layer_mapping/layer_mapping.py +242 -0
- msprobe/core/compare/layer_mapping/postprocess_pass.py +94 -0
- msprobe/core/compare/multiprocessing_compute.py +33 -8
- msprobe/core/compare/npy_compare.py +73 -29
- msprobe/core/compare/utils.py +306 -247
- msprobe/core/data_dump/data_collector.py +44 -43
- msprobe/core/data_dump/data_processor/base.py +88 -35
- msprobe/core/data_dump/data_processor/factory.py +20 -3
- msprobe/core/data_dump/data_processor/mindspore_processor.py +14 -8
- msprobe/core/data_dump/data_processor/pytorch_processor.py +180 -66
- msprobe/core/data_dump/json_writer.py +63 -42
- msprobe/core/data_dump/scope.py +143 -48
- msprobe/core/grad_probe/constant.py +31 -13
- msprobe/core/grad_probe/grad_compare.py +20 -4
- msprobe/core/grad_probe/utils.py +44 -3
- msprobe/core/overflow_check/abnormal_scene.py +185 -0
- msprobe/core/overflow_check/api_info.py +55 -0
- msprobe/core/overflow_check/checker.py +138 -0
- msprobe/core/overflow_check/filter.py +157 -0
- msprobe/core/overflow_check/ignore_rules.yaml +55 -0
- msprobe/core/overflow_check/level.py +22 -0
- msprobe/core/overflow_check/utils.py +28 -0
- msprobe/docs/01.installation.md +29 -9
- msprobe/docs/02.config_introduction.md +83 -84
- msprobe/docs/03.config_examples.md +3 -20
- msprobe/docs/04.kernel_dump_PyTorch.md +73 -0
- msprobe/docs/05.data_dump_PyTorch.md +143 -13
- msprobe/docs/06.data_dump_MindSpore.md +197 -88
- msprobe/docs/07.accuracy_checker_PyTorch.md +69 -46
- msprobe/docs/08.accuracy_checker_online_PyTorch.md +52 -17
- msprobe/docs/09.accuracy_checker_MindSpore.md +51 -15
- msprobe/docs/10.accuracy_compare_PyTorch.md +187 -99
- msprobe/docs/11.accuracy_compare_MindSpore.md +253 -31
- msprobe/docs/12.overflow_check_PyTorch.md +1 -1
- msprobe/docs/13.overflow_check_MindSpore.md +6 -6
- msprobe/docs/15.free_benchmarking_PyTorch.md +60 -55
- msprobe/docs/16.free_benchmarking_MindSpore.md +159 -0
- msprobe/docs/17.grad_probe.md +19 -22
- msprobe/docs/18.online_dispatch.md +89 -0
- msprobe/docs/19.monitor.md +468 -0
- msprobe/docs/20.monitor_performance_baseline.md +52 -0
- msprobe/docs/21.visualization_PyTorch.md +386 -0
- msprobe/docs/22.visualization_MindSpore.md +384 -0
- msprobe/docs/23.tool_function_introduction.md +28 -0
- msprobe/docs/{FAQ_PyTorch.md → FAQ.md} +25 -10
- msprobe/docs/data_dump_Mindspore/dynamic_graph_quick_start_example.md +211 -0
- msprobe/docs/img/compare_result.png +0 -0
- msprobe/docs/img/monitor/cpu_info.png +0 -0
- msprobe/docs/img/ms_dump.png +0 -0
- msprobe/docs/img/ms_layer.png +0 -0
- msprobe/docs/img/pt_dump.png +0 -0
- msprobe/mindspore/__init__.py +16 -0
- msprobe/mindspore/api_accuracy_checker/api_accuracy_checker.py +130 -138
- msprobe/mindspore/api_accuracy_checker/api_info.py +27 -5
- msprobe/mindspore/api_accuracy_checker/api_runner.py +43 -18
- msprobe/mindspore/api_accuracy_checker/base_compare_algorithm.py +21 -7
- msprobe/mindspore/api_accuracy_checker/checker_support_api.yaml +77 -0
- msprobe/mindspore/api_accuracy_checker/cmd_parser.py +63 -1
- msprobe/mindspore/api_accuracy_checker/compute_element.py +59 -24
- msprobe/mindspore/api_accuracy_checker/data_manager.py +264 -0
- msprobe/mindspore/api_accuracy_checker/main.py +27 -3
- msprobe/mindspore/api_accuracy_checker/multi_api_accuracy_checker.py +206 -0
- msprobe/mindspore/api_accuracy_checker/multi_data_manager.py +58 -0
- msprobe/mindspore/api_accuracy_checker/type_mapping.py +22 -5
- msprobe/mindspore/api_accuracy_checker/utils.py +34 -17
- msprobe/mindspore/cell_processor.py +58 -13
- msprobe/mindspore/common/const.py +35 -13
- msprobe/mindspore/common/log.py +5 -9
- msprobe/mindspore/common/utils.py +60 -5
- msprobe/mindspore/compare/distributed_compare.py +15 -28
- msprobe/mindspore/compare/ms_compare.py +319 -158
- msprobe/mindspore/compare/ms_graph_compare.py +99 -49
- msprobe/mindspore/debugger/debugger_config.py +20 -14
- msprobe/mindspore/debugger/precision_debugger.py +43 -13
- msprobe/mindspore/dump/dump_tool_factory.py +18 -1
- msprobe/mindspore/dump/hook_cell/api_registry.py +23 -3
- msprobe/mindspore/dump/hook_cell/primitive_hooks.py +203 -0
- msprobe/mindspore/dump/hook_cell/support_wrap_ops.yaml +107 -10
- msprobe/mindspore/dump/hook_cell/wrap_api.py +21 -13
- msprobe/mindspore/dump/jit_dump.py +56 -20
- msprobe/mindspore/dump/kernel_graph_dump.py +19 -5
- msprobe/mindspore/dump/kernel_kbyk_dump.py +19 -6
- msprobe/mindspore/dym_loader/hook_dynamic_loader.cc +140 -0
- msprobe/mindspore/dym_loader/hook_dynamic_loader.h +53 -0
- msprobe/mindspore/free_benchmark/api_pynative_self_check.py +162 -41
- msprobe/mindspore/free_benchmark/common/config.py +15 -0
- msprobe/mindspore/free_benchmark/common/handler_params.py +15 -1
- msprobe/mindspore/free_benchmark/common/utils.py +37 -8
- msprobe/mindspore/free_benchmark/data/support_wrap_ops.yaml +0 -204
- msprobe/mindspore/free_benchmark/handler/base_handler.py +20 -5
- msprobe/mindspore/free_benchmark/handler/check_handler.py +21 -7
- msprobe/mindspore/free_benchmark/handler/fix_handler.py +18 -3
- msprobe/mindspore/free_benchmark/handler/handler_factory.py +21 -6
- msprobe/mindspore/free_benchmark/perturbation/add_noise.py +23 -8
- msprobe/mindspore/free_benchmark/perturbation/base_perturbation.py +29 -5
- msprobe/mindspore/free_benchmark/perturbation/bit_noise.py +25 -10
- msprobe/mindspore/free_benchmark/perturbation/exchange_value.py +45 -19
- msprobe/mindspore/free_benchmark/perturbation/improve_precision.py +29 -8
- msprobe/mindspore/free_benchmark/perturbation/no_change.py +16 -1
- msprobe/mindspore/free_benchmark/perturbation/perturbation_factory.py +22 -7
- msprobe/mindspore/free_benchmark/self_check_tool_factory.py +17 -2
- msprobe/mindspore/grad_probe/global_context.py +44 -14
- msprobe/mindspore/grad_probe/grad_analyzer.py +27 -13
- msprobe/mindspore/grad_probe/grad_monitor.py +16 -1
- msprobe/mindspore/grad_probe/grad_stat_csv.py +33 -5
- msprobe/mindspore/grad_probe/hook.py +24 -10
- msprobe/mindspore/grad_probe/utils.py +18 -5
- msprobe/mindspore/ms_config.py +22 -15
- msprobe/mindspore/overflow_check/kernel_graph_overflow_check.py +20 -6
- msprobe/mindspore/overflow_check/overflow_check_tool_factory.py +15 -0
- msprobe/mindspore/runtime.py +15 -0
- msprobe/mindspore/service.py +75 -150
- msprobe/mindspore/task_handler_factory.py +15 -0
- msprobe/msprobe.py +24 -7
- msprobe/pytorch/__init__.py +23 -3
- msprobe/pytorch/api_accuracy_checker/common/config.py +81 -2
- msprobe/pytorch/api_accuracy_checker/common/utils.py +53 -21
- msprobe/pytorch/api_accuracy_checker/compare/algorithm.py +19 -2
- msprobe/pytorch/api_accuracy_checker/compare/api_precision_compare.py +50 -25
- msprobe/pytorch/api_accuracy_checker/compare/compare.py +51 -21
- msprobe/pytorch/api_accuracy_checker/compare/compare_column.py +23 -6
- msprobe/pytorch/api_accuracy_checker/compare/compare_utils.py +28 -8
- msprobe/pytorch/api_accuracy_checker/config.yaml +1 -1
- msprobe/pytorch/api_accuracy_checker/generate_op_script/config_op.json +9 -0
- msprobe/pytorch/api_accuracy_checker/generate_op_script/op_generator.py +454 -0
- msprobe/pytorch/api_accuracy_checker/generate_op_script/operator_replication.template +365 -0
- msprobe/pytorch/api_accuracy_checker/run_ut/data_generate.py +73 -33
- msprobe/pytorch/api_accuracy_checker/run_ut/multi_run_ut.py +44 -18
- msprobe/pytorch/api_accuracy_checker/run_ut/run_overflow_check.py +32 -11
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut.py +122 -172
- msprobe/pytorch/api_accuracy_checker/run_ut/run_ut_utils.py +158 -4
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/attl.py +30 -24
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/client.py +68 -31
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/device_dispatch.py +27 -4
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/dump_dispatch.py +115 -0
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/server.py +26 -9
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/torch_ops_config.yaml +63 -0
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/utils.py +44 -0
- msprobe/pytorch/bench_functions/__init__.py +18 -3
- msprobe/pytorch/bench_functions/apply_adam_w.py +15 -0
- msprobe/pytorch/bench_functions/confusion_transpose.py +20 -1
- msprobe/pytorch/bench_functions/fast_gelu.py +15 -0
- msprobe/pytorch/bench_functions/layer_norm_eval.py +15 -0
- msprobe/pytorch/bench_functions/linear.py +15 -0
- msprobe/pytorch/bench_functions/matmul_backward.py +33 -6
- msprobe/pytorch/bench_functions/npu_fusion_attention.py +280 -157
- msprobe/pytorch/bench_functions/rms_norm.py +15 -0
- msprobe/pytorch/bench_functions/rotary_mul.py +32 -9
- msprobe/pytorch/bench_functions/scaled_mask_softmax.py +15 -0
- msprobe/pytorch/bench_functions/swiglu.py +29 -6
- msprobe/pytorch/common/__init__.py +15 -0
- msprobe/pytorch/common/log.py +18 -6
- msprobe/pytorch/common/parse_json.py +31 -16
- msprobe/pytorch/common/utils.py +96 -40
- msprobe/pytorch/compare/distributed_compare.py +13 -14
- msprobe/pytorch/compare/match.py +15 -0
- msprobe/pytorch/compare/pt_compare.py +44 -10
- msprobe/pytorch/debugger/debugger_config.py +69 -52
- msprobe/pytorch/debugger/precision_debugger.py +72 -24
- msprobe/pytorch/dump/kernel_dump/kernel_config.py +33 -0
- msprobe/pytorch/free_benchmark/__init__.py +20 -5
- msprobe/pytorch/free_benchmark/common/constant.py +15 -0
- msprobe/pytorch/free_benchmark/common/counter.py +15 -0
- msprobe/pytorch/free_benchmark/common/enums.py +43 -0
- msprobe/pytorch/free_benchmark/common/params.py +23 -1
- msprobe/pytorch/free_benchmark/common/utils.py +43 -5
- msprobe/pytorch/free_benchmark/compare/grad_saver.py +47 -9
- msprobe/pytorch/free_benchmark/compare/single_benchmark.py +17 -0
- msprobe/pytorch/free_benchmark/main.py +19 -4
- msprobe/pytorch/free_benchmark/perturbed_layers/base_layer.py +15 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/layer_factory.py +19 -4
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/add_noise.py +18 -1
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/bit_noise.py +21 -4
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/change_value.py +28 -2
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/improve_precision.py +19 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/no_change.py +15 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/npu/npu_base_layser.py +15 -0
- msprobe/pytorch/free_benchmark/perturbed_layers/run_cpu.py +15 -0
- msprobe/pytorch/free_benchmark/result_handlers/base_handler.py +65 -16
- msprobe/pytorch/free_benchmark/result_handlers/check_handler.py +15 -0
- msprobe/pytorch/free_benchmark/result_handlers/fix_handler.py +21 -5
- msprobe/pytorch/free_benchmark/result_handlers/handler_factory.py +15 -0
- msprobe/pytorch/free_benchmark/result_handlers/preheat_handler.py +19 -4
- msprobe/pytorch/function_factory.py +17 -2
- msprobe/pytorch/functional/module_dump.py +84 -0
- msprobe/pytorch/grad_probe/grad_monitor.py +23 -6
- msprobe/pytorch/grad_probe/grad_stat_csv.py +40 -10
- msprobe/pytorch/hook_module/__init__.py +16 -1
- msprobe/pytorch/hook_module/api_registry.py +13 -8
- msprobe/pytorch/hook_module/hook_module.py +17 -19
- msprobe/pytorch/hook_module/support_wrap_ops.yaml +1 -0
- msprobe/pytorch/hook_module/utils.py +4 -6
- msprobe/pytorch/hook_module/wrap_aten.py +12 -11
- msprobe/pytorch/hook_module/wrap_distributed.py +6 -7
- msprobe/pytorch/hook_module/wrap_functional.py +21 -20
- msprobe/pytorch/hook_module/wrap_npu_custom.py +9 -17
- msprobe/pytorch/hook_module/wrap_tensor.py +4 -6
- msprobe/pytorch/hook_module/wrap_torch.py +4 -6
- msprobe/pytorch/hook_module/wrap_vf.py +4 -6
- msprobe/pytorch/module_processer.py +18 -6
- msprobe/pytorch/monitor/anomaly_analyse.py +201 -0
- msprobe/pytorch/monitor/anomaly_detect.py +340 -0
- msprobe/pytorch/monitor/distributed/distributed_ops.yaml +19 -0
- msprobe/pytorch/monitor/distributed/stack_blacklist.yaml +5 -0
- msprobe/pytorch/monitor/distributed/wrap_distributed.py +272 -0
- msprobe/pytorch/monitor/features.py +108 -0
- msprobe/pytorch/monitor/module_hook.py +870 -0
- msprobe/pytorch/monitor/module_metric.py +193 -0
- msprobe/pytorch/monitor/module_spec_verifier.py +93 -0
- msprobe/pytorch/monitor/optimizer_collect.py +295 -0
- msprobe/pytorch/monitor/unittest/__init__.py +0 -0
- msprobe/pytorch/monitor/unittest/test_monitor.py +145 -0
- msprobe/pytorch/monitor/utils.py +250 -0
- msprobe/pytorch/monitor/visualizer.py +59 -0
- msprobe/pytorch/online_dispatch/__init__.py +2 -3
- msprobe/pytorch/online_dispatch/compare.py +38 -48
- msprobe/pytorch/online_dispatch/dispatch.py +50 -25
- msprobe/pytorch/online_dispatch/dump_compare.py +21 -9
- msprobe/pytorch/online_dispatch/single_compare.py +60 -39
- msprobe/pytorch/online_dispatch/torch_ops_config.yaml +9 -1
- msprobe/pytorch/online_dispatch/utils.py +48 -23
- msprobe/pytorch/parse.py +15 -0
- msprobe/pytorch/parse_tool/cli.py +5 -6
- msprobe/pytorch/parse_tool/lib/compare.py +19 -26
- msprobe/pytorch/parse_tool/lib/config.py +1 -1
- msprobe/pytorch/parse_tool/lib/parse_tool.py +4 -2
- msprobe/pytorch/parse_tool/lib/utils.py +40 -55
- msprobe/pytorch/parse_tool/lib/visualization.py +3 -1
- msprobe/pytorch/pt_config.py +192 -40
- msprobe/pytorch/service.py +110 -35
- msprobe/visualization/__init__.py +14 -0
- msprobe/visualization/builder/__init__.py +14 -0
- msprobe/visualization/builder/graph_builder.py +165 -0
- msprobe/visualization/builder/msprobe_adapter.py +205 -0
- msprobe/visualization/compare/__init__.py +14 -0
- msprobe/visualization/compare/graph_comparator.py +130 -0
- msprobe/visualization/compare/mode_adapter.py +211 -0
- msprobe/visualization/graph/__init__.py +14 -0
- msprobe/visualization/graph/base_node.py +124 -0
- msprobe/visualization/graph/graph.py +200 -0
- msprobe/visualization/graph/node_colors.py +95 -0
- msprobe/visualization/graph/node_op.py +39 -0
- msprobe/visualization/graph_service.py +214 -0
- msprobe/visualization/utils.py +232 -0
- mindstudio_probe-1.0.4.dist-info/RECORD +0 -276
- msprobe/docs/04.acl_config_examples.md +0 -76
- msprobe/mindspore/free_benchmark/decorator/dec_forward.py +0 -43
- msprobe/mindspore/free_benchmark/decorator/decorator_factory.py +0 -107
- msprobe/pytorch/api_accuracy_checker/tensor_transport_layer/ssl_config.py +0 -10
- msprobe/pytorch/functional/dump_module.py +0 -39
- {mindstudio_probe-1.0.4.dist-info → mindstudio_probe-1.1.1.dist-info}/LICENSE +0 -0
- {mindstudio_probe-1.0.4.dist-info → mindstudio_probe-1.1.1.dist-info}/top_level.txt +0 -0
- /msprobe/{mindspore/free_benchmark/decorator → pytorch/monitor}/__init__.py +0 -0
- /msprobe/pytorch/{functional/data_processor.py → monitor/distributed/__init__.py} +0 -0
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## 1 简介
|
|
4
4
|
|
|
5
|
-
**PyTorch
|
|
5
|
+
**PyTorch 离线精度预检**通过扫描昇腾 NPU 上用户训练模型中的所有 API,输出模型精度的诊断和分析结果。具体而言,该工具通过采集模型中所有 API 的前反向信息,构造相应的单元测试,将 NPU 输出与标杆(CPU 高精度)比对,从而计算对应的精度指标,该过程通过子命令 run_ut 执行;将 NPU 环境下采集的预检数据拷贝至 GPU 环境,同样执行 run_ut;最后通过**新精度标准比对法**<sup>a</sup>将 NPU 和 GPU 的预检结果进行比对,从而找出 NPU 中存在精度问题的 API。同时,本工具支持**随机生成模式和真实数据模式**<sup>b</sup>。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
a. 依据新精度标准,对不同的API采取不同的比对算法(包括绝对阈值法,标杆比对法、二进制一致法、ULP误差比对法和双千指标法),最终给定预检判定结果;
|
|
8
|
+
|
|
9
|
+
b. 在预检 dump 时可以选择由工具构造随机数获得 dump 数据或选择真实输入的数据进行预检 dump 操作。随机生成模式(对应 task: "statistics")执行效率高,可以快速获得结果,但数据精度低,只能大致判断精度问题;真实数据模式(对应 task: "tensor")执行效率略低于随机生成模式,但是数据精度高,可以准确判断精度问题。
|
|
10
10
|
|
|
11
11
|
## 2 离线预检流程
|
|
12
12
|
|
|
13
13
|
1. 在 NPU 和 GPU 环境下分别安装 msprobe。详见[ msprobe 安装](./01.installation.md)章节。
|
|
14
14
|
2. 在 NPU 训练脚本内添加 msprobe 工具 dump 接口 PrecisionDebugger,采集待预检数据。注意需要配置 level="L1"。
|
|
15
15
|
3. 将 NPU 环境下 dump 的预检数据拷贝至 GPU 环境。
|
|
16
|
-
4. 在 NPU 和 GPU 环境下分别执行 run_ut
|
|
17
|
-
5. 将 NPU 和 GPU 执行 run_ut
|
|
16
|
+
4. 在 NPU 和 GPU 环境下分别执行 run_ut,生成的结果最终用于 api_precision_compare.py 函数的输入。详见 [3 离线预检操作指导](#3-离线预检操作指导)。
|
|
17
|
+
5. 将 NPU 和 GPU 执行 run_ut 生成的 `accuracy_checking_details_{timestamp}.csv` 结果文件拷贝至同一环境下。
|
|
18
18
|
6. 运行 api_precision_compare.py,输出结果为预检操作的最终结果。详见 [5 预检结果比对](#5-预检结果比对)章节。
|
|
19
19
|
|
|
20
20
|
## 3 离线预检操作指导
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
|
|
24
24
|
run_ut 预检操作包括以下两种方式:
|
|
25
25
|
|
|
26
|
-
- 使用 run_ut
|
|
27
|
-
- 使用 multi_run_ut
|
|
26
|
+
- 使用 run_ut 子命令执行预检:适用于数据量较小的单卡场景。
|
|
27
|
+
- 使用 multi_run_ut 子命令执行多线程预检:适用于数据量较大的大模型场景。
|
|
28
28
|
|
|
29
|
-
### 3.1 使用 run_ut
|
|
29
|
+
### 3.1 使用 run_ut 执行预检
|
|
30
30
|
|
|
31
31
|
将 API 信息输入到 run_ut 模块进行精度检测并比对,运行如下命令:
|
|
32
32
|
|
|
@@ -38,8 +38,7 @@ msprobe -f pytorch run_ut -api_info ./dump.json
|
|
|
38
38
|
| ---------------------------- | ------------------------------------------------------------ | ---------------------------------- |
|
|
39
39
|
| -api_info 或 --api_info_file | 指定 API 信息文件 dump.json。 | 是 |
|
|
40
40
|
| -save_error_data | 保存精度未达标的 API 输入输出数据。 | 否 |
|
|
41
|
-
| -o 或 --out_path | 指定 run_ut
|
|
42
|
-
| | | |
|
|
41
|
+
| -o 或 --out_path | 指定 run_ut 执行结果存盘路径,默认“./”。 | 否 |
|
|
43
42
|
| -j 或 --jit_compile | 开启 jit 编译。 | 否 |
|
|
44
43
|
| -d 或 --device | 指定 Device ID,选择 UT 代码运行所在的卡,默认值为 0。 | 否 |
|
|
45
44
|
| -csv_path 或 --result_csv_path | 指定本次运行中断时生成的 `accuracy_checking_result_{timestamp}.csv` 文件路径,执行 run_ut 中断时,若想从中断处继续执行,配置此参数即可。需要指定为上次中断的 `accuracy_checking_result_{timestamp}.csv` 文件。详见 [3.3 断点续检](#33-断点续检)。 | run_ut 操作中断后继续执行场景下必须配置 |
|
|
@@ -47,19 +46,19 @@ msprobe -f pytorch run_ut -api_info ./dump.json
|
|
|
47
46
|
| -config 或 --config_path | 指定离线预检操作过程中额外配置(包括黑名单、白名单等)的 [config.json](../config.json) 文件,默认未配置。config.json 文件的配置可参考[配置文件介绍](./02.config_introduction.md)。 | 否 |
|
|
48
47
|
|
|
49
48
|
run_ut 执行结果包括 `accuracy_checking_result_{timestamp}.csv` 和 `accuracy_checking_details_{timestamp}.csv` 两个文件。`accuracy_checking_result_{timestamp}.csv` 属于 API 级,标明每个 API 是否通过测试。建议用户先查看 `accuracy_checking_result_{timestamp}.csv` 文件,对于其中没有通过测试的或者特定感兴趣的 API,根据其 API name 字段在 `accuracy_checking_details_{timestamp}.csv` 中查询其各个输出的达标情况以及比较指标。详细介绍请参见[ 4 预检结果](#4-预检结果)。
|
|
50
|
-
|
|
49
|
+
|
|
51
50
|
如果需要保存比对不达标的输入和输出数据,可以在 run_ut 执行命令结尾添加 `-save_error_data`,例如:
|
|
52
51
|
|
|
53
52
|
```bash
|
|
54
53
|
msprobe -f pytorch run_ut -api_info ./dump.json -save_error_data
|
|
55
54
|
```
|
|
56
55
|
|
|
57
|
-
数据默认会存盘到 './ut_error_data{timestamp}'
|
|
56
|
+
数据默认会存盘到 './ut_error_data{timestamp}' 路径下,如有需要,用户可以通过 error_data_path 参数来配置保存路径,error_data_path 参数在 [config.json](../config.json) 文件或 [config.yaml](../pytorch/api_accuracy_checker/config.yaml) 文件配置,config.json 文件需要在 run_ut 操作时通过 -config 参数指定。
|
|
58
57
|
|
|
59
58
|
#### 3.1.1 config.yaml 文件说明
|
|
60
59
|
|
|
61
60
|
config.yaml 文件可以通过配置参数来控制 dump 和 run_ut 操作的白名单、黑名单等功能。操作步骤如下:
|
|
62
|
-
|
|
61
|
+
|
|
63
62
|
- config.yaml 文件通常位于类似 /home/xxx/miniconda3/envs/xxx/lib/python3.8/site-packages/msprobe/pytorch/api_accuracy_checker/config.yaml 的路径中。
|
|
64
63
|
|
|
65
64
|
- 进入 config.yaml 文件
|
|
@@ -88,15 +87,15 @@ msprobe -f pytorch run_ut -api_info ./dump.json -save_error_data
|
|
|
88
87
|
|
|
89
88
|
#### 3.1.2 API 预检黑名单和白名单
|
|
90
89
|
|
|
91
|
-
run_ut 过程支持 API 预检黑名单和白名单,通过如下文件配置 black_list(黑名单)或white_list(白名单)参数来指定不需要或需要预检的API名称:
|
|
90
|
+
run_ut 过程支持 API 预检黑名单和白名单,通过如下文件配置 black_list(黑名单)或 white_list(白名单)参数来指定不需要或需要预检的 API 名称:
|
|
92
91
|
|
|
93
92
|
- 配置 [config.json](../config.json) 文件,该文件需要在 run_ut 操作时通过 -config 参数指定。
|
|
94
93
|
|
|
95
94
|
- config.json 文件的优先级高于 config.yaml 文件,即执行 config.json 文件时,config.yaml 文件的配置不生效。
|
|
96
95
|
|
|
97
|
-
### 3.2 使用 multi_run_ut
|
|
96
|
+
### 3.2 使用 multi_run_ut 执行多线程预检
|
|
98
97
|
|
|
99
|
-
multi_run_ut
|
|
98
|
+
multi_run_ut 脚本,可以并行执行多个 run_ut 操作,从而减少预检耗时。示例如下:
|
|
100
99
|
|
|
101
100
|
```bash
|
|
102
101
|
msprobe -f pytorch multi_run_ut -api_info ./dump.json -n 32 -d 0 1 2 3
|
|
@@ -106,7 +105,7 @@ msprobe -f pytorch multi_run_ut -api_info ./dump.json -n 32 -d 0 1 2 3
|
|
|
106
105
|
| ---------------------------- | ------------------------------------------------------------ | ---------------------------------- |
|
|
107
106
|
| -api_info 或 --api_info_file | 指定 API 信息文件 dump.json。 | 是 |
|
|
108
107
|
| -save_error_data | 保存精度未达标的 API 输入输出数据。 | 否 |
|
|
109
|
-
| -o 或 --out_path | 指定 run_ut
|
|
108
|
+
| -o 或 --out_path | 指定 run_ut 执行结果存盘路径,默认“./”。 | 否 |
|
|
110
109
|
| -j 或 --jit_compile | 开启 jit 编译。 | 否 |
|
|
111
110
|
| -n | 同时执行 run_ut 线程的数量,默认为 8,最大支持 64,但每个 Device 最大支持 8 个线程。当指定多个线程和多个 Device 时,线程数在每张卡上均分。 | 否 |
|
|
112
111
|
| -d 或 --device | 指定 Device ID,选择 UT 代码运行所在的卡,默认值为 0,支持同时指定 0~7,共 8 个 Device。 | 否 |
|
|
@@ -138,15 +137,15 @@ msprobe -f pytorch run_ut -api_info ./dump.json -csv_path /home/xxx/ut/accuracy_
|
|
|
138
137
|
| 字段 | 含义 |
|
|
139
138
|
| --------------------- | ------------------------- |
|
|
140
139
|
| API name | API 名称。 |
|
|
141
|
-
| Forward Test Success | 前向 API 是否通过测试,pass 为通过,warning 为待观察,error 为错误。SKIP 表示跳过该 API 的计算,跳过原因在 Message
|
|
142
|
-
| Backward Test Success | 反向 API 是否通过测试,pass 为通过,warning 为待观察,error 为错误。如果是空白的话代表该 API
|
|
140
|
+
| Forward Test Success | 前向 API 是否通过测试,pass 为通过,warning 为待观察,error 为错误。SKIP 表示跳过该 API 的计算,跳过原因在 Message 字段中提示,包括:该 API 不支持精度预检,或该 API 被黑名单过滤或不在白名单上,或运行错误等。 |
|
|
141
|
+
| Backward Test Success | 反向 API 是否通过测试,pass 为通过,warning 为待观察,error 为错误。如果是空白的话代表该 API 没有反向输出。SKIP 表示跳过该 API 的计算,跳过原因在 Message 字段中提示,包括:该 API 不支持精度预检,或该 API 被黑名单过滤或不在白名单上,或运行错误等。 |
|
|
143
142
|
| Message | 提示信息。 |
|
|
144
143
|
|
|
145
144
|
该结果为中间结果,仅作为参考,建议完成 [5 预检结果比对](#5-预检结果比对)后查看比对结果。该结果后续将会删除。
|
|
146
145
|
|
|
147
146
|
Forward Test Success 和 Backward Test Success 是否通过测试是由 `accuracy_checking_details_{timestamp}.csv` 中的余弦相似度、最大绝对误差、双百双千双万指标判定结果决定的。
|
|
148
147
|
|
|
149
|
-
需要注意的是 `accuracy_checking_details_{timestamp}.csv` 中可能存在一个 API 的前向(反向)有多个输出,那么每个输出记录一行,而在 `accuracy_checking_result_{timestamp}.csv` 中的结果需要该 API 的所有结果均为 pass 才能标记为 pass,只要存在一个 error 则标记 error,仅存在
|
|
148
|
+
需要注意的是 `accuracy_checking_details_{timestamp}.csv` 中可能存在一个 API 的前向(反向)有多个输出,那么每个输出记录一行,而在 `accuracy_checking_result_{timestamp}.csv` 中的结果需要该 API 的所有结果均为 pass 才能标记为 pass,只要存在一个 error 则标记 error,仅存在 warning 和 pass 且不存在 error 则标记 warning。
|
|
150
149
|
|
|
151
150
|
`accuracy_checking_details_{timestamp}.csv`
|
|
152
151
|
|
|
@@ -157,7 +156,7 @@ Forward Test Success 和 Backward Test Success 是否通过测试是由 `accurac
|
|
|
157
156
|
| API name | NPU 或 GPU下的 API 名称。 |
|
|
158
157
|
| Bench Dtype | 标杆数据的 API 数据类型。 |
|
|
159
158
|
| DEVICE Dtype | NPU 或 GPU 数据的 API 数据类型。 |
|
|
160
|
-
| Shape | API 的 Shape信息。 |
|
|
159
|
+
| Shape | API 的 Shape 信息。 |
|
|
161
160
|
| 余弦相似度 | NPU 或 GPU 数据与标杆数据的余弦相似度。 |
|
|
162
161
|
| 最大绝对误差 | NPU 或 GPU 数据与标杆数据的最大绝对误差。 |
|
|
163
162
|
| 双百指标 | 双百精度指标。是指 NPU 或 GPU 的 Tensor 中的元素逐个与对应的标杆数据对比,相对误差小于百分之一的个数占总元素个数的比例。测试通过标准为相对误差大于百分之一的个数占总元素个数的比例小于百分之一。 |
|
|
@@ -173,25 +172,23 @@ Forward Test Success 和 Backward Test Success 是否通过测试是由 `accurac
|
|
|
173
172
|
| 相对误差错误率 | NPU 与标杆的正常值计算相对误差,其大于错误阈值的元素个数占正常值元素个数的比例。 |
|
|
174
173
|
| 绝对误差错误率 | NPU 与标杆的小值计算绝对误差,其大于错误阈值的元素个数占小值元素个数的比例。 |
|
|
175
174
|
| ULP 误差最大值 | NPU 或 GPU 数据与标杆数据 ULP 误差的最大值(取绝对值后)。 |
|
|
176
|
-
| ULP 误差平均值 | NPU 或 GPU 数据与标杆数据ULP误差的平均值(取绝对值后)。 |
|
|
175
|
+
| ULP 误差平均值 | NPU 或 GPU 数据与标杆数据 ULP 误差的平均值(取绝对值后)。 |
|
|
177
176
|
| ULP 误差大于阈值占比 | NPU 或 GPU 数据与标杆数据的 ULP 误差(取绝对值后)大于阈值(当 NPU 或 GPU 数据类型为 float16 或 bfloat16 时,阈值为 1;当 NPU 或 GPU 数据类型为 float32 时,阈值为 32)的元素个数占总元素的个数比例。 |
|
|
178
|
-
| Status | API
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
**\***:
|
|
177
|
+
| Status | API 预检通过状态。pass 表示通过测试;error 表示未通过;warning 表示测试未通过双千或双万精度指标;SKIP 表示跳过该 API 的计算,跳过原因在 Message 字段中提示,包括:该 API 的某个参数的反向不计算梯度,没有任何计算过程,其他信息均为空,或该 API 的数据类型不支持使用新精度标准进行比对(如 float64),或该 API 不支持精度预检,或该 API 被黑名单过滤或不在白名单上,或运行错误等。 |
|
|
178
|
+
| Message | 提示信息。 |
|
|
182
179
|
|
|
183
180
|
### 4.1 API 预检指标
|
|
184
|
-
|
|
181
|
+
|
|
185
182
|
API 预检指标是通过对 `accuracy_checking_details_{timestamp}.csv` 中的余弦相似度、最大绝对误差双百、双千、双万精度指标的数值进行判断,得出该 API 是否符合精度标准的参考指标。
|
|
186
183
|
|
|
187
|
-
API预检通过测试,则在`accuracy_checking_details_{timestamp}.csv`文件中的 Status 列标记 pass,否则标记 error 或 warning,详细规则如下:
|
|
184
|
+
API 预检通过测试,则在`accuracy_checking_details_{timestamp}.csv`文件中的 Status 列标记 pass,否则标记 error 或 warning,详细规则如下:
|
|
188
185
|
|
|
189
186
|
- 余弦相似度 > 0.99:≤ 0.99 为不达标,标记 error,> 0.99 达标,进行下一步;
|
|
190
187
|
- 最大绝对误差 < 0.001:< 0.001 达标,标记 pass,≥ 0.001 为不达标,进行下一步;
|
|
191
188
|
- 双百、双千、双万精度指标:
|
|
192
189
|
+ 对于 float16 和 bfloat16 数据:双百指标不通过,标记 error;双百指标通过,双千指标不通过,标记 warning;双百、双千指标均通过,标记 pass。
|
|
193
190
|
+ 对于 float32 和 float64 数据:双千指标不通过,标记 error;双千指标通过,双万指标不通过,标记 warning;双千、双万指标均通过,标记 pass。
|
|
194
|
-
- 在 `accuracy_checking_result_{timestamp}.csv` 中以 Forward Test Success 和 Backward Test Success 字段统计该算子前向反向输出的测试结果,对于标记 pass 的算子,则在 `accuracy_checking_result_{timestamp}.csv` 中标记 TRUE 表示测试通过,对于标记 error 或 warning 的算子,则在 `accuracy_checking_result_{timestamp}.csv` 中标记 FALSE 表示测试不通过。由于一个算子可能有多个前向或反向的输入或输出,那么该类算子的输入或输出中必须全为 pass,才能在 `accuracy_checking_result_{timestamp}.csv` 中标记 TRUE,只要有一个输入或输出标记 error 或 warning
|
|
191
|
+
- 在 `accuracy_checking_result_{timestamp}.csv` 中以 Forward Test Success 和 Backward Test Success 字段统计该算子前向反向输出的测试结果,对于标记 pass 的算子,则在 `accuracy_checking_result_{timestamp}.csv` 中标记 TRUE 表示测试通过,对于标记 error 或 warning 的算子,则在 `accuracy_checking_result_{timestamp}.csv` 中标记 FALSE 表示测试不通过。由于一个算子可能有多个前向或反向的输入或输出,那么该类算子的输入或输出中必须全为 pass,才能在 `accuracy_checking_result_{timestamp}.csv` 中标记 TRUE,只要有一个输入或输出标记 error 或 warning,那么在 `accuracy_checking_result_{timestamp}.csv` 中标记 FALSE。
|
|
195
192
|
|
|
196
193
|
### 4.2 小值域阈值
|
|
197
194
|
|
|
@@ -217,8 +214,8 @@ msprobe -f pytorch api_precision_compare -npu /home/xxx/npu/accuracy_checking_de
|
|
|
217
214
|
|
|
218
215
|
| 参数名称 | 说明 | 是否必选 |
|
|
219
216
|
| -------------------- | ------------- | -------- |
|
|
220
|
-
| -npu 或 --npu_csv_path | NPU 预检结果 `accuracy_checking_details_{timestamp}.csv` 文件路径。默认从当前目录下识别该文件。 |
|
|
221
|
-
| -gpu 或 --gpu_csv_path | GPU 预检结果 `accuracy_checking_details_{timestamp}.csv` 文件路径。默认从当前目录下识别该文件。 |
|
|
217
|
+
| -npu 或 --npu_csv_path | NPU 预检结果 `accuracy_checking_details_{timestamp}.csv` 文件路径。默认从当前目录下识别该文件。 | 是 |
|
|
218
|
+
| -gpu 或 --gpu_csv_path | GPU 预检结果 `accuracy_checking_details_{timestamp}.csv` 文件路径。默认从当前目录下识别该文件。 | 是 |
|
|
222
219
|
| -o 或 --out_path | 指定 api_precision_compare.py 执行结果存盘路径,默认为当前目录。 | 否 |
|
|
223
220
|
|
|
224
221
|
执行完成后输出 `api_precision_compare_result_{timestamp}.csv` 和 `api_precision_compare_details_{timestamp}.csv` 文件。文件示例如下:
|
|
@@ -231,10 +228,10 @@ msprobe -f pytorch api_precision_compare -npu /home/xxx/npu/accuracy_checking_de
|
|
|
231
228
|
|
|
232
229
|
| 字段 | 含义 |
|
|
233
230
|
| --------------------- | ------------------------------------------------------------ |
|
|
234
|
-
| API name | API 名称。
|
|
235
|
-
| Forward Test Success | 前向 API
|
|
236
|
-
| Backward Test Success | 反向 API
|
|
237
|
-
| Message | 提示信息。
|
|
231
|
+
| API name | API 名称。 |
|
|
232
|
+
| Forward Test Success | 前向 API 是否通过测试。pass 为通过;warning 为待观察;error 为错误;SKIP 表示跳过该 API 的计算,跳过原因在 Message 字段中提示,包括:该 API 的数据类型不支持使用新精度标准进行比对(如 float64),或该 API 不支持精度预检,或该 API 被黑名单过滤或不在白名单上,或运行错误等。 |
|
|
233
|
+
| Backward Test Success | 反向 API 是否通过测试。pass 为通过;warning 为待观察;error 为错误;如果是空白的话代表该 API 没有反向输出;SKIP 表示该 API 的数据类型不支持使用新精度标准进行比对(如 float64)。 |
|
|
234
|
+
| Message | 提示信息。 |
|
|
238
235
|
|
|
239
236
|
Forward Test Success 和 Backward Test Success 是否通过测试是由 `api_precision_compare_details_{timestamp}.csv` 中的各个指标判定结果决定的。需要注意的是 `api_precision_compare_details_{timestamp}.csv` 中可能存在一个 API 的前向(反向)有多个输出,那么每个输出记录一行,而在 `api_precision_compare_result_{timestamp}.csv` 中的结果需要该 API 的所有结果均为 pass 才能标记为 pass,只要存在一个 error 则标记 error,仅存在 warning 和 pass 且不存在 error 标记 warning。
|
|
240
237
|
|
|
@@ -246,15 +243,15 @@ Forward Test Success 和 Backward Test Success 是否通过测试是由 `api_pre
|
|
|
246
243
|
| ------------------------ | ------------------------------------------------------------ |
|
|
247
244
|
| API name | NPU 或 GPU 下的 API 名称。 |
|
|
248
245
|
| 小值域错误比值 | NPU 与 CPU 的小值域的错误比率 / GPU 与 CPU 的小值域的错误比率。标杆比对法指标。 |
|
|
249
|
-
| 小值域错误判定结果 | 小值域错误比值小于等于 1 标记为 pass,1 ~ 2 之间标记为
|
|
246
|
+
| 小值域错误判定结果 | 小值域错误比值小于等于 1 标记为 pass,1 ~ 2 之间标记为 warning,大于 2 标记为 error。 |
|
|
250
247
|
| 均方根误差比值 | NPU 与 CPU 的均方根误差 / GPU 与 CPU 的均方根误差。标杆比对法指标。 |
|
|
251
|
-
| 均方根误差判定结果 | 均方根误差比值小于等于 1 标记为 pass,1~2 之间标记为
|
|
248
|
+
| 均方根误差判定结果 | 均方根误差比值小于等于 1 标记为 pass,1~2 之间标记为 warning,大于 2 标记为 error。 |
|
|
252
249
|
| 相对误差最大值比值 | NPU 与 CPU 的相对误差最大值 / GPU 与 CPU 的相对误差最大值。标杆比对法指标。 |
|
|
253
|
-
| 相对误差最大值判定结果 | 相对误差最大值比值小于等于 1 标记为 pass,1 ~ 10 之间标记为
|
|
250
|
+
| 相对误差最大值判定结果 | 相对误差最大值比值小于等于 1 标记为 pass,1 ~ 10 之间标记为 warning,大于 10 标记为 error。 |
|
|
254
251
|
| 相对误差平均值比值 | NPU 与 CPU 的相对误差的平均值 / GPU 与 CPU 的相对误差的平均值。标杆比对法指标。 |
|
|
255
|
-
| 相对误差平均值判定结果 | 相对误差平均值比值小于等于 1 标记为 pass,1 ~ 2 之间标记为
|
|
252
|
+
| 相对误差平均值判定结果 | 相对误差平均值比值小于等于 1 标记为 pass,1 ~ 2 之间标记为 warning,大于 2 标记为 error。 |
|
|
256
253
|
| 误差均衡性比值 | NPU 与 CPU 的误差均衡性 / GPU 与 CPU 的误差均衡性。标杆比对法指标。 |
|
|
257
|
-
| 误差均衡性判定结果 | 误差均衡性比值小于等于 1 标记为 pass,1 ~ 2 之间标记为
|
|
254
|
+
| 误差均衡性判定结果 | 误差均衡性比值小于等于 1 标记为 pass,1 ~ 2 之间标记为 warning,大于 2 标记为 error。该字段暂不参与 api_precision_compare_result 的结果判定。 |
|
|
258
255
|
| inf / nan 错误率 | NPU 与标杆 inf / nan 计算不一致的元素个数占总元素的个数比例。绝对阈值法指标。 |
|
|
259
256
|
| inf / nan 判定结果 | inf / nan 错误率判定结果,等于 0 标记为 pass,其余情况标记为 error。 |
|
|
260
257
|
| 相对误差错误率 | NPU 与标杆的正常值计算相对误差,其大于错误阈值的元素个数占正常值元素个数的比例。绝对阈值法指标。 |
|
|
@@ -263,12 +260,38 @@ Forward Test Success 和 Backward Test Success 是否通过测试是由 `api_pre
|
|
|
263
260
|
| 绝对误差判定结果 | 绝对误差错误率判定结果,等于 0 标记为 pass,其余情况标记为 error。 |
|
|
264
261
|
| 二进制一致错误率 | NPU 或 GPU 数据中每个 Tensor 精度不一致的数值的数量与 Tensor 中数值数量的比值。只有数据是 builtin 类型(bool、int、float、str)、torch.bool 和 torch 的 int 类型或者在新精度标准中使用二进制一致算法进行比对的 API 才会展示。二进制一致法指标。 |
|
|
265
262
|
| 二进制一致错误率判定结果 | 二进制一致错误率判定结果,等于 0 标记为 pass,其余情况标记为 error。 |
|
|
266
|
-
| ULP
|
|
267
|
-
| ULP
|
|
268
|
-
| ULP
|
|
263
|
+
| ULP 误差平均值<sup>a</sup> | NPU 数据与标杆数据 ULP 误差的平均值(取绝对值后)。 |
|
|
264
|
+
| ULP 误差大于阈值占比<sup>a</sup> | NPU 数据与标杆数据的 ULP 误差(取绝对值后)大于阈值(当 NPU 数据类型为 float16 或 bfloat16 时,阈值为 1;当 NPU 数据类型为 float32 时,阈值为 32)的元素个数占总元素的个数比例。 |
|
|
265
|
+
| ULP 误差大于阈值占比比值<sup>a</sup> | NPU 与 CPU 的 ULP 误差大于阈值占比 / GPU 与 CPU 的 ULP 误差大于阈值占比。 |
|
|
269
266
|
| ULP 误差判定结果 | ULP 误差判定结果。<br/> 当 NPU 或 GPU 数据类型是 float16 或 bfloat16 时,以下两条标准满足其一标记为 pass,否则标记为 error:<br> NPU ULP 误差大于阈值占比小于 0.001;<br/> NPU ULP 误差大于阈值占比小于 GPU ULP 误差大于阈值占比。<br/> 当 NPU 或 GPU 数据类型是 float32 时,以下三条标准满足其一标记为 pass,否则标记为 error:<br/> NPU ULP 误差平均值小于 64;<br/> NPU ULP 误差大于阈值占比小于 0.05;<br/> NPU ULP 误差大于阈值占比小于 GPU ULP 误差大于阈值占比。 |
|
|
270
267
|
| 双千指标 | 双千精度指标。是指 NPU 的 Tensor 中的元素逐个与对应的标杆数据对比,相对误差小于千分之一的个数占总元素个数的比例。测试通过标准为相对误差大于千分之一的个数占总元素个数的比例小于千分之一。仅 conv1d 和 conv2d 使用该指标。双千指标法指标。 |
|
|
271
268
|
| 双千指标判定结果 | 双千指标判定结果。双千指标大于 0.999 标记为 pass,否则标记为 error。 |
|
|
272
|
-
| 比对结果 | 综合所有指标的最终结果。如果比对指标中有 error,则标记为 error
|
|
269
|
+
| 比对结果 | 综合所有指标的最终结果。如果比对指标中有 error,则标记为 error,在 Message 字段中提示该 API 比对结果不符合标准的指标;有 warning,则标记为 warning,在 Message 字段中提示该 API 比对结果不符合标准的指标;否则标记为 pass;SKIP 表示跳过该 API 的计算,跳过原因在 Message 字段中提示,包括:该 API 的某个参数的反向不计算梯度,没有任何计算过程,其他信息均为空,或该 API 的数据类型不支持使用新精度标准进行比对(如 float64),或该 API 不支持精度预检,或该 API 被黑名单过滤或不在白名单上,或运行错误等。 |
|
|
273
270
|
| 比对算法 | API 使用的比对算法,为标杆比对法、二进制一致法、绝对阈值法和 ULP 误差比对法中的一种。 |
|
|
274
|
-
| Message |
|
|
271
|
+
| Message | 提示信息。 |
|
|
272
|
+
|
|
273
|
+
a:误差比对法指标。
|
|
274
|
+
|
|
275
|
+
## 6 支持的融合算子列表
|
|
276
|
+
|
|
277
|
+
预检工具当前支持的融合算子如下:
|
|
278
|
+
|
|
279
|
+
- npu_apply_adam_w
|
|
280
|
+
|
|
281
|
+
- npu_confusion_transpose
|
|
282
|
+
|
|
283
|
+
- fast_gelu
|
|
284
|
+
|
|
285
|
+
- npu_layer_norm_eval
|
|
286
|
+
|
|
287
|
+
- npu_linear
|
|
288
|
+
|
|
289
|
+
- npu_fusion_attention(该算子在 GPU 上预检时,需要额外安装 flash_attn,请用户自行安装。)
|
|
290
|
+
|
|
291
|
+
- npu_rms_norm
|
|
292
|
+
|
|
293
|
+
- npu_rotary_mul
|
|
294
|
+
|
|
295
|
+
- npu_scaled_masked_softmax
|
|
296
|
+
|
|
297
|
+
- npu_swiglu
|
|
@@ -37,7 +37,7 @@ Host 与 GPU Host 设备间建立连接,将 NPU 上对应 API 的输入数据
|
|
|
37
37
|
| host | 在线预检模式局域网场景信息接收端 IP,str 类型,用于 GPU 设备和 NPU 设备间进行通信,GPU 侧配置为本机地址 127.0.0.1 或本机局域网 IP。局域网场景时,不能配置 nfs_path 参数,否则局域网场景不生效。 | 否 |
|
|
38
38
|
| port | 在线预检模式局域网场景信息接收端端口号,int 类型,用于 GPU 设备和 NPU 设备间进行通信,GPU 侧配置为本机可用端口。局域网场景时,不能配置 nfs_path 参数,否则局域网场景不生效。 | 否 |
|
|
39
39
|
| rank_list | 指定在线预检的 Rank ID,默认值为 [0],list[int] 类型,应配置为大于等于 0 的整数,且须根据实际卡的 Rank ID 配置,若所配置的值大于实际训练所运行的卡的 Rank ID,则在线预检输出数据为空。GPU 和 NPU 须配置一致。 | 是 |
|
|
40
|
-
| tls_path | 在线预检模式局域网场景 SSL 证书路径,该路径下包含私钥文件 server.key 和公钥文件 server.crt,str
|
|
40
|
+
| tls_path | 在线预检模式局域网场景 SSL 证书路径,该路径下包含私钥文件 server.key 和公钥文件 server.crt,str 类型,未配置该参数时默认取值当前路径。tls_path配置为空字符串时,采用TCP协议明文传输api数据;当配置为路径时,采用TLS1.2协议加密传输数据,加密传输时安全性较高,传输速率较低。 | 否 |
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
#### 3.1.2 NPU 侧在线预检配置说明
|
|
@@ -49,18 +49,18 @@ Host 与 GPU Host 设备间建立连接,将 NPU 上对应 API 的输入数据
|
|
|
49
49
|
| level | dump 级别,str 类型,在线预检时配置为 L1,表示 dump API 级精度数据。在线预检可不配置,默认取值 L1。 | 是 |
|
|
50
50
|
| rank | 指定对某张卡上的数据进行 dump,list[int] 类型,默认未配置(表示 dump所有卡的数据),需要与 GPU 侧配置项 rank_list 保持一致。 | 否 |
|
|
51
51
|
| step | 指定 dump 某个 step 的数据,list[int] 类型,默认未配置,表示 dump 所有 step 的数据。dump 特定 step 时,须指定为训练脚本中存在的 step。 | 否 |
|
|
52
|
-
| seed | 随机种子数,int 类型,默认值为 1234。通过固定随机数保证模型的输入或输出一致。 | 否 |
|
|
53
|
-
| is_deterministic | 确定性计算模式,bool 类型,可取值 true(开启)或 false(关闭),默认关闭。 | 否 |
|
|
54
52
|
| scope | dump 范围,list[str] 类型,默认未配置(list 也未配置时表示 dump 所有 api 的数据),配置方式参考 [config.json 配置介绍](./02.config_introduction.md)。 | 否 |
|
|
55
53
|
| list | dump 范围,list[str] 类型,默认未配置(scope 也未配置时表示 dump 所有 api 的数据),配置方式参考 [config.json 配置介绍](./02.config_introduction.md)。 | 否 |
|
|
56
54
|
| online_run_ut | 在线预检模式开关,bool 类型,可取值 True(开启)、False(关闭),默认关闭。 | 是 |
|
|
57
55
|
| nfs_path | 在线预检模式共享存储目录路径,str 类型,用于 GPU 设备和 NPU 设备间进行通信。配置该参数后 host 和 port 不生效。 | 否 |
|
|
58
56
|
| host | 在线预检模式局域网场景信息接收端 IP,str 类型,用于 GPU 设备和 NPU 设备间进行通信,NPU 侧须配置为 GPU 侧的局域网 IP 地址。局域网场景时,不能配置 nfs_path 参数,否则局域网场景不生效。 | 否 |
|
|
59
57
|
| port | 在线预检模式局域网场景信息接收端端口号,int 类型,用于 GPU 设备和 NPU 设备间进行通信,NPU 侧须配置为 GPU 侧的端口号。局域网场景时,不能配置 nfs_path 参数,否则局域网场景不生效。 | 否 |
|
|
58
|
+
| tls_path | 在线预检模式局域网场景 SSL 证书路径,该路径下包含私钥文件 client.key 和公钥文件 client.crt,str 类型,未配置该参数时默认取值当前路径。tls_path配置为空字符串时,采用TCP协议明文传输api数据;当配置为路径时,采用TLS1.2协议加密传输数据,加密传输时安全性较高,传输速率较低。 | 否 |
|
|
59
|
+
| online_run_ut_recompute | 模型训练是否使用重计算机制,bool类型,默认为False,表示模型没有使用重计算。在线预检暂不支持重计算机制下反向算子的预检,当模型训练使用重计算时,跳过反向算子预检,默认模型关闭重计算。 | 否 |
|
|
60
60
|
|
|
61
61
|
#### 3.1.3 局域网场景配置示例
|
|
62
62
|
|
|
63
|
-
若采用TLS1.2协议加密传输api数据,需配置SSL证书,可参考如下生成自签名证书方法,仅供调试使用,生产环境请申请正式证书。
|
|
63
|
+
若采用 TLS1.2 协议加密传输 api 数据,需配置 SSL 证书,可参考如下生成自签名证书方法,仅供调试使用,生产环境请申请正式证书。
|
|
64
64
|
```shell
|
|
65
65
|
# 创建私钥文件server.key
|
|
66
66
|
openssl genrsa -out server.key 2048
|
|
@@ -72,6 +72,19 @@ openssl req -new -key server.key -out server.csr
|
|
|
72
72
|
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
注意:配置TLS协议时,传输性能受机器环境和网络质量的影响,可能触发NPU超时中断模型训练,为避免训练和预检中断,丢弃长时间未传输的api数据,同时NPU侧配置HCCL环境变量,配置方式如下:
|
|
76
|
+
|
|
77
|
+
a) 调整HCCL环境变量,关闭看门狗,避免WorkHCCL超时中断模型训练:
|
|
78
|
+
```shell
|
|
79
|
+
export HCCL_DESYNC_DEBUG=0
|
|
80
|
+
export HCCL_ASYNC_ERROR_HANDLING=0
|
|
81
|
+
```
|
|
82
|
+
b) 调整通信算子超时设置(以1800s举例):
|
|
83
|
+
```shell
|
|
84
|
+
export HCCL_CONNECT_TIMEOUT=1800
|
|
85
|
+
export HCCL_EXEC_TIMEOUT=1800
|
|
86
|
+
```
|
|
87
|
+
|
|
75
88
|
GPU 侧:
|
|
76
89
|
|
|
77
90
|
```json
|
|
@@ -85,7 +98,8 @@ GPU 侧:
|
|
|
85
98
|
"nfs_path": "",
|
|
86
99
|
"host": "127.0.0.1",
|
|
87
100
|
"port": 59208,
|
|
88
|
-
"rank_list": [0]
|
|
101
|
+
"rank_list": [0],
|
|
102
|
+
"tls_path": ""
|
|
89
103
|
}
|
|
90
104
|
}
|
|
91
105
|
```
|
|
@@ -99,15 +113,14 @@ NPU 侧:
|
|
|
99
113
|
"rank": [0],
|
|
100
114
|
"step": [0],
|
|
101
115
|
"level": "L1",
|
|
102
|
-
"seed": 1234,
|
|
103
|
-
"is_deterministic": true,
|
|
104
116
|
"tensor": {
|
|
105
117
|
"scope": [],
|
|
106
118
|
"list": [],
|
|
107
119
|
"online_run_ut": true,
|
|
108
120
|
"nfs_path": "",
|
|
109
121
|
"host": "xx.xx.xx.x",
|
|
110
|
-
"port": 59208
|
|
122
|
+
"port": 59208,
|
|
123
|
+
"tls_path": ""
|
|
111
124
|
}
|
|
112
125
|
}
|
|
113
126
|
```
|
|
@@ -127,7 +140,8 @@ GPU 侧:
|
|
|
127
140
|
"nfs_path": "/nfs/xxx/data",
|
|
128
141
|
"host": "",
|
|
129
142
|
"port": -1,
|
|
130
|
-
"rank_list": [0]
|
|
143
|
+
"rank_list": [0],
|
|
144
|
+
"tls_path": ""
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
```
|
|
@@ -141,15 +155,14 @@ NPU 侧:
|
|
|
141
155
|
"rank": [0],
|
|
142
156
|
"step": [0],
|
|
143
157
|
"level": "L1",
|
|
144
|
-
"seed": 1234,
|
|
145
|
-
"is_deterministic": true,
|
|
146
158
|
"tensor": {
|
|
147
159
|
"scope": [],
|
|
148
160
|
"list": [],
|
|
149
161
|
"online_run_ut": true,
|
|
150
162
|
"nfs_path": "/nfs/xxx/data",
|
|
151
163
|
"host": "",
|
|
152
|
-
"port": -1
|
|
164
|
+
"port": -1,
|
|
165
|
+
"tls_path": ""
|
|
153
166
|
}
|
|
154
167
|
}
|
|
155
168
|
```
|
|
@@ -167,7 +180,7 @@ GPU 侧配置好 config.json 文件后执行 run_ut 命令,此时 GPU 处于
|
|
|
167
180
|
- 局域网场景:当 NPU 侧启动训练后将预检的 API 输入和输出数据发送到 GPU 侧时,GPU 启动预检操作。
|
|
168
181
|
- 共享存储场景:当 NPU 侧启动训练后将预检的 API 输入和输出数据发送到共享存储时,GPU 启动预检操作。
|
|
169
182
|
|
|
170
|
-
### 3.
|
|
183
|
+
### 3.3 在 NPU 侧配置训练脚本
|
|
171
184
|
|
|
172
185
|
在 NPU 训练脚本中添加如下代码以获取 run_ut 操作的预检 API 输入和输出数据:
|
|
173
186
|
|
|
@@ -185,7 +198,7 @@ debugger.stop()
|
|
|
185
198
|
debugger.step()
|
|
186
199
|
```
|
|
187
200
|
|
|
188
|
-
### 3.
|
|
201
|
+
### 3.4 在 NPU 侧执行训练脚本
|
|
189
202
|
|
|
190
203
|
配置完 NPU 侧训练脚本后即可执行训练脚本,命令示例如下:
|
|
191
204
|
|
|
@@ -193,6 +206,28 @@ debugger.step()
|
|
|
193
206
|
bash train.sh
|
|
194
207
|
```
|
|
195
208
|
|
|
196
|
-
训练脚本执行完毕后,在GPU侧dump_path
|
|
197
|
-
|
|
198
|
-
|
|
209
|
+
训练脚本执行完毕后,在GPU侧dump_path目录下生成比对结果文件,`accuracy_checking_result_{timestamp}_rank{rank_id}.csv`和`accuracy_checking_details_{timestamp}_rank{rank_id}.csv`记录两方比对结果,`api_precision_compare_result_{timestamp}_rank{rank_id}.csv`和`api_precision_compare_details_{timestamp}_rank{rank_id}.csv`记录三方比对结果。详细介绍请参见[离线精度预检中的 **4 预检结果**](./07.accuracy_checker_PyTorch.md#4-预检结果)。
|
|
210
|
+
|
|
211
|
+
## 4 支持的融合算子列表
|
|
212
|
+
|
|
213
|
+
预检工具当前支持的融合算子如下:
|
|
214
|
+
|
|
215
|
+
- npu_apply_adam_w
|
|
216
|
+
|
|
217
|
+
- npu_confusion_transpose
|
|
218
|
+
|
|
219
|
+
- fast_gelu
|
|
220
|
+
|
|
221
|
+
- npu_layer_norm_eval
|
|
222
|
+
|
|
223
|
+
- npu_linear
|
|
224
|
+
|
|
225
|
+
- npu_fusion_attention(该算子在 GPU 上预检时,需要额外安装 flash_attn,请用户自行安装。)
|
|
226
|
+
|
|
227
|
+
- npu_rms_norm
|
|
228
|
+
|
|
229
|
+
- npu_rotary_mul
|
|
230
|
+
|
|
231
|
+
- npu_scaled_masked_softmax
|
|
232
|
+
|
|
233
|
+
- npu_swiglu
|
|
@@ -2,33 +2,70 @@
|
|
|
2
2
|
|
|
3
3
|
## 1 简介
|
|
4
4
|
|
|
5
|
-
**MindSpore 动态图精度预检**<sup>a</sup>通过扫描昇腾 NPU 上用户训练 MindSpore 模型中的所有 Mint API,输出精度情况的诊断和分析。工具以模型中所有 Mint API 前反向的 dump 结果为输入,构造相应的 API 单元测试,将 NPU 输出与标杆(CPU 高精度)比对,计算对应的精度指标,从而找出 NPU 中存在精度问题的 Mint API
|
|
5
|
+
**MindSpore 动态图精度预检**<sup>a</sup>通过扫描昇腾 NPU 上用户训练 MindSpore 模型中的所有 Mint API,输出精度情况的诊断和分析。工具以模型中所有 Mint API 前反向的 dump 结果为输入,构造相应的 API 单元测试,将 NPU 输出与标杆(CPU 高精度)比对,计算对应的精度指标,从而找出 NPU 中存在精度问题的 Mint API。本工具支持**随机生成模式和真实数据模式**<sup>b</sup>。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
a. 支持 Mindspore 版本:2.4;
|
|
8
|
+
|
|
9
|
+
b. 在预检时可以由工具构造随机数据或者获取真实dump数据进行预检操作。随机生成模式执行效率高,可以快速获得结果,但结果准确度低,只能大致判断精度问题;真实数据模式执行效率略低于随机生成模式,并且需要较大磁盘空间存放待预检数据,但是结果准确度高,可以准确判断精度问题。
|
|
9
10
|
|
|
10
11
|
## 2 离线预检流程
|
|
11
12
|
|
|
12
13
|
操作流程如下:
|
|
13
14
|
|
|
14
|
-
1. 在 NPU
|
|
15
|
+
1. 在 NPU 环境下安装 msprobe。详见[ msprobe 安装](./01.installation.md)章节。
|
|
15
16
|
2. 在 NPU 训练脚本内添加 msprobe 工具 dump 接口 PrecisionDebugger,采集待预检数据。详见 [MindSpore 场景下的数据采集](./06.data_dump_MindSpore.md)章节,注意需要配置 level="L1"。
|
|
16
|
-
3. 执行预检操作,查看预检结果文件,分析预检不达标的API。
|
|
17
|
+
3. 执行预检操作,查看预检结果文件,分析预检不达标的 API。
|
|
17
18
|
|
|
18
19
|
## 3 离线预检操作指导
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
### 3.1 使用 run_ut 执行预检
|
|
22
|
+
|
|
23
|
+
将 API 信息输入到 run_ut 模块进行精度检测并比对,运行如下命令:
|
|
24
|
+
|
|
25
|
+
|
|
21
26
|
```bash
|
|
22
27
|
msprobe -f mindspore run_ut -api_info ./dump.json -o ./checker_result
|
|
23
28
|
```
|
|
24
29
|
|
|
25
|
-
| 参数名称 | 说明
|
|
26
|
-
| ----------------------------
|
|
27
|
-
| -api_info 或 --api_info_file | 指定 API 信息文件 dump.json
|
|
28
|
-
| -o 或 --out_path | 指定预检结果存盘路径,默认“./”。
|
|
30
|
+
| 参数名称 | 说明 |参数类型 | 是否必选 |
|
|
31
|
+
| ---------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------- | ---------------------------------- |
|
|
32
|
+
| -api_info 或 --api_info_file | 指定 API 信息文件 dump.json。对其中的mint api以及部分Tensor api进行预检 | str | 是 |
|
|
33
|
+
| -o 或 --out_path | 指定预检结果存盘路径,默认“./”。 | str | 否 |
|
|
34
|
+
| -csv_path 或 --result_csv_path | 指定本次运行中断时生成的 `accuracy_checking_result_{timestamp}.csv` 文件路径,执行 run_ut 中断时,若想从中断处继续执行,配置此参数即可。需要指定为上次中断的 `accuracy_checking_result_{timestamp}.csv` 文件。详见 [3.3 断点续检](#33-断点续检)。 | str | 否 |
|
|
29
35
|
|
|
30
36
|
预检执行结果包括 `accuracy_checking_result_{timestamp}.csv` 和 `accuracy_checking_details_{timestamp}.csv` 两个文件。`accuracy_checking_result_{timestamp}.csv` 属于 API 级,标明每个 API 是否通过测试。建议用户先查看 `accuracy_checking_result_{timestamp}.csv` 文件,对于其中没有通过测试的或者特定感兴趣的 API,根据其 API Name 字段在 `accuracy_checking_details_{timestamp}.csv` 中查询其各个输出的达标情况以及比较指标。详细介绍请参见 [4 预检结果](#4-预检结果)。
|
|
31
37
|
|
|
38
|
+
### 3.2 使用 multi_run_ut 执行多线程预检
|
|
39
|
+
|
|
40
|
+
multi_run_ut 脚本,可以并行在多个Device执行 run_ut 操作,从而减少预检耗时。示例如下:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
msprobe -f mindspore multi_run_ut -api_info ./dump.json -d 0 1 2 3
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| 参数名称 | 说明 |参数类型 | 是否必选 |
|
|
47
|
+
| ---------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------- | ---------------------------------- |
|
|
48
|
+
| -api_info 或 --api_info_file | 指定 API 信息文件 dump.json。对其中的mint api以及部分Tensor api进行预检 | str | 是 |
|
|
49
|
+
| -o 或 --out_path | 指定预检结果存盘路径,默认“./”。 | str | 否 |
|
|
50
|
+
| -csv_path 或 --result_csv_path | 指定本次运行中断时生成的 `accuracy_checking_result_{timestamp}.csv` 文件路径,执行 run_ut 中断时,若想从中断处继续执行,配置此参数即可。需要指定为上次中断的 `accuracy_checking_result_{timestamp}.csv` 文件。详见 [3.3 断点续检](#33-断点续检)。 | str | 否 |
|
|
51
|
+
| -d 或 --device | 指定 Device ID,选择 UT 代码运行所在的卡,默认值为 0,支持同时指定 0 ~ Device数量的N - 1 ,例如 0 1 2 3 4 | List[int] | 否 |
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### 3.3 断点续检
|
|
57
|
+
|
|
58
|
+
断点续检操作通过如下命令执行:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
msprobe -f mindspore run_ut -api_info ./dump.json -csv_path xxx/accuracy_checking_result_{timestamp}.csv
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
精度预检 run_ut 过程中,若因环境、数据量过大等原因导致预检进程中断,那么当用户解决这些问题后,重新执行 run_ut 操作,可以通过断点续检操作继续前面未完成的预检,会在 -csv_path 指定的 `accuracy_checking_result_{timestamp}.csv` 文件以及对应的 `accuracy_checking_details_{timestamp}.csv` 文件中继续写入后续的结果,不会重新创建结果文件。
|
|
65
|
+
|
|
66
|
+
须指定为上次预检中断的 `accuracy_checking_result_{timestamp}.csv` 文件。请勿修改 `accuracy_checking_result_{timestamp}.csv` 和 `accuracy_checking_details_{timestamp}.csv` 文件以及文件名,否则不对断点续检的结果负责。
|
|
67
|
+
|
|
68
|
+
|
|
32
69
|
## 4 预检结果
|
|
33
70
|
|
|
34
71
|
精度预检生成的 `accuracy_checking_result_{timestamp}.csv` 和 `accuracy_checking_details_{timestamp}.csv` 文件内容详情如下:
|
|
@@ -45,9 +82,9 @@ msprobe -f mindspore run_ut -api_info ./dump.json -o ./checker_result
|
|
|
45
82
|
| MaxAbsErr | 被检验数据与标杆数据的最大绝对误差。 |
|
|
46
83
|
| MaxRelativeErr | 被检验数据与标杆数据的最大相对误差。 |
|
|
47
84
|
| Status | API 预检通过状态,pass 表示通过测试,error 表示未通过。 |
|
|
48
|
-
|
|
|
85
|
+
| Message | 提示信息。 |
|
|
49
86
|
|
|
50
|
-
|
|
87
|
+
注意:PyTorch 无法对 dtype 为整数类型的 tensor 进行反向求导,而 MindSpore 支持。反向过程的预检仅比较 dtype 为浮点型的输出。
|
|
51
88
|
|
|
52
89
|
`accuracy_checking_result_{timestamp}.csv`
|
|
53
90
|
|
|
@@ -63,6 +100,5 @@ Forward Test Success 和 Backward Test Success 是否通过测试是由 `accurac
|
|
|
63
100
|
|
|
64
101
|
### 4.1 API 预检指标
|
|
65
102
|
|
|
66
|
-
- API
|
|
67
|
-
|
|
68
|
-
- 余弦相似度大于0.99,并且最大绝对误差小于0.0001,标记“pass”,否则标记为“error”。
|
|
103
|
+
- API 预检指标是通过对 `accuracy_checking_details_{timestamp}.csv` 中的余弦相似度、最大绝对误差的数值进行判断,得出该 API 是否符合精度标准的参考指标。
|
|
104
|
+
- 余弦相似度大于 0.99,并且最大绝对误差小于 0.0001,标记“pass”,否则标记为“error”。
|