From 76da6076a8d0272106f77755457ddcc9bc5548d3 Mon Sep 17 00:00:00 2001 From: cai-weiwei1989 <734267852@qq.com> Date: Tue, 12 Aug 2025 15:52:10 +0800 Subject: [PATCH] =?UTF-8?q?[profiler]=E6=80=BB=E4=BD=93=E4=BB=8B=E7=BB=8D?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=A8=A1=E6=9D=BF=E6=95=B4=E6=94=B9=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E4=BD=8E=E9=94=99=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/mindstudio-vscode-plugins/ReadMe.md | 4 +- .../tensorboard-plugins/tb_plugin/README.md | 36 +-- profiler/affinity_cpu_bind/README.md | 2 +- profiler/example/mstx_torch_plugin/README.md | 2 +- profiler/msprof_analyze/README.md | 272 +++++++++--------- .../cluster_kernels_analysis/README.md | 4 +- profiler/msprof_analyze/docs/img/1.png | Bin 0 -> 9891 bytes 7 files changed, 163 insertions(+), 157 deletions(-) create mode 100644 profiler/msprof_analyze/docs/img/1.png diff --git a/plugins/mindstudio-vscode-plugins/ReadMe.md b/plugins/mindstudio-vscode-plugins/ReadMe.md index 37e928d9d9..bca5f2afce 100644 --- a/plugins/mindstudio-vscode-plugins/ReadMe.md +++ b/plugins/mindstudio-vscode-plugins/ReadMe.md @@ -30,7 +30,7 @@ MindStudio Operator Debug VSCode Plugin插件[源码仓](https://gitee.com/ascen 2. IDE界面远程SSH登录算子开发环境,打开已编译的算子工程文件 3. 安装[Hex Editor](https://marketplace.visualstudio.com/items?itemName=ms-vscode.hexeditor)插件和[MindStudio Operator Debug VSCode Plugin](https://ascend-package.obs.cn-north-4.myhuaweicloud.com:443/mindstudio-operator-tools/MindStudio-Operator-Debug-VSCode-Plugin-0.0.1.vsix)插件 -* IDE界面插件市场界面离线本地安装 +* IDE界面插件市场离线本地安装 ``` - 插件.vsix文件上传linux环境 - 展开IDE界面左侧边栏的插件菜单 @@ -79,7 +79,7 @@ MindStudio Operator Debug VSCode Plugin插件[源码仓](https://gitee.com/ascen * `environment` 包含自定义环境变量的对象数组,在加载完`environmentScripts`脚本中的环境变量后依次加载`environment`中的环境变量,格式需满足:`[{"name": "xxx", "value":"yyy"}]` #### 断点调试(设置/删除/禁用/启用断点) -* 可以在算子程序行号显示处设置、删除、禁用、用断点,也可以在debug侧边工具栏中的底部断点工具栏执行相同操作。 +* 可以在算子程序行号显示处设置、删除、禁用、启用断点,也可以在debug侧边工具栏中的底部断点工具栏执行相同操作。 #### 单步执行调试(逐行执行/内部执行/跳出函数)/继续/暂停/重启 * 可以单击顶部调试工具栏上的图标控制程序,包括单步执行、步入、步出、继续、暂停、重启或停止程序的操作。 diff --git a/plugins/tensorboard-plugins/tb_plugin/README.md b/plugins/tensorboard-plugins/tb_plugin/README.md index f3a629c197..8469da86aa 100644 --- a/plugins/tensorboard-plugins/tb_plugin/README.md +++ b/plugins/tensorboard-plugins/tb_plugin/README.md @@ -5,7 +5,7 @@ ### 介绍 此工具是PyTorch profiling数据以及可视化的TensorBoard的插件。 \ -它支持将Ascend平台采集、解析的Pytorch Profiling数据可视化呈现,也兼容GPU数据采集、解析可视化,支持PyTorch 2.0GPU版本的profiling数据可视化。同时集成了精度比对的功能,支持查看loss曲线和比对两个网络的loss收敛趋势。 +它支持将Ascend平台采集、解析的PyTorch Profiling数据可视化呈现,也兼容GPU数据采集、解析可视化,支持PyTorch 2.0GPU版本的profiling数据可视化。同时集成了精度比对的功能,支持查看loss曲线和比对两个网络的loss收敛趋势。 ### 快速安装说明 * 相关依赖: @@ -39,7 +39,7 @@ `------operator_memory.csv` ### 启动方式 - + 1. 启动TensorBoard `tensorboard --logdir=./samples` @@ -77,12 +77,12 @@ ##### Operator View - Operator View展示的是运行在host侧和device侧的Pytorch算子、计算算子的详细信息。 + Operator View展示的是运行在host侧和device侧的PyTorch算子、计算算子的详细信息。 ![Alt text](./docs/images/operator_view.PNG) Calls: 表示的是运行过程中此算子被调用的次数。 - + Input Shapes: shapes信息。 Device Self Duration: 算子在device侧的耗时(除去子算子)。 @@ -168,7 +168,7 @@ ##### Memory View - 展示的是Pytorch Profiler执行过程中内存申请和释放的信息。 + 展示的是PyTorch Profiler执行过程中内存申请和释放的信息。 主要包括两张折线图和两张表。可以在 'Device' 下拉框下选择要展示的NPU卡的内存使用信息。Group By可以切换总的内存使用和各个组件内存使用图表。 * Operator @@ -205,7 +205,7 @@ Diff视图提供了Profiling数据比对功能。适用于同一网络不同迭代之间采集数据比对算子耗时情况,网络进行优化前后相同位置算子耗时情况比对、单机多卡不同卡之间采集数据比对以及相同网络不同硬件平台上运行性能情况比对等场景。 ![Alt text](./docs/images/diff_view.png) - + * 最上方为整体比对,以采集的step为周期比较两份数据各类算子的耗时情况以及累计耗时变化趋势。点击其中某块柱形,可以单点查看对应详情。 ![Alt text](./docs/images/diff_detail.png) @@ -222,7 +222,7 @@ Distributed视图展示的是多卡采集数据情况,包括每张卡的计算、通信信息以及通信算子的详细信息,界面由两张柱状图和一个通信算子信息表构成,如下图。 ![Alt text](./docs/images/distributed_view.PNG) - + * 左侧柱状图呈现了每张卡计算和通信等项的耗时,各项定义如下: | 字段 | 含义 | @@ -231,9 +231,9 @@ | Communication | 通信时间:总通讯时间减去和计算重叠的时间。| | Overlapp | 重叠时间:计算和通信重叠的时间。此项占比越大代表计算和通信的并行性越好,理想情况下计算和通信完全重叠。| | Other | 除去计算和通信的其他部分耗时,包括初始化、数据加载等。| - + * 右侧柱状图将通信时间分为数据传输时间和同步时间进行统计,定义如下: - + | 字段 | 含义 | |------|------| | Data Transfer Time | 通信时间中实际的数据传输时间。 | @@ -273,8 +273,8 @@ ![Alt text](./docs/images/accuracy_file_operator.PNG) * 点击配置数据匹配条件图标后,出现匹配条件配置弹框,需要设置Loss Tag和Iteration Tag两个配置项,弹框内每个Tag都包含一个输入框。 - ![Alt text](./docs/images/accuracy_config_modal.PNG) - 根据2个Tag的取值有如下3点匹配规则: + ![Alt text](./docs/images/accuracy_config_modal.PNG) + 根据2个Tag的取值有如下3点匹配规则: 1. 匹配数据时将逐行读取文件,查找是否存在输入框内设定的文本,若找到该文本,若为Loss Tag则查找其后是否存在数字或以科学计数法表示的数字(忽略两者中间空格),若为Iteration Tag则查找其后是否存在整数(忽略两者中间空格)。 2. 若存在多个匹配项,将第一项作为匹配值。 3. 只有当Loss Tag和Iteration都存在匹配值时,该行的Iteration和Loss才会为有效数据。 @@ -291,27 +291,27 @@ 因此上方这张图中最终提取出的有效数据为区域1和区域2内的同一行数字的集合。 * 点击导出CSV图标后,将导出找到的Iteration和Loss数据为csv文件。 \ - ![Alt text](./docs/images/accuracy_csv.PNG) + ![Alt text](./docs/images/accuracy_csv.PNG) * 点击删除图标后,界面弹出确认删除框,确认后可移除该文件。 - ![Alt text](./docs/images/accuracy_delete.PNG) + ![Alt text](./docs/images/accuracy_delete.PNG) ##### Loss数据看板 已上传文件后,可在左侧侧边栏勾选该文件,右侧则会展示该文件的Loss数据看板,包含loss折线图和明细表格。 - + * 勾选单个文件时,Loss数据看板将会占满整个右侧展示界面。 - ![Alt text](./docs/images/accuracy_single_file.PNG) + ![Alt text](./docs/images/accuracy_single_file.PNG) * 勾选两个以上文件时,右侧将会展示Loss数据看板和Loss比对看板。 - ![Alt text](./docs/images/accuracy_multiple_files.PNG) + ![Alt text](./docs/images/accuracy_multiple_files.PNG) * Loss数据看板为全量展示,折线图内展示的是所有勾选文件的所有数据,表格内展示的同样为勾选文件的全量数据,若表格内iteration为某些文件独有,则其他文件该行显示为`NA`。 ##### Loss比对看板 当勾选文件为2个以上时,将展示Loss比对看板,Loss比对看板基于iteration取两份比对数据的交集进行展示。 - + * 在Comparison objects中选择两个文件,则展示该两个文件的比对信息。 - ![Alt text](./docs/images/accuracy_loss_comparison.png) + ![Alt text](./docs/images/accuracy_loss_comparison.png) * 比对方式有三种,通过Comparison Setting进行设定。 * Comparison Normal:相同iteration,后选择文件的loss值减去先选择文件的loss值。 diff --git a/profiler/affinity_cpu_bind/README.md b/profiler/affinity_cpu_bind/README.md index bcc3c810b8..45df273e28 100644 --- a/profiler/affinity_cpu_bind/README.md +++ b/profiler/affinity_cpu_bind/README.md @@ -32,7 +32,7 @@ python3 bind_core.py -app="inference/train cmd" 该方式会自动拉起训练或推理任务,检测任务进程,并实施绑核。 - - 手动拉起训练或推理任务后再执行绑核 + - 手动拉起训练或推理任务后再执行绑核。 ```bash python3 bind_core.py ``` diff --git a/profiler/example/mstx_torch_plugin/README.md b/profiler/example/mstx_torch_plugin/README.md index f6c5b07115..59acd97234 100644 --- a/profiler/example/mstx_torch_plugin/README.md +++ b/profiler/example/mstx_torch_plugin/README.md @@ -1,6 +1,6 @@ # mstx_torch_plugin -Ascend Pytorch Profiler中的[采集并解析msprof_tx数据](https://www.hiascend.com/document/detail/zh/canncommercial/80RC3/devaids/devtools/profiling/atlasprofiling_16_0033.html#ZH-CN_TOPIC_0000002081898541__section5940122172516)功能已经内置了通信算子的打点。为了方便用户在不修改业务代码的基础上获取更多关键阶段的耗时数据,mstx_torch_plugin在Ascend Pytorch Profiler内置了**dataloader**、**forward**、**step**、**save_checkpoint**这四个关键阶段函数的打点。 +Ascend PyTorch Profiler中的[采集并解析msprof_tx数据](https://www.hiascend.com/document/detail/zh/canncommercial/80RC3/devaids/devtools/profiling/atlasprofiling_16_0033.html#ZH-CN_TOPIC_0000002081898541__section5940122172516)功能已经内置了通信算子的打点。为了方便用户在不修改业务代码的基础上获取更多关键阶段的耗时数据,mstx_torch_plugin在Ascend PyTorch Profiler内置了**dataloader**、**forward**、**step**、**save_checkpoint**这四个关键阶段函数的打点。 ## 约束 diff --git a/profiler/msprof_analyze/README.md b/profiler/msprof_analyze/README.md index f199380793..0a680e4d4b 100644 --- a/profiler/msprof_analyze/README.md +++ b/profiler/msprof_analyze/README.md @@ -1,17 +1,18 @@ -# 性能工具 +# msprof_analyze -MindStudio Training Tools工具针对训练&大模型场景,提供端到端性能调优工具msprof-analyze:用户采集到性能数据后,由MindStudio Training Tools的性能工具msprof-analyze提供统计、分析以及相关的调优建议。 +## 简介 -## NPU性能数据采集 +msprof_analyze:是mstt工具针对训练&大模型场景,提供端到端的性能调优工具。用户采集到性能数据后,由msprof_analyze提供统计、分析以及相关的调优建议。 -目前MindStudio Training Tools工具主要支持对Ascend PyTorch Profiler接口采集的性能数据进行分析,请参考官方文档:[Ascend PyTorch Profiler数据采集与分析](https://www.hiascend.com/document/detail/zh/canncommercial/80RC1/devaids/auxiliarydevtool/atlasprofiling_16_0006.html)。 +**基本概念** -### 环境和依赖 +mstt(MindStudio Training Tools,MindStudio训练工具链):是MindStudio提供的针对模型训练开发流程中的精度调试和性能调优流程的辅助工具。 -- 硬件环境请参见《[昇腾产品形态说明](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软件包。 +**工具使用流程** -以上环境依赖请根据实际环境选择适配的版本。 +![1](docs/img/1.png) + +## 版本说明 ### 版本配套说明 @@ -19,82 +20,102 @@ MindStudio Training Tools工具针对训练&大模型场景,提供端到端性 - 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() -``` +### 软件包下载 + +| 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 | + +## 快速入门 + +1. 安装msprof_analyze工具,执行如下命令。 -### 采集方式二: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() -``` + ```bash + pip install msprof-analyze + ``` -### NPU性能数据目录结构 + 提示如下信息则表示安装成功。 -ascend pytorch profiler数据目录结构如下: + ```bash + Successfully installed msprof-analyze-{version} + ``` -``` -|- ascend_pytorch_profiling - |- * _ascend_pt - |- ASCEND_PROFILER_OUTPUT - |- trace_view.json - |- FRAMEWORK - |- PROF_XXX - |- profiler_info.json - |- * _ascend_pt -``` +2. 数据准备。 + + MindSpore场景:参见“性能数据采集 > [MindSpore](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/msquickstart/atlasquick_train_0017.html)”。 + + PyTorch场景:参见“性能数据采集 > [PyTorch](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/msquickstart/atlasquick_train_0018.html)”。 + +3. 数据分析。 + + - 执行advisor分析 + + ```bash + msprof-analyze advisor all -d $HOME/profiling_data/ + ``` + + 详细分析结果介绍请参见《[advisor](advisor/README.md)》中的“[报告解析](https://gitee.com/ascend/mstt/tree/master/profiler/msprof_analyze/advisor#报告解析无标杆)”。 + + - 执行compare_tools性能比对。 + + 1. 将GPU环境下的性能数据拷贝到NPU环境。 + + 2. 执行性能比对操作。 + + ```bash + msprof-analyze compare -d $HOME/profiling_data_1/ -bp $HOME/profiling_data_2/ --output_path ./compare_result/profiler_compare + ``` + + 详细结果介绍请参见《[性能比对工具](https://gitee.com/ascend/mstt/tree/master/profiler/msprof_analyze/compare_tools)》中的“[比对结果说明](https://gitee.com/ascend/mstt/tree/master/profiler/msprof_analyze/compare_tools#比对结果说明)”。 + + - 执行cluster_analyse集群分析。 + + 1. 数据准备。 + + 将所有Device下的性能数据拷贝到同一目录下。 + + 2. 执行性能分析操作。 + + ```bash + msprof-analyze cluster -d $HOME/profiling_data/ -m all + ``` + + 分析结果在更多介绍请参见《[集群分析工具](https://gitee.com/ascend/mstt/tree/master/profiler/msprof_analyze/cluster_analyse)》。 -## 安装 + 集群分析工具的交付件通过MindStudio Insight工具展示,详细操作请参见[使用MindStudio Insight工具可视化性能数据](https://www.hiascend.com/document/detail/zh/mindstudio/81RC1/msquickstart/atlasquick_train_0021.html)。 -性能工具的安装方式包括:**pip安装**、**下载whl包安装**和**源代码编译安装**。 +## 环境部署 -### pip安装 +### 环境和依赖 + +- 硬件环境请参见《[昇腾产品形态说明](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软件包。 + +以上环境依赖请根据实际环境选择适配的版本。 + +### 安装 + +msprof_analyze工具的安装方式包括:**pip安装**、**下载whl包安装**和**源代码编译安装**。 + +#### pip安装 ```shell pip install msprof-analyze @@ -110,34 +131,12 @@ pip命令会自动安装最新的包及其配套依赖。 Successfully installed msprof-analyze-{version} ``` -### 下载whl包安装 +#### 下载whl包安装 1. 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 | - + 请通过[软件包下载](#软件包下载)msprof_analyze工具whl包。 + 2. whl包校验。 1. 根据以上下载链接下载whl包到Linux安装环境。 @@ -150,7 +149,7 @@ Successfully installed msprof-analyze-{version} {name}为whl包名称。 - 若回显呈现对应版本whl包一致的**校验码**,则表示下载了正确的性能工具whl安装包。示例如下: + 若回显呈现对应版本whl包一致的**校验码**,则表示下载了正确的whl安装包。示例如下: ```bash sha256sum msprof_analyze-1.0-py3-none-any.whl @@ -171,7 +170,7 @@ Successfully installed msprof-analyze-{version} Successfully installed msprof_analyze-{version} ``` -### 源代码编译安装 +#### 源代码编译安装 1. 安装依赖。 @@ -194,61 +193,68 @@ Successfully installed msprof-analyze-{version} pip3 install -r requirements.txt && python3 setup.py bdist_wheel ``` - 以上命令执行完成后在mstt/profiler/msprof_analyze/dist目录下生成性能工具whl安装包`msprof_analyze-{version}-py3-none-any.whl`。 + 以上命令执行完成后在mstt/profiler/msprof_analyze/dist目录下生成工具whl安装包`msprof_analyze-{version}-py3-none-any.whl`。 4. 安装。 - 执行如下命令进行性能工具安装。 + 执行如下命令进行msprof_analyze工具安装。 ```bash cd dist pip3 install ./msprof_analyze-{version}-py3-none-any.whl ``` -## 卸载和更新 +### 卸载和更新 若需要更新工具,请先卸载旧版本后再重新安装新版本,如下操作: -1. 卸载 +- 卸载 - ```bash - pip3 uninstall msprof-analyze - ``` + ```bash + pip3 uninstall msprof-analyze + ``` -2. 更新 +- 更新 - ```bash - pip3 install ./msprof_analyze-{version}-py3-none-any.whl - ``` + ```bash + pip3 install ./msprof_analyze-{version}-py3-none-any.whl + ``` -## 工具使用 +## 功能介绍 -```bash -msprof-analyze advisor [-h] -``` +### 性能分析 + +- [advisor(专家建议工具)](advisor/README.md) + + 将Ascend PyTorch Profiler或者MindSpore采集的性能数据进行分析,并输出性能调优建议。 + +- [cluster_analyse(集群分析工具)](cluster_analyse/README.md) + + 提供多机多卡的集群分析能力, 当前需要配合Ascend Insight的集群分析功能使用。 + +- [compare_tools(性能比对工具)](compare_tools/README.md) + + 提供PyTorch和MindSpore训练场景的性能数据比对。 + +### 其他功能 ```bash -msprof-analyze compare [-h] +msprof-analyze auto-completion ``` +自动补全。配置后在当前视图下配置msprof-analyze工具所有的子参数时,可以使用Tab将所有子参数自动补全。 + ```bash -msprof-analyze cluster [-h] +msprof-analyze -h ``` +-h、-H或--help,命令行参数帮助信息。 + ```bash -msprof-analyze auto-completion [-h] +msprof-analyze -v ``` -``` -msprof-analyze [-h] [-v] -``` +-v、-V或--version,命令行参数帮助信息。 -| 参数 | 说明 | -| -------------------- |-------------------------------------------------------------------------------------------------------------------------| -| 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 | 命令行参数帮助信息。 | +## [Licnese](LICENSE) diff --git a/profiler/msprof_analyze/cluster_analyse/cluster_kernels_analysis/README.md b/profiler/msprof_analyze/cluster_analyse/cluster_kernels_analysis/README.md index 1ada30fe54..f2eb52ce16 100644 --- a/profiler/msprof_analyze/cluster_analyse/cluster_kernels_analysis/README.md +++ b/profiler/msprof_analyze/cluster_analyse/cluster_kernels_analysis/README.md @@ -7,7 +7,7 @@ cluster_op_summary_analysis.py脚本基于多卡性能数据的op_summary信息 将算子以op_name、input_shape、input_size、output_shape进行分类,统计每一类算子,在不同节点(node)的不同卡(device)上,执行时间的最大、最小、方差、平均时间以及范围。 ### xxx_info.html -主要是各个特性(time和ratio)的html文件,以html方式展示top_n算子的箱线图。 +主要是各个特性(time和ratio)的html文件,以html方式展示TopN算子的箱线图。 time和ratio表示AI Core和AI Vector Core算子性能指标中的耗时和占比字段。 @@ -50,7 +50,7 @@ time和ratio表示AI Core和AI Vector Core算子性能指标中的耗时和占 3. 运行脚本 ```bash - python3 cluster_prof_info_analysis.py –d data_path -t type -n top_n + python3 cluster_prof_info_analysis.py –d data_path -t -n ``` - -d:集群场景性能数据目录,输入node的上一级目录。 diff --git a/profiler/msprof_analyze/docs/img/1.png b/profiler/msprof_analyze/docs/img/1.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf1cac87ce9858bdbcee93c02914a02543914ba GIT binary patch literal 9891 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