diff --git a/README.md b/README.md index 899f32e5c0c2b67774c6c36eb16211f12b15e698..06aaa0f6bf93d8822c266cfcb927c4e166973550 100644 --- a/README.md +++ b/README.md @@ -24,25 +24,17 @@ mstt包括精度工具(msprobe)和性能工具(msprof-analyze),分析 [MindStudio Probe(msprobe,MindStudio 精度调试工具)](./debug/accuracy_tools/msprobe)。 -## [性能工具](./profiler/msprof_analyze) +## [性能工具](./profiler) -1. [compare_tools(性能比对工具)](./profiler/msprof_analyze/compare_tools) +[msprof-analzye(MindStudio Profiler Analyze 性能分析工具)](./profiler/msprof_analzye) - 提供 NPU 与 GPU 性能拆解功能以及算子、通信、内存性能的比对功能。 +基于采集的性能数据进行分析,识别AI作业中的性能瓶颈。 -2. [cluster_analyse(集群分析工具)](./profiler/msprof_analyze/cluster_analyse) - - 提供多机多卡的集群分析能力(基于通信域的通信分析和迭代耗时分析), 当前需要配合 MindStudio Insight 的集群分析功能使用。 - -3. [advisor](./profiler/msprof_analyze/advisor) - - 将 Ascend PyTorch Profiler 或者 msprof 采集的 PyTorch 场景性能数据进行分析,并输出性能调优建议。 - -4. [bind_core](./profiler/affinity_cpu_bind) +[bind_core](./profiler/affinity_cpu_bind) 绑核脚本,支持非侵入修改工程代码,实现一键式绑核功能。 -5. [msMonitor](./msmonitor) +[msMonitor](./msmonitor) MindStudio一站式在线监控工具。 diff --git a/profiler/msprof_analyze/README.md b/profiler/msprof_analyze/README.md index f199380793a7862ca8e0af835657660c3e397a06..bacec50fdafb112727bba6076a945604eef87be9 100644 --- a/profiler/msprof_analyze/README.md +++ b/profiler/msprof_analyze/README.md @@ -1,98 +1,11 @@ -# 性能工具 - -MindStudio Training Tools工具针对训练&大模型场景,提供端到端性能调优工具msprof-analyze:用户采集到性能数据后,由MindStudio Training Tools的性能工具msprof-analyze提供统计、分析以及相关的调优建议。 - -## NPU性能数据采集 - -目前MindStudio Training Tools工具主要支持对Ascend PyTorch Profiler接口采集的性能数据进行分析,请参考官方文档:[Ascend PyTorch Profiler数据采集与分析](https://www.hiascend.com/document/detail/zh/canncommercial/80RC1/devaids/auxiliarydevtool/atlasprofiling_16_0006.html)。 - -### 环境和依赖 - -- 硬件环境请参见《[昇腾产品形态说明](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fdocument%2Fdetail%2Fzh%2Fcanncommercial%2F80RC22%2Fquickstart%2Fquickstart%2Fquickstart_18_0002.html)》。 -- 软件环境请参见《[CANN 软件安装指南](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fdocument%2Fdetail%2Fzh%2Fcanncommercial%2F80RC22%2Fsoftwareinst%2Finstg%2Finstg_0000.html%3FMode%3DPmIns%26OS%3DUbuntu%26Software%3DcannToolKit)》安装昇腾设备开发或运行环境,即toolkit软件包。 - -以上环境依赖请根据实际环境选择适配的版本。 - -### 版本配套说明 - -- Ascend PyTorch Profiler接口支持AscendPyTorch 1.11.0或更高版本,支持的PyTorch和CANN以及PyTorch和Python软件版本配套关系请参见《[Ascend Extension for PyTorch插件](https://gitee.com/ascend/pytorch)》。 -- MindSpore Profiler接口支持MindSpore 2.5.0或更高版本,支持的MindSpore和CANN以及MindSpore和Python软件版本配套关系请参见《[MindSpore-安装](https://www.mindspore.cn/install/)》。 -- Ascend PyTorch Profiler接口支持的固件驱动版本与配套CANN软件支持的固件驱动版本相同,开发者可通过“[昇腾社区-固件与驱动](https://gitee.com/link?target=https%3A%2F%2Fwww.hiascend.com%2Fhardware%2Ffirmware-drivers%2Fcommunity%3Fproduct%3D2%26model%3D28%26cann%3D8.0.RC3.alpha003%26driver%3D1.0.25.alpha)”页面根据产品型号与CANN软件版本获取配套的固件与驱动。 - -### 采集方式一:通过with语句进行采集 - -```python -import torch_npu -experimental_config = torch_npu.profiler._ExperimentalConfig( - aic_metrics=torch_npu.profiler.AiCMetrics.PipeUtilization, - profiler_level=torch_npu.profiler.ProfilerLevel.Level1, - l2_cache=False -) -with torch_npu.profiler.profile( - activities=[ - torch_npu.profiler.ProfilerActivity.CPU, - torch_npu.profiler.ProfilerActivity.NPU - ], - record_shapes=True, - profile_memory=True, - with_stack=True, - experimental_config=experimental_config, - schedule=torch_npu.profiler.schedule(wait=10, warmup=0, active=1, repeat=1), - on_trace_ready=torch_npu.profiler.tensorboard_trace_handler("./profiling_data") -) as prof: - # 模型训练代码 - for epoch, data in enumerate(dataloader): - train_model_one_step(model, data) - prof.step() -``` - -### 采集方式二:start,stop方式进行采集 - -```python -import torch_npu -experimental_config = torch_npu.profiler._ExperimentalConfig( - aic_metrics=torch_npu.profiler.AiCMetrics.PipeUtilization, - profiler_level=torch_npu.profiler.ProfilerLevel.Level1, - l2_cache=False -) -prof = torch_npu.profiler.profile( - activities=[ - torch_npu.profiler.ProfilerActivity.CPU, - torch_npu.profiler.ProfilerActivity.NPU - ], - record_shapes=True, - profile_memory=True, - with_stack=True, - experimental_config=experimental_config, - on_trace_ready=torch_npu.profiler.tensorboard_trace_handler("./profiling_data")) -# 模型训练代码 -for epoch, data in enumerate(dataloader): - if epoch == 11: - prof.start() - train_model_one_step(model, data) - prof.step() - if epoch == 11: - prof.stop() -``` - -### NPU性能数据目录结构 - -ascend pytorch profiler数据目录结构如下: +# msprof-analyze -``` -|- ascend_pytorch_profiling - |- * _ascend_pt - |- ASCEND_PROFILER_OUTPUT - |- trace_view.json - |- FRAMEWORK - |- PROF_XXX - |- profiler_info.json - |- * _ascend_pt -``` +## 📌 简介 +msprof-analyze(MindStudio Profiler Analyze)是MindStudio全流程工具链推出的性能分析工具,基于采集的性能数据进行分析,识别AI作业中的性能瓶颈。 -## 安装 +## 🔧 安装 -性能工具的安装方式包括:**pip安装**、**下载whl包安装**和**源代码编译安装**。 +msprof-analyze的安装方式包括:**pip安装**、**下载whl包安装**和**源代码编译安装**。 ### pip安装 @@ -100,7 +13,8 @@ ascend pytorch profiler数据目录结构如下: pip install msprof-analyze ``` -使用`pip install msprof-analyze==版本号`可安装指定版本的包,支持1.2.1及之后版本,版本号参见“**下载whl包安装**”。 +使用`pip install msprof-analyze==版本号`可安装指定版本的包,使用采集性能数据对应的CANN版本号即可。 +如不清楚版本号可不指定,使用最新程序包。 pip命令会自动安装最新的包及其配套依赖。 @@ -113,31 +27,8 @@ Successfully installed msprof-analyze-{version} ### 下载whl包安装 1. whl包获取。 + 请通过[发布程序包下载链接](#发布程序包下载链接)下载whl包。 - 请通过下表链接下载profiler工具whl包。 - -| profiler版本 | 发布日期 | 下载链接 | 校验码 | -|----------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ | -| 8.1.0 | 2025-07-30 | [msprof_analyze-8.1.0-py3-none-any.whl](https://ptdbg.obs.cn-north-4.myhuaweicloud.com/profiler/package/8.1.0/msprof_analyze-8.1.0-py3-none-any.whl) | 064f68ff22c88d91d8ec8c47045567d030d1f9774169811c618c06451ef697e4 | -| 2.0.2 | 2025-03-31 | [msprof_analyze-2.0.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.2/msprof_analyze-2.0.2-py3-none-any.whl) | 4227ff628187297b2f3bc14b9dd3a8765833ed25d527f750bc266a8d29f86935 | -| 2.0.1 | 2025-02-28 | [msprof_analyze-2.0.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.1/msprof_analyze-2.0.1-py3-none-any.whl) | 82dfe2c779dbab9015f61d36ea0c32d832b6d182454b3f7db68e6c0ed49c0423 | -| 2.0.0 | 2025-02-08 | [msprof_analyze-2.0.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.0/msprof_analyze-2.0.0-py3-none-any.whl) | 8e44e5f3e7681c377bb2657a600ad9841d3bed11061ddd7844c30e8a97242101 | -| 1.3.4 | 2025-01-20 | [msprof_analyze-1.3.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.4/msprof_analyze-1.3.4-py3-none-any.whl) | 8de92188d1a97105fb14cadcb0875ccd5f66629ee3bb25f37178da1906f4cce2 | -| 1.3.3 | 2024-12-26 | [msprof_analyze-1.3.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.3/msprof_analyze-1.3.3-py3-none-any.whl) | 27676f2eee636bd0c65243f81e292c7f9d30d7f985c772ac9cbaf10b54d3584e | -| 1.3.2 | 2024-12-20 | [msprof_analyze-1.3.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.2/msprof_analyze-1.3.2-py3-none-any.whl) | ceb227e751ec3a204135be13801f1deee6a66c347f1bb3cdaef596872874df06 | -| 1.3.1 | 2024-12-04 | [msprof_analyze-1.3.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.1/msprof_analyze-1.3.1-py3-none-any.whl) | eae5548804314110a649caae537f2c63320fc70ec41ce1167f67c1d674d8798e | -| 1.3.0 | 2024-10-12 | [msprof_analyze-1.3.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.0/msprof_analyze-1.3.0-py3-none-any.whl) | 8b09758c6b5181bb656a95857c32852f898c370e7f1041e5a08e4f10d5004d48 | -| 1.2.5 | 2024-09-25 | [msprof_analyze-1.2.5-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.5/msprof_analyze-1.2.5-py3-none-any.whl) | aea8ae8deac07b5b4980bd2240da27d0eec93b9ace9ea9eb2e3a05ae9072018b | -| 1.2.4 | 2024-09-19 | [msprof_analyze-1.2.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.4/msprof_analyze-1.2.4-py3-none-any.whl) | 7c392e72c3347c4034fd3fdfcccb1f7936c24d9c3eb217e2cc05bae1347e5ab7 | -| 1.2.3 | 2024-08-29 | [msprof_analyze-1.2.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.3/msprof_analyze-1.2.3-py3-none-any.whl) | 354a55747f64ba1ec6ee6fe0f05a53e84e1b403ee0341ec40cc216dd25fda14c | -| 1.2.2 | 2024-08-23 | [msprof_analyze-1.2.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.2/msprof_analyze-1.2.2-py3-none-any.whl) | ed92a8e4eaf5ada8a2b4079072ec0cc42501b1b1f2eb00c8fdcb077fecb4ae02 | -| 1.2.1 | 2024-08-14 | [msprof_analyze-1.2.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.1/msprof_analyze-1.2.1-py3-none-any.whl) | 7acd477417bfb3ea29029dadf175d019ad3212403b7e11dc1f87e84c2412c078 | -| 1.2.0 | 2024-07-25 | [msprof_analyze-1.2.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.0/msprof_analyze-1.2.0-py3-none-any.whl) | 6a4366e3beca40b4a8305080e6e441d6ecafb5c05489e5905ac0265787555f37 | -| 1.1.2 | 2024-07-12 | [msprof_analyze-1.1.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.2/msprof_analyze-1.1.2-py3-none-any.whl) | af62125b1f9348bf491364e03af712fc6d0282ccee3fb07458bc9bbef82dacc6 | -| 1.1.1 | 2024-06-20 | [msprof_analyze-1.1.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.1/msprof_analyze-1.1.1-py3-none-any.whl) | 76aad967a3823151421153d368d4d2f8e5cfbcb356033575e0b8ec5acea8e5e4 | -| 1.1.0 | 2024-05-28 | [msprof_analyze-1.1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.0/msprof_analyze-1.1.0-py3-none-any.whl) | b339f70e7d1e45e81f289332ca64990a744d0e7ce6fdd84a8d82e814fa400698 | -| 1.0 | 2024-05-10 | [msprof_analyze-1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.0/msprof_analyze-1.0-py3-none-any.whl) | 95b2f41c8c8e8afe4887b738c8cababcb4f412e1874483b6adae4a025fcbb7d4 | - 2. whl包校验。 1. 根据以上下载链接下载whl包到Linux安装环境。 @@ -205,50 +96,215 @@ Successfully installed msprof-analyze-{version} pip3 install ./msprof_analyze-{version}-py3-none-any.whl ``` -## 卸载和更新 - -若需要更新工具,请先卸载旧版本后再重新安装新版本,如下操作: +### 卸载和更新 -1. 卸载 - - ```bash - pip3 uninstall msprof-analyze - ``` - -2. 更新 +若需要更新工具,请先卸载旧版本后再重新安装新版本,操作如下: +```bash +# 卸载旧版本 +pip3 uninstall msprof-analyze +# 安装新版本 +pip3 install ./msprof_analyze-{version}-py3-none-any.whl +``` - ```bash - pip3 install ./msprof_analyze-{version}-py3-none-any.whl - ``` +## 🧰 使用方法 +### 数据准备 +msprof-analzye需要传入采集的性能数据文件夹,如何采集性能数据请参见[采集profiling性能数据指导](#采集profiling性能数据指导)章节。 -## 工具使用 +### 命令格式 +msprof-analzye性能分析工具通过命令行方式启动性能分析。命名格式如下: +``` +msprof-analyze -m [feature_option] -d [global_option] [analyze_option] +``` +`-m`指定分析能力,`[feature_option]`可指定对应特性,详见[分析特性介绍](#分析特性介绍)章节,必选。 +``为profiling性能数据文件夹,必选。 +`[global_option]`为全局参数,详见[全局参数说明](#全局参数)章节,可选。 +`[analyze_option]`为分析能力参数,详见[分析能力参数说明](#分析能力参数)章节,可选。 + +详细使用样例请参考[使用样例](#使用样例)章节。 + +### 参数说明 +#### 全局参数 +主要包括输入输出与格式参数、执行参数以及帮助信息等。 + + | 参数名 | 说明 | 是否必选 | + | --------------------- | ------------------------------------------------------------ | -------- | + | --profiling_path或-d | 性能数据汇集目录。未配置-o参数时,运行分析脚本之后会在该目录下自动创建cluster_analysis_output文件夹,保存分析数据。 | 是 | + | --output_path或-o | 自定义输出路径,运行分析脚本之后会在该目录下自动创建cluster_analysis_output文件夹,保存分析数据。 | 否 | + | --mode或-m | 分析能力选项,取值详见[分析能力特性说明](#分析特性介绍)表。 默认参数为all,all会执行step_trace_time和communication_matrix通信矩阵和communication_time通信耗时分析能力 | 否 | + | --export_type | 设置导出的数据形式。取值为db(.db格式文件)和notebook(Jupyter Notebook文件),默认值为db。 | 否 | + | --force | 强制执行,配置后可强制跳过如下情况:
指定的目录、文件的用户属主不属于当前用户,忽略属主判断直接执行。
csv文件大于5G、json文件大于10G、db文件大于8G,忽略文件过大判断直接执行。
配置该参数表示开启强制执行,默认未配置表示关闭。 | 否 | + | --parallel_mode | 设置收集多卡、多节点db数据时的并发方式。取值为concurrent(使用concurrent.feature进程池实现并发)。| 否 | + | --data_simplification | 数据精简模式。对于数据量过大的性能数据db文件,可以通过配置该参数将数据精简,并提高工具分析效率。配置该参数表示开启数据精简,默认未配置表示关闭,当前参数只针对all/communication_matrix/communication_time分析能力。 | 否 | + | -v,-V
--version | 查看版本号。 | 否 | + | -h,-H
--help | 命令行参数帮助信息。 | 否 | + +#### 分析能力参数 + + | 参数名 | 说明 | 是否必选 | + | --------------------- | ------------------------------------------------------------ | -------- | + | --rank_list | 对特定Rank上的数据进行统计,默认值为all(表示对所有Rank进行统计),须根据实际卡的Rank ID配置。应配置为大于等于0的整数,若所配置的值大于实际训练所运行的卡的Rank ID,则仅解析合法的RankID的数据,比如当前环境Rank ID为0到7,实际训练运行0到3卡,此时若配置Rank ID为0, 3, 4或不存在的10等其他值,则仅解析0和3。配置示例:--rank_list 0, 1, 2。
**需要对应分析能力适配才可使用, 当前分析能力设置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum时支持。** | 否 | + | --step_id | 性能数据Step ID,配置后对该Step的性能数据进行分析。需配置性能数据中实际存在的Step ID,默认未配置,表示全量分析。配置示例:--step_id=1。
**需要对应分析能力适配才可使用, 当前只有分析能力设置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum时支持。** | 否 | + | --top_num | 设置TopN耗时的通信算子的数量,默认值为15,配置示例:--top_num 20。
**只有-m配置hccl_sum时可配置此参数。** | 否 | + | --exclude_op_name | 控制compute_op_name结果是否包含op_name,示例:--exclude_op_name,后面不需要跟参数。
**只有-m配置compute_op_sum时可配置此参数。** | 否 | + | --bp | 要对比的标杆集群数据,示例:--bp {bp_cluster_profiling_path},表示profiling_path和bp_cluster_profiling_path的数据进行对比。
**只有-m配置cluster_time_compare_summary时可配置此参数。** | 否 | + +#### 子功能命令参数 +| 参数 | 说明 | +|---------------------|-------------------------------------------------------------------------------------------------------------------------| +| compare | [compare(性能比对子功能)](./compare_tools/README.md)。提供NPU与GPU性能拆解功能以及算子、通信、内存性能的比对功能。| +| advisor | [advisor(专家建议子功能)](./advisor/README.md)。基于性能数据进行分析,并输出性能调优建议。 | +| cluster | [cluster_analyse(集群分析工具)](./cluster_analyse/README.md)。提供集群分析能力,已作为默认子命令,不设置即为cluster集群分析功能 | +| auto-completion | 自动补全。配置后在当前视图下配置msprof-analyze工具所有的子参数时,可以使用Tab将所有子参数自动补全。 | + + +### 分析特性介绍 + +#### 拆解对比类 + +| 分析能力 | 介绍 | 介绍链接 | +|---------|----------------------------------------|-----| +| cluster_time_summary | 性能数据细粒度拆解,替换step_trace_time.csv内容。 | [link](./docs/cluster_time_summary.md) | +| cluster_time_compare_summary | 性能数据细粒度对比。 | [link](./docs/cluster_time_compare_summary.md) | + +#### 计算类特性 + +| 分析能力 | 介绍 | 介绍链接 | +|---------|----------------------------------------|-----| +| compute_op_sum | device侧运行的计算类算子汇总。 | - | +| freq_analysis | 识别是否aicore存在空闲(频率为800MHz)、异常(频率不为1800MHz或800MHz)的情况并给出分析结果。 | - | +| ep_load_balance | moe负载信息汇总分析。 | - | + +#### 通信类特性 + +| 分析能力 | 介绍 | 介绍链接 | +|---------|----------------------------------------|-----| +| communication_matrix | 通信矩阵分析。 | - | +| communication_time| 通信耗时分析。 | - | +| all | 默认值,会执行communication_matrix通信矩阵和communication_time通信耗时分析能力,并导出cluster_step_trace_time交付件。 | - | +| communication_group_map | 集群场景通信域与并行策略呈现。 | - | +| communication_time_sum | 集群场景通信时间和带宽汇总分析。 | - | +| communication_matrix_sum | 集群场景通信时间和带宽汇总分析。 | - | +| hccl_sum | 通信类算子信息汇总。 | - | +| pp_chart | pp流水图,针对pp并行下各个阶段的耗时分析与可视化能力。| [link](./docs/pp_chart.md) | +| slow_rank | 根据当前的快慢卡统计算法,展示各个rank得出的快慢卡影响次数,识别慢卡出现的原因。 | - | + +#### Host下发类特性 + +| 分析能力 | 介绍 | 介绍链接 | +|---------|----------------------------------------|-----| +| cann_api_sum | CANN层API的汇总。 | - | +| mstx_sum | MSTX自定义打点汇总。 | - | + +#### 其他特性 +| 分析能力 | 类别 | 介绍 | 介绍链接 | +|---------|----| ------------------------------------|-----| +| mstx2commop | 数据处理类 | 将通过MSTX内置通信打点的通信信息转换成通信算子表格式。 | - | +| p2p_pairing | 数据处理类 | P2P算子生成全局关联索引,输出的关联索引会作为一个新的字段`opConnectionId`附在`COMMUNICATION_OP`的表中。 | - | + +交付件详细内容请参见[recipe结果交付件表](./docs/recipe_output_format.md)文档。 + +### 使用样例 +#### 最简使用 ```bash -msprof-analyze advisor [-h] +# 只传入cluster_data性能数据文件夹,输入cluster_time_summary分析能力,在cluster_data输入文件夹下生成cluster_文件夹,保存分析结果信息 +msprof-analyze -m cluster_time_summary -d ./cluster_data ``` +#### 分析能力为all设置下使用 ```bash -msprof-analyze compare [-h] +# 可以输入-m参数=all 当前输出step_trace_time/通信矩阵/通信耗时交付件 +msprof-analyze -m all -d ./cluster_data ``` +#### 指定输出路径 ```bash -msprof-analyze cluster [-h] +# 设置-o参数,指定自定义输出路径 +msprof-analyze -m cluster_time_summary -d ./cluster_data -o ./cluster_output ``` +#### 设置输出格式 ```bash -msprof-analyze auto-completion [-h] +# 设置--export_type参数,设置输出格式 +msprof-analyze -m cluster_time_summary -d ./cluster_data --export_type db ``` +#### 性能对比(compare)子功能 +支持GPU与NPU之间、NPU与NPU之间两组性能数据的深度对比,通过多维度量化指标直观呈现性能差异。 + +```bash +# 基础用法:对比昇腾NPU与GPU性能数据 +msprof-analyze compare -d ./ascend_pt # 昇腾NPU性能数据目录 + -bp ./gpu_trace.json # GPU性能数据文件 + -o ./compare_output # 对比结果输出目录 ``` -msprof-analyze [-h] [-v] + +对比报告`performance_comparison_result_{timestamp}.xlsx`包含: +* 宏观性能拆分:按计算、通信、空闲三大维度统计耗时占比差异,快速识别性能损耗主要场景。 +* 细粒度对比:按算子(如 Conv、MatMul)、框架接口等粒度展示耗时差异,定位具体性能差距点。 + +> 对比规则维度、参数说明及报告解读,请参考 [msprof-analyze compare](./compare_tools/README.md)子功能介绍文档。 + +#### 专家建议(advisor)子功能 +自动分析性能数据,识别算子执行效率、下发调度、集群通信等潜在瓶颈,并生成分级优化建议,助力快速定位问题。 + +```bash +# 基础用法 +msprof-analyze advisor all -d ./prof_data -o ./advisor_output ``` -| 参数 | 说明 | -| -------------------- |-------------------------------------------------------------------------------------------------------------------------| -| advisor | [advisor](./advisor/README.md)。将Ascend PyTorch Profiler或者MindSpore采集的PyThon场景性能数据进行分析,并输出性能调优建议。 | -| compare | [compare_tools(性能比对工具)](./compare_tools/README.md)。提供NPU与GPU性能拆解功能以及算子、通信、内存性能的比对功能。 | -| cluster | [cluster_analyse(集群分析工具)](./cluster_analyse/README.md)。提供多机多卡的集群分析能力(基于通信域的通信分析和迭代耗时分析), 当前需要配合Ascend Insight的集群分析功能使用。 | -| auto-completion | 自动补全。配置后在当前视图下配置msprof-analyze工具所有的子参数时,可以使用Tab将所有子参数自动补全。 | -| -v,-V
--version | 查看版本号。 | -| -h,-H
--help | 命令行参数帮助信息。 | +分析完成后,在执行终端打印关键问题与优化建议,并生成 +* `mstt_advisor_{timestamp}.html`按重要程度标记的优化建议 +* `mstt_advisor_{timestamp}.xlsx`问题综述与详细的分析信息 + +> 详细分析规则、参数配置及结果解读,请参考 [msprof-analyze advisor](./advisor/README.md)子功能介绍文档。 + +## 扩展功能 +### 自定义开发指导 +用户可自定义一套性能数据的分析规则,需要详细了解性能分析的开发人员,具体开发指导请参见[自定义分析能力开发指导](./docs/custom_analysis_guide.md)。 + + +## 附录 +### 采集profiling性能数据指导 + * msprof 场景:参见“性能数据采集 > [msprof采集通用命令](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/T&ITools/Profiling/atlasprofiling_16_0008.html)”。 + * PyTorch 场景:参见“性能数据采集 > [PyTorch](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/msquickstart/atlasquick_train_0018.html)”。 + * MindSpore 场景:参见“性能数据采集 > [MindSpore](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/msquickstart/atlasquick_train_0017.html)”。 + +### 发布程序包下载链接 +| profiler版本 | 发布日期 | 下载链接 | 校验码 | +|----------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ | +| 8.1.0 | 2025-07-30 | [msprof_analyze-8.1.0-py3-none-any.whl](https://ptdbg.obs.cn-north-4.myhuaweicloud.com/profiler/package/8.1.0/msprof_analyze-8.1.0-py3-none-any.whl) | 064f68ff22c88d91d8ec8c47045567d030d1f9774169811c618c06451ef697e4 | +| 2.0.2 | 2025-03-31 | [msprof_analyze-2.0.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.2/msprof_analyze-2.0.2-py3-none-any.whl) | 4227ff628187297b2f3bc14b9dd3a8765833ed25d527f750bc266a8d29f86935 | +| 2.0.1 | 2025-02-28 | [msprof_analyze-2.0.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.1/msprof_analyze-2.0.1-py3-none-any.whl) | 82dfe2c779dbab9015f61d36ea0c32d832b6d182454b3f7db68e6c0ed49c0423 | +| 2.0.0 | 2025-02-08 | [msprof_analyze-2.0.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/2.0.0/msprof_analyze-2.0.0-py3-none-any.whl) | 8e44e5f3e7681c377bb2657a600ad9841d3bed11061ddd7844c30e8a97242101 | +| 1.3.4 | 2025-01-20 | [msprof_analyze-1.3.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.4/msprof_analyze-1.3.4-py3-none-any.whl) | 8de92188d1a97105fb14cadcb0875ccd5f66629ee3bb25f37178da1906f4cce2 | +| 1.3.3 | 2024-12-26 | [msprof_analyze-1.3.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.3/msprof_analyze-1.3.3-py3-none-any.whl) | 27676f2eee636bd0c65243f81e292c7f9d30d7f985c772ac9cbaf10b54d3584e | +| 1.3.2 | 2024-12-20 | [msprof_analyze-1.3.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.2/msprof_analyze-1.3.2-py3-none-any.whl) | ceb227e751ec3a204135be13801f1deee6a66c347f1bb3cdaef596872874df06 | +| 1.3.1 | 2024-12-04 | [msprof_analyze-1.3.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.1/msprof_analyze-1.3.1-py3-none-any.whl) | eae5548804314110a649caae537f2c63320fc70ec41ce1167f67c1d674d8798e | +| 1.3.0 | 2024-10-12 | [msprof_analyze-1.3.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.3.0/msprof_analyze-1.3.0-py3-none-any.whl) | 8b09758c6b5181bb656a95857c32852f898c370e7f1041e5a08e4f10d5004d48 | +| 1.2.5 | 2024-09-25 | [msprof_analyze-1.2.5-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.5/msprof_analyze-1.2.5-py3-none-any.whl) | aea8ae8deac07b5b4980bd2240da27d0eec93b9ace9ea9eb2e3a05ae9072018b | +| 1.2.4 | 2024-09-19 | [msprof_analyze-1.2.4-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.4/msprof_analyze-1.2.4-py3-none-any.whl) | 7c392e72c3347c4034fd3fdfcccb1f7936c24d9c3eb217e2cc05bae1347e5ab7 | +| 1.2.3 | 2024-08-29 | [msprof_analyze-1.2.3-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.3/msprof_analyze-1.2.3-py3-none-any.whl) | 354a55747f64ba1ec6ee6fe0f05a53e84e1b403ee0341ec40cc216dd25fda14c | +| 1.2.2 | 2024-08-23 | [msprof_analyze-1.2.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.2/msprof_analyze-1.2.2-py3-none-any.whl) | ed92a8e4eaf5ada8a2b4079072ec0cc42501b1b1f2eb00c8fdcb077fecb4ae02 | +| 1.2.1 | 2024-08-14 | [msprof_analyze-1.2.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.1/msprof_analyze-1.2.1-py3-none-any.whl) | 7acd477417bfb3ea29029dadf175d019ad3212403b7e11dc1f87e84c2412c078 | +| 1.2.0 | 2024-07-25 | [msprof_analyze-1.2.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.2.0/msprof_analyze-1.2.0-py3-none-any.whl) | 6a4366e3beca40b4a8305080e6e441d6ecafb5c05489e5905ac0265787555f37 | +| 1.1.2 | 2024-07-12 | [msprof_analyze-1.1.2-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.2/msprof_analyze-1.1.2-py3-none-any.whl) | af62125b1f9348bf491364e03af712fc6d0282ccee3fb07458bc9bbef82dacc6 | +| 1.1.1 | 2024-06-20 | [msprof_analyze-1.1.1-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.1/msprof_analyze-1.1.1-py3-none-any.whl) | 76aad967a3823151421153d368d4d2f8e5cfbcb356033575e0b8ec5acea8e5e4 | +| 1.1.0 | 2024-05-28 | [msprof_analyze-1.1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.1.0/msprof_analyze-1.1.0-py3-none-any.whl) | b339f70e7d1e45e81f289332ca64990a744d0e7ce6fdd84a8d82e814fa400698 | +| 1.0 | 2024-05-10 | [msprof_analyze-1.0-py3-none-any.whl](https://ptdbg.obs.myhuaweicloud.com/profiler/package/1.0/msprof_analyze-1.0-py3-none-any.whl) | 95b2f41c8c8e8afe4887b738c8cababcb4f412e1874483b6adae4a025fcbb7d4 | + + +## FAQ +暂无 + +## 致谢 + +🔎 msprof-analyze 由华为公司的下列部门联合贡献 : + +华为公司: + +- 昇腾计算MindStudio开发部 +- 昇腾计算生态使能部 +- 2012网络实验室 +感谢来自社区的每一个PR,欢迎贡献 msprof-analzye! \ No newline at end of file diff --git a/profiler/msprof_analyze/cli/cluster_cli.py b/profiler/msprof_analyze/cli/cluster_cli.py index adaf0f8d7cab8eff139125fbb4699ea962e3a427..9fd9b19571e7e6c4c87045ae54317d2e36cda5ca 100644 --- a/profiler/msprof_analyze/cli/cluster_cli.py +++ b/profiler/msprof_analyze/cli/cluster_cli.py @@ -17,6 +17,7 @@ import click from msprof_analyze.prof_common.constant import Constant from msprof_analyze.cluster_analyse.cluster_analysis import ALL_FEATURE_LIST, Interface from msprof_analyze.prof_common.path_manager import PathManager +from msprof_analyze.advisor.version import print_version_callback, cli_version context_settings = dict(Constant.CONTEXT_SETTINGS) context_settings['ignore_unknown_options'] = True @@ -35,6 +36,9 @@ context_settings['ignore_unknown_options'] = True @click.option("--export_type", help="recipe export type", type=click.Choice(["db", "notebook"]), default="db") @click.option("--rank_list", type=str, help="Rank id list", default='all') @click.option("--step_id", type=int, help="Step id", default=Constant.VOID_STEP) +@click.option('--version', '-V', '-v', is_flag=True, + callback=print_version_callback, expose_value=False, + is_eager=True, help=cli_version()) @click.argument('args', nargs=-1) def cluster_cli(**kwargs) -> None: Interface(kwargs).run() diff --git a/profiler/msprof_analyze/cli/entrance.py b/profiler/msprof_analyze/cli/entrance.py index 534a9b133c7e60d1442cb290490a79e9256ce43d..466d7cf0bfa66c6c8bc332262d0bd09c38bd42ec 100644 --- a/profiler/msprof_analyze/cli/entrance.py +++ b/profiler/msprof_analyze/cli/entrance.py @@ -54,14 +54,29 @@ class SpecialHelpOrder(click.Group): self.list_commands = self.list_commands_for_help return super(SpecialHelpOrder, self).get_help(ctx) + def parse_args(self, ctx, args): + # 检查是否有已知的子命令 + has_subcommand = any(arg in self.list_commands(ctx) for arg in args if not arg.startswith('-')) -@click.group(context_settings=CONTEXT_SETTINGS, cls=SpecialHelpOrder) + # 如果没有子命令但有参数,自动添加 cluster 子命令 + if not has_subcommand and args: + args = ['cluster'] + args + # 如果没有子命令也没有参数,执行--help + elif not has_subcommand and not args: + args = ['--help'] + + return super(SpecialHelpOrder, self).parse_args(ctx, args) + + +@click.group(context_settings=CONTEXT_SETTINGS, cls=SpecialHelpOrder, invoke_without_command=True) @click.option('--version', '-V', '-v', is_flag=True, callback=print_version_callback, expose_value=False, is_eager=True, help=cli_version()) -def msprof_analyze_cli(**kwargs): - pass - +@click.pass_context +def msprof_analyze_cli(ctx, **kwargs): + """如果没有子命令,默认执行 cluster""" + if ctx.invoked_subcommand is None: + ctx.invoke(cluster_cli) msprof_analyze_cli.add_command(analyze_cli, name="advisor") msprof_analyze_cli.add_command(compare_cli, name="compare") diff --git a/profiler/msprof_analyze/cluster_analyse/README.md b/profiler/msprof_analyze/cluster_analyse/README.md index ddac0672c1a4b6aab56410caf8c3635764ca1c97..184421e8ea90ab4e69fd23a681305b656c5c23b0 100644 --- a/profiler/msprof_analyze/cluster_analyse/README.md +++ b/profiler/msprof_analyze/cluster_analyse/README.md @@ -1,906 +1,2 @@ -# 集群分析工具 -cluster_analyse(集群分析工具)是在集群场景下,通过此工具来进行集群数据的分析,当前主要对基于通信域的迭代内耗时分析、通信时间分析以及通信矩阵分析为主, 从而定位慢卡、慢节点以及慢链路问题。 - -## 性能数据采集 -当前集群调优工具主要支持PyTorch场景的Ascend PyTorch Profiler采集方式和MindSpore场景的MindSpore Profiler采集方式以及msprof命令行工具采集方式下的集群数据。 - -此工具只需要NPU的性能数据作为输入。 - -Ascend PyTorch Profiler采集方法请参见《[NPU性能数据采集](https://gitee.com/ascend/mstt/tree/master/profiler/msprof_analyze#npu性能数据采集)》,MindSpore Profiler采集方法请参见《[性能调试](https://www.mindspore.cn/mindinsight/docs/zh-CN/r2.3/performance_profiling_ascend.html)》,msprof命令行采集方法请参见《[msprof命令行工具](https://www.hiascend.com/document/detail/zh/canncommercial/800/devaids/devtools/profiling/atlasprofiling_16_0010.html)》。 - -我们要求至少是L1级别的数据。 -```python -experimental_config = torch_npu.profiler._ExperimentalConfig( - profiler_level=torch_npu.profiler.ProfilerLevel.Level1 -) -``` -### 确认数据是否可用 - -通过上述三种方式获得性能数据,打开采集到的某张卡数据,可用的数据应该具备: - -- Ascend PyTorch Profiler采集的\*ascend_pt目录或MindSpore Profiler采集的\*ascend_ms目录: - - - ./profiler_info_x.json, - - ./ASCEND_PROFILER_OUTPUT/step_trace_time.csv, - - ./ASCEND_PROFILER_OUTPUT/trace_view.json, - - ./ASCEND_PROFILER_OUTPUT/kernel_details.csv, - - ./ASCEND_PROFILER_OUTPUT/communication.json, - - ./ASCEND_PROFILER_OUTPUT/communication_matrix.json - - 或者具备: - - - analysis.db - - ascend_pytorch_profiler_{rank_id}.db - -- msprof命令行采集的PROF_XXX目录: - - - --type=db、--export=on情况下解析的:msprof_{timestamp}.db - - --type=db、--analyze=on情况下解析的:analyze/communication_analyzer.db - -以上csv、json文件与db文件只能存在一类,否则集群分析工具解析异常。MindSpore场景暂不支持以上db文件。 - -确认这几个文件生成后,继续下面的集群分析。 - -## 数据汇聚与解析 - -### 操作步骤 - -1. 参见《[性能工具](../README.md)》完成工具安装。建议安装最新版本。 - -2. 将所有卡的数据拷贝并汇集到一个目录下,运行以下命令,在该目录下即可生成cluster_analysis_output文件夹。 - - ```bash - msprof-analyze cluster -d {cluster profiling data path} [-m mode] [-o output_path] [--data_simplification] [--force] - ``` - - 或 - - ```bash - python3 cluster_analysis.py -d {cluster profiling data path} [-m mode] [-o output_path] [--data_simplification] [--force] - ``` - - 命令示例: - - ```bash - msprof-analyze cluster -d ./cluster_profiling_data_path -m cann_api_sum --parallel_mode concurrent - ``` - - 或 - - ```bash - python3 cluster_analysis.py -d ./cluster_profiling_data_path -m cann_api_sum --parallel_mode concurrent - ``` - - 参数说明: - - | 参数名 | 说明 | 是否必选 | - |-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------- | - | --profiling_path或-d | 性能数据汇集目录。未配置-o参数时,运行分析脚本之后会在该目录下自动创建cluster_analysis_output文件夹,保存分析数据。 | 是 | - | --output_path或-o | 自定义输出路径,运行分析脚本之后会在该目录下自动创建cluster_analysis_output文件夹,保存分析数据。 | 否 | - | --mode或-m | 数据解析模式,取值详见“**--mode参数说明**”表。 | 否 | - | --data_simplification | 数据精简模式。对于数据量过大的性能数据db文件,可以通过配置该参数将数据精简,并提高工具分析效率。配置该参数表示开启数据精简,默认未配置表示关闭。 | 否 | - | --force | 强制执行cluster。配置后可强制跳过如下情况:
指定的目录、文件的用户属主不属于当前用户,忽略属主判断直接执行。
csv文件大于5G、json文件大于10G、db文件大于8G,忽略文件过大判断直接执行。
配置该参数表示开启强制执行,默认未配置表示关闭。 | 否 | - | --parallel_mode | 设置收集多卡、多节点db数据时的并发方式。取值为concurrent(使用concurrent.feature进程池实现并发)。
**只有-m配置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum和自定义分析参数时可配置此参数。** | 否 | - | --export_type | 设置导出的数据形式。取值为db(.db格式文件)和notebook(Jupyter Notebook文件),默认值为db。
**只有-m配置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum和自定义分析参数时可配置此参数。** | 否 | - | --rank_list | 对特定Rank上的数据进行统计,默认值为all(表示对所有Rank进行统计),须根据实际卡的Rank ID配置。应配置为大于等于0的整数,若所配置的值大于实际训练所运行的卡的Rank ID,则仅解析合法的RankID的数据,比如当前环境Rank ID为0到7,实际训练运行0到3卡,此时若配置Rank ID为0, 3, 4或不存在的10等其他值,则仅解析0和3。配置示例:--rank_list 0, 1, 2。
**只有-m配置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum和自定义分析参数时可配置此参数。** | 否 | - | --step_id | 性能数据Step ID,配置后对该Step的性能数据进行分析。需配置性能数据中实际存在的Step ID,默认未配置,表示全量分析。配置示例:--step_id=1。
**只有-m配置cann_api_sum、compute_op_sum、hccl_sum、mstx_sum和自定义分析参数时可配置此参数。** | 否 | - | --top_num | 设置TopN耗时的通信算子的数量,默认值为15,配置示例:--top_num 20。
**只有-m配置hccl_sum时可配置此参数。** | 否 | - | --exclude_op_name | 控制compute_op_name结果是否包含op_name,示例:--exclude_op_name,后面不需要跟参数。
**只有-m配置compute_op_sum时可配置此参数。** | 否 | - | --bp | 标杆数据路径,**只有-m配置cluster_time_compare_summary时可配置此参数。** | 否 | - - --mode参数说明: - - --mode参数设置不同的数据解析模式,可分析生成cluster_analysis.db交付件,交付件详细内容请参见[cluster_analysis.db交付件表结构说明](#cluster_analysisdb交付件表结构说明)。 - -| 参数名 | 说明 | 是否必选 | -|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------| -| communication_matrix | 解析通信矩阵数据。 | 否 | -| communication_time | 解析通信耗时数据。 | 否 | -| all | 解析内容包括:
通信矩阵communication_matrix
通信耗时数据communication_time
汇总集群内的节点信息(基于ascend_pytorch_profiler_{rank_id}.db生成)
--mode参数默认值为all。 | 否 | -| cann_api_sum | 集群API性能数据汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/CannApiSum目录下输出交付件stats.ipynb。 | 否 | -| compute_op_sum | 集群场景性能数据的device运行算子信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/ComputeOpSum目录下输出交付件stats.ipynb;可根据实际情况决定是否打开--exclude_op_name。 | 否 | -| hccl_sum | 集合通信算子耗时分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/HcclSum目录下输出交付件stats.ipynb。 | 否 | -| mstx_sum | 集群场景mstx打点信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。--export_type为db时,输出交付件cluster_analysis.db;--export_type为notebook时,在cluster_analysis_output/MstxSum目录下输出交付件stats.ipynb。 | 否 | -| communication_group_map | 集群场景通信域与并行策略呈现,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件和analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | -| communication_time_sum | 集群场景通信时间和带宽汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | -| communication_matrix_sum | 集群场景通信矩阵汇总分析,输入性能数据需要基于analysis.db。--export_type为db时,输出交付件cluster_analysis.db。 | 否 | -| freq_analysis | 集群场景aicore frequency信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。打印输出是否aicore存在空闲(频率为800MHz)、异常(频率不为1800MHz或800MHz)的现象。如果有,则在输出交付件cluster_analysis.db增加对应的卡和频率信息。 | 否 | -| ep_load_balance | 集群场景moe负载信息汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db增加EPTokensSummary, TopEPTokensInfo分析表格。 | 否 | -| slow_rank | 集群场景通信算子快慢卡汇总分析,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件cluster_analysis.db中展示各个rank按照当前的快慢卡统计算法得出的快慢卡影响次数。 | 否 | -| mstx2commop | 集群场景基于mstx打点信息生成通信算子信息,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出交付件ascend_pytorch_profiler_{rank_id}.db增加COMMUNICATION_OP, STRING_IDS分析表格。 | 否 | -| cluster_time_summary | 集群场景迭代耗时细粒度拆解,详见[集群耗时细粒度分析与对比指南](../docs/cluster_time_summary.md)。 | 否 | -| cluster_time_compare_summary | 集群间迭代耗时比对,详见[集群耗时细粒度分析与对比指南](../docs/cluster_time_summary.md)。 | 否 | -| p2p_pairing | 集群场景P2P算子生成全局关联索引,输入性能数据需要基于ascend_pytorch_profiler_{rank_id}.db文件。输出的关联索引会作为一个新的字段`opConnectionId`附在原性能数据ascend_pytorch_profiler_{rank_id}.db文件的`COMMUNICATION_OP`的表中。 | 否 | -| pp_chart | 基于打点后的ascend_pytorch_profiler_{rank_id}.db文件,分析打点数据,还原pp流水图,详见[pp流水图采集和分析指导](../docs/pp_chart.md)。 | 否 | -| 自定义分析参数 | 与cann_api_sum、compute_op_sum、hccl_sum等参数功能类似,用户可自定义一套性能数据的分析规则,要求用户开发者详细了解性能分析规则,具体开发指导请参见“[自定义分析规则开发指导](#自定义分析规则开发指导)”。 | 否 | - - -### 交付件 - -集群分析工具的交付件通过MindStudio Insight工具展示,详见《[MindStudio Insight用户指南](https://www.hiascend.com/document/detail/zh/mindstudio/70RC3/msinsightug/msascendinsightug/Insight_userguide_0002.html)》。 - -#### cluster_step_trace_time.csv - -数据解析模式为communication_matrix、communication_time或all时均生成。 - -A列: Step数,是采集性能数据时设置的,一般来说集群性能数据采集一个step足够,如果采集多个step,需要先筛选一下。 - -B列: Type,主要分两种,rank和stage,和后面的Index强相关,可以理解为一个是单卡rank,一个是rank group(pp 并行的stage),如果type为stage,则后面D-K列信息为rank group下的最大值(**Level0场景下没有stage类型**)。 - -C列:Index,与type相关,表示卡号。 - -D列:Computing, 此列统计计算时间。 - -E列:Communication(Not Overlapped),此列统计未被掩盖的通信耗时。 - -F列:Overlapped,统计计算与通信重叠的耗时。 - -G列:Communication,通信时间的全部耗时。 - -H列:Free,空闲时间,指device侧既不在通信也不在计算的耗时,可能在做sdma拷贝或者空等。 - -I列:Stage时间,I、J、K列属于pp并行时有效的数值,stage时间代表除receive算子时间外的时间。 - -J列:Bubble时间,指receive时间的总和。 - -K列:Communication(Not Overlapped and Exclude Receive)指剔除receive算子外的并且不被掩盖的通信时间。 - -L列:Preparing,指迭代开始到首个计算或通信算子运行的时间。 - -M列:DP Index,指集群数据按照并行策略切分后所属DP组的索引, 如果没有采集则不显示。 - -N列:PP Index,指集群数据按照并行策略切分后所属PP组的索引,如果没有采集则不显示。 - -O列:TP Index,指集群数据按照并行策略切分后所属TP组的索引,如果没有采集则不显示。 - -**Tips**:先筛选B列type为stage,看stage间是否有问题,再筛选B列type为rank,看rank是否有问题,根据以下几点排查。 - -* 根据Computing的时间差异判断是否有慢卡,或者有负载不均衡的现象。 - -* 根据Free统计是否有host bound或者分布不均现象。 - -* 根据Communication(Not Overlapped and Exclude Receive)时间判断是否通信耗时占比过大。 - -* 根据Bubble时间的占比和理论计算公式判断bubble设置是否合理,stage间是否有不均衡现象。 - -以上时间理论上都应该处于持平状态,即(最大值-最小值)/均值≤5%,否则就可能出现慢卡。 - -#### cluster_communication_matrix.json - -数据解析模式为communication_matrix或all时生成。 - -直接打开json(vscode或json查看器),搜索“Total”, 会有多个搜索结果,一般来说链路带宽信息的结构: - -```bash -{src_rank}-{dst_rank}: { - "Transport Type": "LOCAL", - "Transit Time(ms)": 0.02462, - "Transit Size(MB)": 16.777216, - "Op Name": "", - "Bandwidth(GB/s)": 681.4466 -} -``` -**Tips**:可以根据rank互联的带宽以及链路类型,判断是否有慢链路的问题。 - -- “LOCAL”是片内拷贝,速度最高。 -- “HCCS”或“PCIE”是节点内片间拷贝,速度居中。 -- “RDMA”是节点间拷贝,速度最低。 - -#### cluster_communication.json - -数据解析模式为communication_time或all时生成。 - -主要为通信耗时数据。 - -#### cluster_analysis.db - -解析analysis.db或ascend_pytorch_profiler_{rank_id}.db生成的交付件,根据数据解析模式不同而解析不同的数据,详情介绍请参见[cluster_analysis.db交付件表结构说明](#cluster_analysisdb交付件表结构说明) - -#### communication_group.json - -记录通信域信息,解析analysis.db生成的交付件,collective表示集合通信域,P2P表示点对点通信,用户无须关注该文件。 - -#### stats.ipynb - -- 数据解析模式为cann_api_sum时生成,保存在cluster_analysis_output/CannApiSum目录下。 - - 可使用jupyter notebook工具或MindStudio Insight工具打开,主要展示集群API耗时信息。 - -- 数据解析模式为compute_op_sum时生成,保存在cluster_analysis_output/ComputeOpSum目录下。 - - 可使用jupyter notebook工具或MindStudio Insight工具打开,主要展示集群计算算子耗时分析(将集群所有计算算子进行汇总并以图表展示),集群Rank计算算子耗时分析(将每个Rank的计算算子进行各自汇总)。 - -- 数据解析模式为hccl_sum时生成,保存在cluster_analysis_output/HcclSum目录下。 - - 可使用jupyter notebook工具或MindStudio Insight工具打开,主要展示集群通信算子耗时分析(将集群所有通信算子进行汇总并以图表展示),集群Rank通信算子耗时分析(将每个Rank的通信算子进行各自汇总)、Top通信算子信息展示。 - -- 数据解析模式为mstx_sum时生成,保存在cluster_analysis_output/MstxSum目录下。 - - 可使用jupyter notebook工具或MindStudio Insight工具打开,主要展示集群场景mstx打点信息,分为框架侧、CANN侧和Device侧三部分的打点信息。 - -## cluster_analysis.db交付件表结构说明 - -说明: - -msprof-analyze配置--mode参数时可分析并输出cluster_analysis.db交付件,本节介绍该交付件的表结构和字段说明。 - -### compute_op_sum - -设置-m compute_op_sum时,会生成以下表。 - -#### ComputeOpAllRankStats - -说明: - -基于db格式的集群性能数据,针对全部rank的数据,以OpType和TaskType分组,对计算算子的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpType | TEXT | 计算算子类型 | -| TaskType | TEXT | 算子执行的加速器类型 | -| Count | INTEGER | 以OpType和TaskType分组进行统计的算子数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | - -#### ComputeOpPerRankStatsByOpType - -说明: - -基于db格式的集群性能数据,针对每个rank的数据,以OpType和TaskType分组,对计算算子的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpType | TEXT | 计算算子类型 | -| TaskType | TEXT | 算子执行的加速器类型 | -| Count | INTEGER | 以OpType和TaskType分组进行统计的算子数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| Rank | INTEGER | rank_id | - -#### ComputeOpPerRankStatsByOpName - -说明: - -配置--exclude_op_name参数时不会生成该表; -基于db格式的集群性能数据,针对每个rank的数据,以OpName、OpType、TaskType和InputShapes分组,对计算算子的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpName | TEXT | 计算算子名字 | -| OpType | TEXT | 计算算子类型 | -| TaskType | TEXT | 算子执行的加速器类型 | -| InputShapes | TEXT | 算子的输入维度 | -| Count | INTEGER | 这个分组的算子数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| Rank | INTEGER | rank_id | - -### cann_api_sum - -设置-m cann_api_sum时,会生成以下表。 - -#### CannApiSum - -说明: - -基于db格式的集群性能数据,针对全部rank的数据,对每一种api(名字不同)的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| name | TEXT | API名字 | -| timeRatio | REAL | API的耗时占所有API总耗时的百分比 | -| totalTimeNs | INTEGER | API的总耗时,单位ns | -| totalCount | INTEGER | API的数量 | -| averageNs | REAL | 耗时的平均值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| medNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| minNs | REAL | 耗时的最小值,单位ns | -| maxNs | REAL | 耗时的最大值,单位ns | -| stdev | REAL | 耗时的标准差,单位ns | -| minRank | TEXT | minNs对应的rank的集合 | -| maxRank | TEXT | maxNs对应的rank的集合 | - -#### CannApiSumRank - -说明: - -基于db格式的集群性能数据,针对每个rank的数据,对每一种api(名字不同)的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| name | TEXT | API名字 | -| durationRatio | REAL | API的耗时占卡内所有API总耗时的百分比 | -| totalTimeNs | INTEGER | API的总耗时,单位ns | -| totalCount | INTEGER | API的数量 | -| averageNs | REAL | 耗时的平均值,单位ns | -| minNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| medNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| maxNs | REAL | 耗时的最大值,单位ns | -| stdev | REAL | 耗时的标准差,单位ns | -| rank | INTEGER | rank_id | - -### hccl_sum - -设置-m hccl_sum时,会生成以下表。 - -#### HcclAllRankStats - -说明: - -基于db格式的集群性能数据,针对全部rank的数据,对每一种通信算子类型(例如hcom_broadcast_)的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpType | TEXT | 通信算子类型 | -| Count | INTEGER | 数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | - -#### HcclPerRankStats - -说明: - -基于db格式的集群性能数据,针对每个rank的数据,对每一种通信算子类型(例如hcom_broadcast_)的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpType | TEXT | 通信算子类型 | -| Count | INTEGER | 数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| Rank | INTEGER | rank_id | - -#### HcclGroupNameMap - -说明: - -通信域内包含的rank。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| GroupName | TEXT | 通信域,例如:10.170.22.98%enp67s0f5_60000_0_1708156014257149 | -| GroupId | TEXT | 通信域的hash值的后三位 | -| Ranks | TEXT | 该通信域的所有rank | - -#### HcclTopOpStats - -说明: - -基于db格式的集群性能数据,对所有rank的通信算子的耗时进行分析,展示耗时平均值排名TOP N(默认为 15)的通信算子的数据。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| OpName | TEXT | 通信算子名,例如hcom_allReduce__606_0_1 | -| Count | INTEGER | 数量 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| MinRank | INTEGER | 该通信算子耗时最小的rank | -| MaxRank | INTEGER | 该通信算子耗时最大的rank | - -### communication_group_map - -设置-m communication_group_map,会生成以下表。 - -#### CommunicationGroupMapping - -说明: - -基于db格式的集群性能数据,生成通信域与并行策略的对应关系。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| type | TEXT | 算子类型,包含collective和p2p, 其中算子名包含"send","recv","receive"的算子被认为是p2p | -| rank_set | TEXT | 通信域内包含的rank(global rank)| -| group_name | TEXT | 通信域的hash值,可映射成group_id | -| group_id | TEXT | hccl内部定义的通信域名字,例如:10.170.22.98%enp67s0f5_60000_0_1708156014257149 | -| pg_name | TEXT | 业务定义的通信域名字,例如:"dp","dp_cp","mp"等等 | - -### communication_time_sum - -设置-m communication_time_sum时,会生成以下表。 - -#### ClusterCommunicationTime - -说明: - -基于db格式的集群性能数据,分析集群通信时间。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| step | TEXT | 算子所属的step | -| rank_id | INTEGER | global rank | -| hccl_op_name | TEXT | 通信算子名,例如hcom_allReduce__606_0_1 | -| group_name | TEXT | 通信域hashId,例如3915571125887837303 | -| start_timestamp | REAL | 开始时间,单位us | -| elapsed_time | REAL | 通信总耗时,单位ms | -| transit_time | REAL | 传输时间,单位ms | -| wait_time | REAL | 等待时间,单位ms | -| synchronization_time | REAL | 同步时间,单位ms | -| idle_time | REAL | 空闲时间,单位ms | -| synchronization_time_ratio | REAL | 同步时间占比,synchronization_time /(transit_time + synchronization_time) | -| wait_time_ratio | REAL | 等待时间占比,wait_time /(transit_time + wait_time) | - -#### ClusterCommunicationBandwidth - -说明: - -基于db格式的集群性能数据,分析集群通信带宽。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| step | TEXT | 算子所属的step | -| rank_id | INTEGER | global rank | -| hccl_op_name | TEXT | 通信算子名,例如hcom_allReduce__606_0_1 | -| group_name | TEXT | 通信域hashId,例如3915571125887837303 | -| band_type | TEXT | 传输类型,包含:LOCAL、SDMA、RDMA、HCCS等 | -| transit_size | REAL | 传输的数据量,单位MB | -| transit_time | REAL | 传输耗时,单位ms | -| bandwidth | REAL | 带宽,单位GB/s | -| large_packet_ratio | REAL | 大数据包的比例 | -| package_size | REAL | 一次传输的通信数据包大小,单位MB | -| count | INTEGER | 通信传输次数 | -| total_duration | REAL | 通信传输总耗时,单位ms | - -### communication_matrix_sum - -设置-m communication_matrix_sum时,会生成以下表。 - -#### ClusterCommunicationMatrix - -说明: - -基于db格式的集群性能数据,生成通信矩阵数据。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| step | TEXT | 算子所属的step | -| hccl_op_name | TEXT | 矩阵分析后的精简算子名,例如:send-top1 | -| group_name | TEXT | 通信域hashId,例如3915571125887837303 | -| src_rank | REAL | 发送数据的rankId,例如:0| -| dst_rank | REAL | 接收数据的rankId,例如:1| -| transport_type | TEXT | 传输类型,包含:LOCAL、SDMA、RDMA等 | -| op_name | TEXT | 算子的原始名字 | -| transit_size | REAL | 传输的数据量,单位MB | -| transit_time | REAL | 传输耗时,单位ms | -| bandwidth | REAL | 带宽,单位GB/s | - -### mstx_sum - -设置-m mstx_sum时,会生成以下表。 - -#### MSTXAllFrameworkStats - -说明: - -基于db格式的集群性能数据,分析mstx打点数据的框架侧耗时(不区分rank)。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| Name | TEXT | mstx打点数据携带信息 | -| Count | INTEGER | 该迭代内以Name为分组的打点的次数 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| StepId | INTEGER | 迭代id | - -#### MSTXAllCannStats - -说明: - -基于db格式的集群性能数据,分析mstx打点数据的cann层耗时(不区分rank)。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| Name | TEXT | mstx打点数据携带信息 | -| Count | INTEGER | 该迭代内以Name为分组的打点的次数 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| StepId | INTEGER | 迭代id | - -#### MSTXAllDeviceStats - -说明: - -基于db格式的集群性能数据,分析mstx打点数据的device侧耗时(不区分rank)。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| Name | TEXT | mstx打点数据携带信息 | -| Count | INTEGER | 该迭代内以Name为分组的打点的次数 | -| MeanNs | REAL | 耗时的平均值,单位ns | -| StdNs | REAL | 耗时的标准差,单位ns | -| MinNs | REAL | 耗时的最小值,单位ns | -| Q1Ns | REAL | 耗时的25%分位数,单位ns | -| MedianNs | REAL | 耗时的50%分位数,单位ns | -| Q3Ns | REAL | 耗时的75%分位数,单位ns | -| MaxNs | REAL | 耗时的最大值,单位ns | -| SumNs | REAL | 耗时的总和,单位ns | -| StepId | INTEGER | 迭代id | - -#### MSTXMarkStats - -说明: - -基于db格式的集群性能数据,针对每个rank的打点数据,以Rank,StepId分组,对mstx打点的耗时进行统计分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| Name | TEXT | mstx打点数据携带信息 | -| FrameworkDurationNs | REAL | 框架侧耗时,单位ns | -| CannDurationNs | REAL | CANN层耗时,单位ns | -| DeviceDurationNs | REAL | device侧耗时,单位ns | -| Rank | INTEGER | global rank | -| StepId | INTEGER | 迭代id | - -### freq_analysis - -说明: - -基于db格式的集群性能数据,分析aicore frequency,提供npu降频一键检测能力。频率分为三种情况: -* 正常情况下,应当稳定在1800MHz; -* 当npu空闲时间较长时,设备会自动降频,会掉到800MHz; -* 当npu因为各种原因,出现降频现象时,除了1800MHz,800MHz,还有出现其他异常频率。 - -设置-m freq_analysis时,如果发生降频,会生成以下表。 - -#### FreeFrequencyRanks - -说明: - -对应第二种情况。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| rankId | INTEGER | global rank | -| aicoreFrequency | TEXT | [800, 1800] | - -#### AbnormalFrequencyRanks - -说明: - -对应第三种情况。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| rankId | INTEGER | global rank | -| aicoreFrequency | TEXT | 异常频率列表;例如:[800, 1150, 1450, 1800] | - -### ep_load_balance - -说明: - -集群训练场景下,MOE负载不均指的是,在分布式环境下,不同的专家模型处理的任务量不均衡,导致某些专家过载(处理过多任务),而其他专家闲置。这种负载不均会降低系统的整体效率,甚至可能导致性能瓶颈。 - -设置-m ep_load_balance时,会生成以下表。 - -#### EPTokensSummary - -说明: - -基于db格式的集群性能数据,分析GroupedMatmul算子的shape信息。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| rank | INTEGER | global rank | -| epRanks | TEXT | 同一个ep(Expert Parallelism)的rank集合,例如0,1 | -| inputShapesSummary | INTEGER | 该rank的GroupedMatmul算子的inputshapes的第一个维度的总和 | - -#### TopEPTokensInfo - -说明: - -负载不均的ep。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| epRanks | TEXT | 负载不均的ep(Expert Parallelism)的rank集合,例如0,1 | -| tokensDiff | INTEGER | 同一个ep内最大值与最小值之间的差值 | - -### slow_rank - -设置-m slow_rank时,会生成以下表。 - -#### SlowRank - -说明: - -基于db格式的集群性能数据,进行慢卡分析。 - -格式: - -| 字段名 | 类型 | 含义 | -| ------ | ---- | ---- | -| rankId | INTEGER | 慢卡 | -| slowAffectCount | INTEGER | 该rank影响了多少次通信 | - -### mstx2commop - -设置-m mstx2commop时,会生成以下表。 - -#### COMMUNICATION_OP - -说明: - -基于db格式的集群通信算子数据。 - -格式: - -| 字段名 | 类型 | 含义 | -|--------------|---------|----------------------------------------------------------------------------| -| opName | INTEGER | 算子名,STRING_IDS(opName),例:hcom_allReduce__428_0_1 | -| startNs | INTEGER | 通信大算子的开始时间,单位ns | -| endNs | INTEGER | 通信大算子的结束时间,单位ns | -| connectionId | INTEGER | 生成host-device连线 | -| groupName | INTEGER | 通信域,STRING_IDS(groupName),例:10.170.22.98%enp67s0f5_60000_0_1708156014257149 | -| opId | INTEGER | 索引,通信大算子Id,用于关联COMMUNICATION_TASK_INFO表 | -| relay | INTEGER | 借轨通信标识 | -| retry | INTEGER | 重传标识 | -| dataType | INTEGER | 大算子传输的数据类型,如(INT8,FP32),ENUM_HCCL_DATA_TYPE(dataType) | -| algType | INTEGER | 通信算子使用的算法,可分为多个阶段,STRING_IDS(algType),如(HD-MESH) | -| count | NUMERIC | 算子传输的dataType类型的数据量 | -| opType | INTEGER | 算子类型,STRING_IDS(opType),例:hcom_broadcast_ | - -#### STRING_IDS - -说明: - -字符串映射表,COMMUNICATION_OP表opName字段可通过关联STRING_IDS表得到value。 - -格式: - -| 字段名 | 类型 | 含义 | -|-------|---------|--------------| -| id | INTEGER | 索引,string id | -| value | TEXT | string value | - -## 附录 - -### 自定义分析规则开发指导 - -自定义分析规则是基于对Profiling的analysis.db和ascend_pytorch_profiler_{rank_id}.db文件进行性能数据分析而开发。与cann_api_sum、compute_op_sum、hccl_sum等参数功能实现类似,可自定义一套性能数据的分析规则,方法如下: - -1. 在mstt工具代码仓profiler/msprof_analyze/cluster_analyse/recipes目录下创建xxx目录和xxx.py文件。 - - 例如:profiler/msprof_analyze/cluster_analyse/recipes/cann_api_sum/cann_api_sum.py,其中目录名和文件名要保持一致,该目录名也会作为使用msprof-analyze cluster工具启动该自定义分析的开关参数。 - -2. 在xxx.py文件进行性能数据分析规则的开发,开发要求继承BaseRecipeAnalysis,实现run函数。 - - 典型的run函数实现: - - ```python - def run(self, context): - mapper_res = self.mapper_func(context) - self.reducer_func(mapper_res) - if self._export_type == "db": - self.save_db() - elif self._export_type == "notebook": - self.save_notebook() - else: - logger.error("Unknown export type.") - ``` - - 1. `mapper_func`函数:多卡数据查询并合并返回结果。由于集群数据每张卡的数据处理是同样的,因此采用context并行处理集群数据并将结果按序拼装返回。开发只需要实现单卡数据处理的函数`self._mapper_fun`。 - - ```python - def mapper_func(self, context): - return context.wait( - context.map( - self._mapper_func, - self._get_rank_db(), - analysis_class=self._recipe_name - ) - ) - ``` - - ```python - def _mapper_func(self, data_map, analysis_class): - """ - Extract the profiling data required for cluster analysis from each device, and then aggregate the - results from each device to be processed by a reduce function. - Params: - data_map: eg. {"RANK_ID": 1, "profiler_db_path": "xxxx/ascend_pytorch_profiler_1.db"} - analysis_class: hccl_sum, compute_op_sum, cann_api_sum, mstx_sum...... - """ - pass - ``` - - 2. `reducer_func`函数:对多卡结果分析处理。接收`mapper_func`函数的返回值,进行进一步的集群数据的汇总分析,数据结构采用dataframe。 - - 3. `save_db`函数:分析结果保存在cluster_analysis.db中。 - - 4. `save_notebook`函数:分析结果以csv和stats.ipynb的形式保存。 - -3. `self._mapper_fun`函数依赖单db数据查询,可通过可通过如下两种方式。 - - 1. 使用DatabaseService可配置单表的查询。 - - 可参考:https://gitee.com/ascend/mstt/blob/pre-research/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py - - 使用样例: - - ```Python - service = DatabaseService(profiler_db_path) - service.add_table_for_query("ENUM_HCCL_DATA_TYPE", ["id", "name"]) # 第一个参数:表名;第二个参数:字段列表,默认为None,当不填写时表明select * - service.add_table_for_query("STRING_IDS", ["id", "value"]) #可以添加多个表 - df_dict = service.query_data() # 将配置的所有表按序查询,以dict形式返回,key为表名,value为数据库查询结果dataframe数据类型 - ``` - - 2. 维护在msprof_analyze/prof_exports目录下,新建一个py文件,需继承自BaseStatsExport(注:新增之前可以看现有的是否可用,避免重复)如下示例(以hccl_sum_export.py文件为例): - - ```Python - from msprof_analyze.prof_exports.base_stats_export import BaseStatsExport - - QUERY = """ - SELECT - NAME_IDS.value AS "OpName", - TYPE_IDS.value AS "OpType", - round(endNs - startNs) AS "Duration", - GROUP_NAME_IDS.value AS "GroupName" - FROM - COMMUNICATION_OP - LEFT JOIN - STRING_IDS AS TYPE_IDS - ON TYPE_IDS.id == COMMUNICATION_OP.opType - LEFT JOIN - STRING_IDS AS NAME_IDS - ON NAME_IDS.id == COMMUNICATION_OP.opName - LEFT JOIN - STRING_IDS AS GROUP_NAME_IDS - ON GROUP_NAME_IDS.id == COMMUNICATION_OP.groupName - """ - - - class HcclSumExport(BaseStatsExport): - def __init__(self, db_path, recipe_name): - super().__init__(db_path, recipe_name) - self._query = QUERY - ``` - - 使用样例:df = HcclSumExport(profiler_db_path, analysis_class).read_export_db(),返回的数据类型是dataframe。 - -4. 分析规则增加拓展参数。 - - 实现函数add_parser_argument,样例如下: - - ```Python - @classmethod - def add_parser_argument(cls, parser): - parser.add_argument("--top_num", type=str, help="Duration cost top count", default=cls.DEFAULT_TOP_NUM) - ``` - - 从self._extra_args里获取对应的扩展参数: - - ```Python - def __init__(self, params): - super().__init__(params) - top_num = self._extra_args.get(self.TOP_NUM, self.DEFAULT_TOP_NUM) - self.top_num = int(top_num) if isinstance(top_num, str) and top_num.isdigit() else self.DEFAULT_TOP_NUM - ``` - -5. 执行自定义分析规则命令。 - - ```bash - msprof-analyze cluster -d {cluster profiling data path} --mode xxx --top_num 10 - ``` - -### 开发和上库流程规范 - -开发要遵守以下流程规范。 - -1. **需求澄清和串讲** - - 确定要做该需求后,首先要明确该需求的**迭代时间**,开发流程需要严格遵守我们的迭代时间,参加该需求的需求澄清以及串讲(我们会安排相应会议)。需求澄清可由DE完成(对齐输入输入以及流程图),需求串讲需要开发者来完成,串讲时需要准备**设计文档和测试用例**(有文档模版,可以跟SE或者DE联系拿到)。 - -2. **UT** - - 为了保证后面的开发者修改你的代码时不会影响你的功能,或者能够感知这次修改的影响,比如算法实现、字段变更等,需要在上库的同时添加UT。 - UT的编写可以参考已经上库的其他用例,建议四段式命名:test_{目标方法名}_should_{预期结果}_when_{分支条件}_given_{输入参数},可以灵活使用mock方式构造虚拟返回。 - -3. **资料编写** - - 目前,如果新增一个分析能力,需要在[操作步骤](#操作步骤)的第2小节的“--mode参数说明”中添加对应参数的说明,简洁说明该分析能力的作用以及输入输出。 - 另外,需要在[cluster_analysis.db交付件表结构说明](#cluster_analysisdb交付件表结构说明)中添加表结构说明,明确输入输出。可以详细说明你的分析能力的**主要场景、用途甚至是算法原理**,保证用户知道这个分析能力的能做什么,对调优有什么帮助。(参考[freq_analysis](#freq_analysis)的说明) - -4. **CI** - - 正常商发需求合入master分支;预研需求合入pre-research分支;poc需求合入poc分支。 - 提了PR之后,可以评论**compile**,触发线上CI,会跑cleancode和冒烟,只有全绿,才可以发起代码检视。PR合入需要lgtm标签和approve标签(群里有相应的committer可以加标签)。 - -5. **代码检视** - - 代码上库,需要经过检视,可以将链接发到**msprof-analyze代码检视群**,说明该PR的标题,然后@相关人进行检视。修改完检视意见后再次@commiter,合代码。 - 为了让结果可信以及方便其他开发或者测试使用这个分析能力,需要编写测试用例并提供**自验报告**作为凭证。 - - +# msprof-analzye集群分析能力 +本能力已经整合到msprof-analzye性能分析工具中.详细介绍请参照[msprof-analzye](../README.md)说明文档使用. \ No newline at end of file diff --git a/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py index 18c084b16aa225aca5b2c5503e175943d5ab4a05..1a82ec9e8d7506d2514925e501e0374e21e8caaf 100644 --- a/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py +++ b/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py @@ -202,4 +202,3 @@ class Mstx2Commop(BaseRecipeAnalysis): PathManager.make_dir_safety(new_path) shutil.copyfile(profiler_db_path, new_db_path) return new_db_path - diff --git a/profiler/msprof_analyze/docs/cluster_time_compare_summary.md b/profiler/msprof_analyze/docs/cluster_time_compare_summary.md new file mode 100644 index 0000000000000000000000000000000000000000..48abb91217f951ccdcf121a8744256525990622f --- /dev/null +++ b/profiler/msprof_analyze/docs/cluster_time_compare_summary.md @@ -0,0 +1,44 @@ +# cluster_time_compare_sumary 集群性能数据细粒度比对 + + +## 背景与挑战 +大集群场景涉及多个计算节点,数据量大,原有的单卡性能数据对比不能评估整体集群运行情况。 + +## 功能介绍 + + cluster_time_compare_sumary 提供了AI运行过程中集群维度的性能数据对比能力,包括计算、通信和内存拷贝等各部分的时间消耗,帮助用户找到性能瓶颈。 + +## 使用方法 + +```bash +# 首先执行cluster_time_summary分析能力,执行集群耗时细粒度拆解 +msprof-analyze -m cluster_time_summary -d ./cluster_data +msprof-analyze -m cluster_time_summary -d ./base_cluster_data + +# 执行cluster_time_compare_summary,传入两个拆解分析后的文件夹路径 +msprof-analyze -m cluster_time_compare_summary -d ./cluster_data --bp ./base_cluster_data +``` +**参数说明:** +* `-m`cluster_time_compare_summary 使能集群耗时细粒度对比能力 +* `-d`集群性能数据文件夹路径 +* `-bp`标杆集群数据路径 +* 其余参数:与msprof-analzye参数一致 + +**输出数据:** +* 存储位置:cluster_analysis_output/cluster_analysis.db +* 数据表名:ClusterTimeCompareSummary + +**字段说明:** + +| 字段名称 | 类型 | 说明 | +|------------|----------|----------------------------------| +| rank | INTEGER | 卡号 | +| step | INTEGER | 迭代编号 | +| {metrics} | REAL | 当前集群耗时指标,与ClusterTimeSummary字段一致 | +| {metrics}Base | REAL | 基准集群的对应耗时 | +| {metrics}Diff | REAL | 耗时偏差值(当前集群-基准集群),正值表示当前集群更慢 | + +备注:表中时间相关字段,统一使用微秒(us) + +**输出结果分析:** +* 按*Diff字段排序找出最大差异项,找到劣化环节。 \ No newline at end of file diff --git a/profiler/msprof_analyze/docs/cluster_time_summary.md b/profiler/msprof_analyze/docs/cluster_time_summary.md index fa1be67080afbadd13fdedb3a81a51aee892946e..f3ed99868a98250c157d5075011a5e8966980e7d 100644 --- a/profiler/msprof_analyze/docs/cluster_time_summary.md +++ b/profiler/msprof_analyze/docs/cluster_time_summary.md @@ -1,23 +1,25 @@ -# 集群耗时细粒度分析与比对指南 +# cluster_time_summary 集群性能数据细粒度拆解 + +## 背景与挑战 +1、 大集群场景涉及多个计算节点,数据量大,单卡维度的性能数据统计与分析不能评估整体集群运行情况。 +2、 原有的cluster_step_trace_time。csv交付件没有单独的执行命令,导致用户使用不直观,且不能涵盖内存拷贝等指标项,需要增强。 + +## 功能介绍 -## 简介 -本指南介绍两种集群性能分析功能: * cluster_time_summary 提供了集群训练过程中迭代耗时拆解,包括计算、通信和内存拷贝等各部分的时间消耗,帮助用户找到性能瓶颈。 -* cluster_time_compare_summary 支持两个集群间的性能数据比对,辅助定界性能劣化原因。 -## 操作指导 -### cluster_time_sumary 集群耗时细粒度拆解 +**使用方法** -**命令行使能:** ``` -msprof-analyze cluster -m cluster_time_summary -d ./cluster_data +msprof-analyze -m cluster_time_summary -d ./cluster_data ``` **参数说明:** -* `-d`集群数据路径:需要使用Ascend Pytorch Profiler采集AI任务,导出类型包含DB,并使用`torch_npu.profiler.profile.step()`接口划分迭代。 -* 其余参数:与cluster集群分析功能支持的参数一致,详见[参数列表](../cluster_analyse/README.md) +* `-m`设置为cluster_time_summary 使能集群耗时细粒度拆解能力 +* `-d`集群性能数据文件夹路径 +* 其余参数:与msprof-analzye参数一致 **输出数据:** -* 存储位置:cluster_analysis_output/cluster_analysis.db +* 存储位置:cluster_analysis_output/cluster_analysis。db * 数据表名:ClusterTimeSummary ![输出结果展示](img/clutser_time_summary.png) @@ -43,35 +45,4 @@ msprof-analyze cluster -m cluster_time_summary -d ./cluster_data **输出结果分析:** * 通过分析计算、通信、内存拷贝、空闲时间占比,找到性能瓶颈。 * 通过比较集群内各卡耗时指标差异,定界性能问题。例如,computing计算耗时波动显著,通常表明存在卡间不同步、计算卡性能不均的情况,而通信传输耗时差异过大时,则需优先排查参数面网络是否存在拥塞或配置异常。 -* 配合使用cluster_time_compare_summary功能,可有效定位集群性能劣化根因。 - - -### cluster_time_compare_sumary 集群比对 - -**通过以下命令行使能:** -``` -msprof-analyze cluster -m cluster_time_compare_summary -d ./cluster_data --bp ./base_cluster_data -``` -**参数说明:** -* `-d`集群数据路径:需要先执行cluster_time_summary分析,要求该路径下存在集群数据与cluster_analysis_output/cluster_analysis.db,包含ClusetrTimeSummary表。 -* `-bp`标杆集群数据路径:需要先执行cluster_time_summary分析,要求该路径下存在cluster_analysis_output/cluster_analysis.db,包含ClusetrTimeSummary表。 -* 其余参数:与cluster集群分析功能支持的参数一致,详见[参数列表](../cluster_analyse/README.md) - -**输出数据:** -* 存储位置:cluster_analysis_output/cluster_analysis.db -* 数据表名:ClusterTimeCompareSummary - -**字段说明:** - -| 字段名称 | 类型 | 说明 | -|------------|----------|----------------------------------| -| rank | INTEGER | 卡号 | -| step | INTEGER | 迭代编号 | -| {metrics} | REAL | 当前集群耗时指标,与ClusterTimeSummary字段一致 | -| {metrics}Base | REAL | 基准集群的对应耗时 | -| {metrics}Diff | REAL | 耗时偏差值(当前集群-基准集群),正值表示当前集群更慢 | - -备注:表中时间相关字段,统一使用微秒(us) - -**输出结果分析:** -* 按*Diff字段排序找出最大差异项,找到劣化环节。 \ No newline at end of file +* 配合使用cluster_time_compare_summary功能,可有效定位集群性能劣化根因。 \ No newline at end of file diff --git a/profiler/msprof_analyze/docs/custom_analysis_guide.md b/profiler/msprof_analyze/docs/custom_analysis_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..893892441144caeb5a608be16f686a8d2d2760d1 --- /dev/null +++ b/profiler/msprof_analyze/docs/custom_analysis_guide.md @@ -0,0 +1,155 @@ +# 自定义分析规则开发指导 +自定义分析规则是基于对Profiling的analysis.db和ascend_pytorch_profiler_{rank_id}.db文件进行性能数据分析而开发。与cann_api_sum、compute_op_sum、hccl_sum等参数功能实现类似,可自定义一套性能数据的分析规则,方法如下: + +1. 在mstt工具代码仓profiler/msprof_analyze/cluster_analyse/recipes目录下创建xxx目录和xxx.py文件。 + + 例如:profiler/msprof_analyze/cluster_analyse/recipes/cann_api_sum/cann_api_sum.py,其中目录名和文件名要保持一致,该目录名也会作为使用msprof-analyze cluster工具启动该自定义分析的开关参数。 + +2. 在xxx.py文件进行性能数据分析规则的开发,开发要求继承BaseRecipeAnalysis,实现run函数。 + + 典型的run函数实现: + + ```python + def run(self, context): + mapper_res = self.mapper_func(context) + self.reducer_func(mapper_res) + if self._export_type == "db": + self.save_db() + elif self._export_type == "notebook": + self.save_notebook() + else: + logger.error("Unknown export type.") + ``` + + 1. `mapper_func`函数:多卡数据查询并合并返回结果。由于集群数据每张卡的数据处理是同样的,因此采用context并行处理集群数据并将结果按序拼装返回。开发只需要实现单卡数据处理的函数`self._mapper_fun`。 + + ```python + def mapper_func(self, context): + return context.wait( + context.map( + self._mapper_func, + self._get_rank_db(), + analysis_class=self._recipe_name + ) + ) + ``` + + ```python + def _mapper_func(self, data_map, analysis_class): + """ + Extract the profiling data required for cluster analysis from each device, and then aggregate the + results from each device to be processed by a reduce function. + Params: + data_map: eg. {"RANK_ID": 1, "profiler_db_path": "xxxx/ascend_pytorch_profiler_1.db"} + analysis_class: hccl_sum, compute_op_sum, cann_api_sum, mstx_sum...... + """ + pass + ``` + + 2. `reducer_func`函数:对多卡结果分析处理。接收`mapper_func`函数的返回值,进行进一步的集群数据的汇总分析,数据结构采用dataframe。 + + 3. `save_db`函数:分析结果保存在cluster_analysis.db中。 + + 4. `save_notebook`函数:分析结果以csv和stats.ipynb的形式保存。 + +3. `self._mapper_fun`函数依赖单db数据查询,可通过可通过如下两种方式。 + + 1. 使用DatabaseService可配置单表的查询。 + + 可参考:https://gitee.com/ascend/mstt/blob/pre-research/profiler/msprof_analyze/cluster_analyse/recipes/mstx2commop/mstx2commop.py + + 使用样例: + + ```Python + service = DatabaseService(profiler_db_path) + service.add_table_for_query("ENUM_HCCL_DATA_TYPE", ["id", "name"]) # 第一个参数:表名;第二个参数:字段列表,默认为None,当不填写时表明select * + service.add_table_for_query("STRING_IDS", ["id", "value"]) #可 以添加多个表 + df_dict = service.query_data() # 将配置的所有表按序查询,以dict形式返回,key为表名,value为数据库查询结果dataframe数据类型 + ``` + + 2. 维护在msprof_analyze/prof_exports目录下,新建一个py文件,需继承自BaseStatsExport(注:新增之前可以看现有的是否可用,避免重复)如下示例: + + ```Python + from msprof_analyze.prof_exports.base_stats_export import BaseStatsExport + + QUERY = """ + SELECT + NAME_IDS.value AS "OpName", + TYPE_IDS.value AS "OpType", + round(endNs - startNs) AS "Duration", + GROUP_NAME_IDS.value AS "GroupName" + FROM + COMMUNICATION_OP + LEFT JOIN + STRING_IDS AS TYPE_IDS + ON TYPE_IDS.id == COMMUNICATION_OP.opType + LEFT JOIN + STRING_IDS AS NAME_IDS + ON NAME_IDS.id == COMMUNICATION_OP.opName + LEFT JOIN + STRING_IDS AS GROUP_NAME_IDS + ON GROUP_NAME_IDS.id == COMMUNICATION_OP.groupName + """ + + + class HcclSumExport(BaseStatsExport): + def __init__(self, db_path, recipe_name): + super().__init__(db_path, recipe_name) + self._query = QUERY + ``` + + 使用样例:df = HcclSumExport(profiler_db_path, analysis_class).read_export_db(),返回的数据类型是dataframe。 + +4. 分析规则增加拓展参数。 + + 实现函数add_parser_argument,样例如下: + + ```Python + @classmethod + def add_parser_argument(cls, parser): + parser.add_argument("--top_num", type=str, help="Duration cost top count", default=cls.DEFAULT_TOP_NUM) + ``` + + 从self._extra_args里获取对应的扩展参数: + + ```Python + def __init__(self, params): + super().__init__(params) + top_num = self._extra_args.get(self.TOP_NUM, self.DEFAULT_TOP_NUM) + self.top_num = int(top_num) if isinstance(top_num, str) and top_num.isdigit() else self.DEFAULT_TOP_NUM + ``` + +5. 执行自定义分析规则命令。 + + ```bash + msprof-analyze cluster -d {cluster profiling data path} --mode xxx --top_num 10 + ``` + +## 开发和上库流程规范 + +开发要遵守以下流程规范。 + +1. **需求澄清和串讲** + + 确定要做该需求后,首先要明确该需求的**迭代时间**,开发流程需要严格遵守我们的迭代时间,参加该需求的需求澄清以及串讲(我们会安排相应会议)。需求澄清可由DE完成(对齐输入输入以及流程图),需求串讲需要开发者来完成,串讲时需要准备**设计文档和测试用例**(有文档模版,可以跟SE或者DE联系拿到)。 + +2. **UT** + + 为了保证后面的开发者修改你的代码时不会影响你的功能,或者能够感知这次修改的影响,比如算法实现、字段变更等,需要在上库的同时添加UT。 + UT的编写可以参考已经上库的其他用例,建议四段式命名:test_{目标方法名}_should_{预期结果}_when_{分支条件}_given_{输入参数},可以灵活使用mock方式构造虚拟返回。 + +3. **资料编写** + + 目前,如果新增一个分析能力,需要在[操作步骤](#操作步骤)的第2小节的“--mode参数说明”中添加对应参数的说明,简洁说明该分析能力的作用以及输入输出。 + 另外,需要在[recipe结果和cluster_analysis.db交付件表结构说明](#recipe结果和cluster_analysisdb交付件表结构说明)中添加表结构说明,明确输入输出。可以详细说明你的分析能力的**主要场景、用途甚至是算法原理**,保证用户知道这个分析能力的能做什么,对调优有什么帮助。(参考[freq_analysis](#freq_analysis)的说明) + +4. **CI** + + 正常商发需求合入master分支;预研需求合入pre-research分支;poc需求合入poc分支。 + 提了PR之后,可以评论**compile**,触发线上CI,会跑cleancode和冒烟,只有全绿,才可以发起代码检视。PR合入需要lgtm标签和approve标签(群里有相应的committer可以加标签)。 + +5. **代码检视** + + 代码上库,需要经过检视,可以将链接发到**msprof-analyze代码检视群**,说明该PR的标题,然后@相关人进行检视。修改完检视意见后再次@commiter,合代码。 + 为了让结果可信以及方便其他开发或者测试使用这个分析能力,需要编写测试用例并提供**自验报告**作为凭证。 + 注:cluster_analysis.db里面的表格,统一遵守表名大驼峰,列名小驼峰的命名规则。 \ No newline at end of file diff --git a/profiler/msprof_analyze/prof_exports/mstx2commop_export.py b/profiler/msprof_analyze/prof_exports/mstx2commop_export.py index f6a4a525a22320f64c047ef8bdf9ee2e8cc61d18..53648f46751c1220e1b0879aa6abc8c14991d67b 100644 --- a/profiler/msprof_analyze/prof_exports/mstx2commop_export.py +++ b/profiler/msprof_analyze/prof_exports/mstx2commop_export.py @@ -44,4 +44,4 @@ class Mstx2CommopExport(BaseStatsExport): def __init__(self, db_path, recipe_name, step_range): super().__init__(db_path, recipe_name, step_range) filter_stat = "AND ms.startNs >= ? and ms.startNs <= ?" if step_range else "" - self._query = QUERY.format(filter_stat) + self._query = QUERY.format(filter_stat) \ No newline at end of file