东方智慧AI 算力
AI算力 · 昇腾部署课件 F4

F4 性能调优:数据怎么采、怎么看

2026-10-05

编制:观澜|日期:2026-10-06|级别:T2 标准级 层级:F 层 · 场景实战(F 层第 4 课;前接 F1 模型迁移、F2 精度调试、F3 多卡与分布式) 素材来源:昇腾官方《性能调优工具(msProf)》用户指南(快速入门 / msprof 采集命令 / msProf 解析工具 / 性能数据文件参考 / 扩展功能)+《msprof-analyze · 专家建议》+《MindSpeed LLM · FSDP2 后端模型性能优化指南》+《Rec SDK 性能调优》+ 官方案例库 版本口径:CANN 9.2.0-beta.2 为主;MindSpeed 26.1.0、MindStudio 26.1.0 的章节已单独标注


第一段 章前定位

这一课不教你什么

先把边界划清——本课不是 D5。

D5《可用性、健康与调优》 本课 F4《性能调优》
问的问题 服务别挂:进程卡死了没有、健康检查通不通、日志级别对不对 跑得慢怎么变快:慢在哪一层、数据怎么采、采完怎么看
视角 服务视角(就绪、自愈、静默故障、KV Cache 亲和调度) 设备与执行视角(算子、搬运、通信、下发)
触发场景 服务起来了但不稳定 服务稳定但时延/吞吐不达标

一句话分工:D5 管"活着",F4 管"跑得快不快"。 两者都会用 Profiling 这个词,但 D5 关心的是服务级的健康数据,F4 关心的是设备上的时间花到哪去了。

其次,本课也不负责"优化代码本身"

性能调优是一条长链:先看清 → 再判断 → 才动手改。本课重点在前两步:

  • 怎么采:把设备上真实发生的事采下来(第一个坑:默认不采);
  • 怎么看:把采下来的文件读懂,判断瓶颈属于哪一类(算力 / 带宽 / 通信 / 下发 / 显存)。

改这一步只有原则性的方向(融合、类型、下发方式、并行度),具体改法依赖你的模型与代码——本课给判断依据,不替你改模型。这是诚实的边界,也是避免"讲了一堆技巧但不知道用哪条"的关键。

第三,一条数据纪律先讲明

性能数字极易被编造("调优后提升 3 倍"这类)。本课的原则:

凡官方文档给出阈值/公式的,写明"出处 + 版本";官方没给的,正文里明写「官方未给出,需现场确认」。

一个典型的坑:官方在不同产品、不同场景下给的参考值口径并不统一(例如"未掩盖通信 ≤10%"来自 MindSpeed LLM 的 FSDP2 场景,不是通用红线)。本课会逐条标明它来自哪个场景,避免把一个场景的阈值当普适真理用。


第二段 学习目标

学完这一课,你应该能:

  1. ✅ 说清一条性能数据的完整链路:采集 → 解析/导出 → 看 → 判瓶颈,以及每一步的产物文件长什么样
  2. ✅ 知道为什么"不采就什么都看不到"——Profiling 默认不开,这是第一个必须主动做的动作
  3. ✅ 用 msprof 命令行把一次训练或推理的性能数据采下来,并读懂屏幕上那几行 [INFO] 说明什么
  4. ✅ 说出 Timeline(时序) 和 Summary(统计) 两类文件各回答什么问题,以及各自该看哪个文件
  5. ✅ 用指标判断瓶颈类型:Free 时间看 Host 下发、aic_mac_ratio / aic_mte2_ratio 看计算还是访存、通信泳道看未掩盖通信、cube_utilization(%) 看矩阵单元
  6. ✅ 说出判据与它的来源(哪个阈值来自哪个场景),并知道哪些阈值官方没给、要自己建基线
  7. ✅ 采集踩坑时能自查:采集报错、采不到 AI Core 指标、文件过期、解析缺 modelid —— 各查什么

第三段 全景:一条性能数据从哪来、到哪去

3.1 先记住一句话:默认不采

官方原文(《Profiling数据采集与分析》,TensorFlow 商用版 9.0.0):

默认训练过程中不采集 Profiling 性能数据,如需采集、解析性能数据,请参考本节内容。

这句话的后果:你跑得慢,但屏幕上什么额外信息都没有——不是"没数据",是"没采"。所以性能调优的第一个动作永远是主动打开采集,而不是先猜。

⭐ 官方对采 Profiling 的定位(同一篇文档): 其目的是"准确定位系统的软、硬件性能瓶颈……以最小的代价提升业务性能"。 注意"定位"二字——采数据的价值不在数据本身,在于把猜测换成证据。

3.2 四段链路(本课的骨架)

① 采集        谁在跑:msprof 命令行(或框架侧 Profiler 接口)
              产出:PROF_XXX 目录(原始数据 + 自动解析件)

② 解析 / 导出 msprof --export=on   或   msprof.py import + export
              产出:mindstudio_profiler_output(json + csv)+ msprof_时间戳.db

③ 看数据      两类文件,回答两个不同的问题:
              Timeline(时序)——先看谁在等谁
              Summary(统计)——再问哪一类最贵

④ 定瓶颈      计算 / 访存 / 通信 / Host 下发 / 显存
              纪律:每次只处理一个主瓶颈,改完用同一口径重测

3.3 ③ 里的两个文件族(先分清,再谈分析)

官方(《性能数据文件参考》)把导出结果分成两类:

类型 长什么样 干什么用 用什么打开
Timeline(时序) msprof_{时间戳}.json 可视化展示各层级算子的调用关系与执行时序 chrome://tracing 或 MindStudio Insight
Summary(统计) mindstudio_profiler_output 下的 csv 文件 多维度的统计摘要信息,以表格形式汇总运行耗时 表格软件 / 文本

⭐ 记忆法: Timeline 回答"谁在等谁"(时间轴上的先后与间隙);Summary 回答"哪一类最贵"(按类型聚合的耗时排序)。 顺序上先 Timeline 定方向、再 Summary 定量——反过来容易盯着一个"耗时最高的算子"却看不出它其实是在等别人。

3.4 ④ 的五类瓶颈(名字先记住,第六段给判据)

计算瓶颈   Cube / Vector 单元忙不过来
访存瓶颈   数据搬运(MTE2/MTE3)占了大头
通信瓶颈   多卡场景,通信没被计算掩盖
Host 下发  设备在"饿着"等 CPU 下发任务(Free 时间高)
显存瓶颈   不是慢,是跑不动(OOM 或频繁换入换出)

⚠️ 这五类不是并列选项,而是"排他性诊断":先确定主瓶颈,再谈优化。 官方原话(《Rec SDK 性能调优》):

实际中大部分情况是解决完一个 bound,又会出现另一个 bound,或者混杂到一起的场景;没有出现 bound 可能是 NPU 利用率没有打满,可以先构造压力打满的场景,再分析瓶颈点。

这两句要记住:① 瓶颈会搬家,一次只解决一个;② 看不出瓶颈 ≠ 没有瓶颈,很可能是压力不够,没把设备跑满。


第四段 【如果我来做】——一次真实的性能问题排查路径

这一节是本课的核心。 前三段讲的是"性能数据是什么、有哪几段链路、瓶颈分几类",这一节讲的是: 如果客户把一台"跑得慢"的机器交给我,我按什么顺序做、每一步凭什么判断。

4.0 先亮结论:我会按这个顺序做

为什么顺序不能反:

  • 一上来就改代码调参数,改动没有基线可比——改完是快了还是慢了,说不清;
  • 一上来就开最高采集等级,采集开销把现象本身掩盖了(官方专门有"性能膨胀"这回事,见第八段);
  • 不先确认"设备到底跑满没有",可能花一天调一个根本没在工作的算子。

我会按这个顺序做(顺序 = 我"手伸进去"的顺序):

① 先对齐口径:跟提出需求的人确认指标是什么、目标是多少(时延?吞吐?step 耗时?),以及 batchsize / 数据类型——没有基准就无所谓快慢 ② 先看设备忙不忙:npu-smi info 看利用率,先做一次零成本的粗判 ③ 先确认环境能采:一行验环境的命令先过,不然采集起来也是一堆空数据 ④ 采最小的一份:只采一个稳态 step / 一小段时间窗,能定位问题就够,别一次采全程 ⑤ 先看 Timeline 找"间隙":间隙(设备空闲)比"哪个算子慢"更值得先看 ⑥ 再用 Summary 定量:按总耗时排序,落到具体算子类型或通信操作 ⑦ 定一个主瓶颈:计算 / 访存 / 通信 / 下发 / 显存,只选一个 ⑧ 改动之后用同一口径重测:这是唯一能证明"改对了"的方式 ⑨ 诚实:官方没给的阈值、没给的加速比,明说是自己建的基线,不编数字

下面把中间的每一步展开。

4.1 第 0 步:先把"快慢"定义出来(不做任何操作)

目的:在做任何事之前,先拿到一把尺子。

官方《Rec SDK 性能调优》把需要对齐的指标列得很清楚,我抄下来当清单:

要对齐的 为什么 官方给的例子
时延要求 是固定值还是变化值?低负载和高负载的标准一样吗? 要求某个固定值,或是变化值;以及低/高负载的要求标准
batchsize 分布 固定值还是动态值?分布如何? 固定值,或动态值及分布
QPS 官方定义:QPS = 请求数 / 秒(req/sec) —
吞吐量 官方定义:吞吐量 = QPS × batchsize —
数据类型 float16 / float32 决定算力口径 float16、float32 或其他
CPU 资源 官方明说:多卡场景可能会出现 CPU bound,前期调试需确认 CPU 资源是否已满足 单卡按客户配置,Docker 中切分 CPU 资源验证

训练场景的口径略有不同,官方《MindSpeed LLM · FSDP2》给的是这四项:

指标 定义 日志字段
稳态单 step 耗时 完成一个 optimizer step 的时间(含梯度累积的所有 micro batch) elapsed time per iteration (ms)
有效 token 吞吐 有效 token 数 ÷ step 耗时 tokens/s
MFU 模型实测 FLOPS ÷ 硬件理论峰值 mfu(仅在 FLOPS 口径相同的模型间比较)
峰值显存 — max_memory_allocated / max_memory_reserved

⚠️ 这里有一条本课要反复强调的纪律: 官方没有给出"性能达标线" —— 什么算快、什么算慢,官方文档未给出通用数字。 所以第 0 步的产出不是"官方标准",而是你和业务方一起定的目标值。 没有这个值,后面所有"提升了 X%"都无从谈起。

4.2 第 1 步:先看设备忙不忙(零成本粗判)

在采任何数据之前,我先敲一条最简单的命令(见第五段命令 ①)。

决策依据(官方《Rec SDK 性能调优》原文口径):

  • 利用率很高 → 很有可能就是 bound(设备被计算/搬运占满,问题在设备内部);
  • 单个推理时利用率低、多个推理并行时才超过 80% → 官方说"一般认为这个值就已经很高了";
  • ⚠️ 但这条命令的值不能当结论——官方明说:这种方式查看到的值是 cube 核上的 cycle 与时钟频率换算出来的 cycle 的比值,不包含 vector core 的占比,所以只是初步查看,具体要从 profiling 里的 cycle 自行计算。

所以第 1 步的作用只有一个:决定"要不要往下采"。它不能替你定瓶颈。

4.3 第 2 步:先确认环境采得动(不然白采)

采集工具对环境有要求,官方《msProf 快速入门》的前置条件表:

项目 要求 验证方法(官方原表)
硬件算力 Linux 服务器配备至少 1 张 NPU 卡,驱动与固件已安装 执行 npu-smi info,确认 NPU 卡状态正常
容器运行 已安装并运行 Docker(建议版本 ≥ 18.0) 执行 docker ps,无报错即表示服务正常启动
脚本执行 宿主机已安装 Python 3 执行 python3 -V
网络通信 已安装 curl(任意版本) 执行 curl -V

⚠️ 一条重要的适用范围说明(官方原文,必须照实转述): 《msProf 快速入门》这一篇教程 "仅支持在标准化 CANN 容器中执行,不支持直接在裸机、虚拟机或其他非标准容器环境中执行。" 这是"快速入门教程"的适用范围,不是 msProf 工具本身的限制——但在裸机/虚机上照抄快速入门的容器步骤会失败。 裸机环境的采集参数是否可用,需按《msProf 模型调优工具》主文档逐条确认。

再看一眼工具在哪(官方《msProf解析工具》给的两个路径):

  • msprof 命令行本体:${INSTALL_DIR}/tools/profiler/bin(Ascend EP 场景)
  • msprof.py 脚本:${INSTALL_DIR}/tools/profiler/profiler_tool/analysis/msprof
  • get_msprof_info.py:${INSTALL_DIR}/tools/profiler/profiler_tool/analysis/interface

其中 ${INSTALL_DIR} 官方给了替换口径:若安装的是 Toolkit 软件包、以 root 安装,安装后文件存储路径为 /usr/local/Ascend/cann。

4.4 第 3 步:采一份"最小"的数据

为什么不采全程:官方专门有一篇案例讲"性能膨胀"(profilingcase_007,见第八段)——开启 Profiling 后 step 耗时会变长,两者差值就是膨胀时间;膨胀程度与采集设置强相关。

我的默认策略:

先采最小 → 能定方向就不加项 → 定不了再加(stack / memory / shape)

训练场景官方 MindSpeed LLM 给了一个"最小 trace 采集"的范式(见第五段命令 ③ 的对照表), 核心两个参数就是"采哪几个 step"和"采哪几个 rank":

  • --training.profile_step_start 5 / --training.profile_step_end 6(官方明确:采集区间是左闭右开 [start, end))
  • --training.profile_ranks 0(首轮只采 0 号 rank)
  • 官方提示:定位性能问题时开启 stack、memory 和 shape 采集会使数据体积增大,并引入额外采集开销。

推理/单机场景则直接用 msprof 命令行把程序包起来采(第五段命令 ②)。

4.5 第 4 步:先看 Timeline 的"间隙",不要先看"谁最慢"

这是本课最容易被做错的一步。 多数人拿到 Timeline 第一反应是找"最长的那个色块", 但设备空着的那些间隙(Free)往往比某个慢算子更值得先看。

官方《MindSpeed LLM · FSDP2》把单步时间拆成三项,这是理解 Timeline 的钥匙:

step_time = computation_time
          + unhidden_communication_time
          + device_free_time

官方原话:Free 表示 Device 既未执行计算也未执行通信的时间段。其占比应小于 3%;若占比偏高,通常表明 NPU 在等待 Host 下发任务。

为什么先看 Free:如果设备大量时间在"等人喂任务",那么你优化任何算子都不会变快——因为瓶颈根本不在这里。这就是"先定方向、再谈细节"。

再看三件事(官方给的 Timeline 常用泳道):

泳道 看什么
Python / CANN 泳道 Host 侧在干什么:API 调用、下发是否密集
Ascend Hardware(NPU 层) 设备侧计算、通信任务的执行时序
Communication(通信) 通信事件与 Ascend Hardware 的通信子泳道一一对应
Overlap Analysis(覆盖分析) 把计算、通信任务垂直投影,得到计算、通信和空闲时间的拆分
AI Core Freq 是否降频(降频会导致该时间段性能必然下降)

⭐ Overlap Analysis 是通信场景的"第一眼":它把"计算、通信、空闲"三者拆开, 是不是通信没被掩盖住,一眼就能看出来,不必先去逐个算通信算子。

4.6 第 5 步:用 Summary 定量,落到具体算子

定完方向,再用统计文件把它量化。官方两篇文档给了同一套看法:

文件 官方定义 怎么看
op_statistic_*.csv 按算子类型聚合统计,(关键性概括)各类算子的调用总时间、总次数 按 Total Time(us) 降序排列,优先关注耗时占比高的算子类型
op_summary_*.csv 记录每个算子任务的执行明细 按 Task Duration(us) 降序定位耗时较长的任务,再结合 Task Type 查看 AI Core 和 AI CPU 上的任务分布

⭐ 两个文件的区别一句话: op_statistic 是"按类型汇总"(哪一类贵);op_summary 是"按任务明细"(哪一个贵)。 官方在快速入门里给的顺序也是这个:先看 statistic 定类型,再看 summary 定实例。

4.7 第 6 步:落到"是计算还是访存"——看 Kernel 明细的指标字段

这一层是 F4 与"看一眼就知道"的分水岭。官方《MindSpeed LLM · FSDP2》把字段给全了(需配置 aic_metrics=PipeUtilization 且 profiler_level >= Level1):

Cube(AI Core)算子重点看两个:

字段 含义
aic_mac_ratio MAC(矩阵乘加)单元耗时占比;高值表示计算密集型算子的计算资源利用率较高
aic_mte2_ratio MTE2(从 DDR/L2 读数据到 L1)耗时占比;高值可能表示内存带宽瓶颈

Vector(AI Vector Core)算子重点看两个:

字段 含义
aiv_vec_ratio Vector 单元占比;高值表示向量计算密集
aiv_mte2_ratio Vector MTE2 占比;高值可能表示内存带宽瓶颈

官方的判据原话(照抄):

通过分析 MAC/MTE2 占比,可以判断算子是计算 Bound 还是访存 Bound:MAC 占比高通常表示计算 Bound,MTE2 占比高通常表示访存 Bound。 对于 Cube 算子,期望 aic_mac_ratio 较高、aic_mte2_ratio 较低;对于 Vector 算子,期望 aiv_vec_ratio 较高、aiv_mte2_ratio 较低。

⭐ 这就是本课最值钱的一句判据:"计算还是访存"不用猜,看 MAC 与 MTE2 的占比对比即可。 另外还有一个直接字段 cube_utilization(%)(矩阵乘单元利用率),也可作参考。

4.8 第 7 步:只改一个瓶颈,然后用同一口径重测

官方给的是四类瓶颈的"推荐尝试顺序"(《MindSpeed LLM · FSDP2》"按瓶颈选择优化方向"表), 本课把它当作动手顺序的模板(注意:这些特性面向 MindSpeed LLM 训练,其他场景只借"顺序",不照搬特性名):

瓶颈类型 典型现象 推荐尝试顺序 官方点名的"不应优先做的事"
计算瓶颈 Attention、Norm、RoPE 等算子耗时高 模型专用融合 → Flash Attention → Fused RMSNorm/RoPE → MoE GroupedMatMul 未确认热点算子就增加切分或卸载
显存瓶颈 logits、激活、参数或优化器状态占用过高 ChunkLoss → CP/EP 切分 → 激活重计算 → 异步激活卸载 → Swap Optimizer 未区分显存来源就启用 offload 或 swap
通信瓶颈 未掩盖通信时间过长 FSDP 前向/反向预取 → fused dispatcher → EP MC2 → 检查并行组与拓扑 只调整并行度,不检查专家负载和通信重叠
Host 下发瓶颈 Device Free 时间偏高 任务队列 → CPU 绑核;小算子过多时同时评估计算类融合特性 通过 offload 引入更多 Host/Device 拷贝和调度

⚠️ 官方的一条硬提醒:除任务队列和 CPU 绑核外,其余特性均需要先针对模型完成相应的代码适配。 命令行或 YAML 参数只用于开启已适配的特性实现,不能代替模型代码适配。 —— 这句话直接否掉了"抄一串参数就能变快"的想法。

4.9 第 8 步:收口与出证据

  • 改动前后各采一次,用同一口径(同样 step、同样 rank、同样采集等级)对比;
  • 官方建议的观测项是端到端:step 耗时、Kernel 数量、峰值显存、精度结果一起看——官方原话是"启用后需对比端到端 step 耗时、Kernel 数量、峰值显存和精度结果,确认实际收益";
  • 验收证据:改前/改后的两份 Profiling 目录 + 一页说明(改了什么、哪一类指标变了、变成了多少)。

4.10 第 9 步:诚实——哪些地方我要明说"官方没给"

一份可信的调优报告,一定包含"我不知道的部分":

我做不到的 为什么
给一个"利用率应该到多少"的通用红线 官方未给出通用阈值;只有场景级参考值(如 MindSpeed 的 Free < 3%、未掩盖通信 ≤10%),口径不同不能混用
给"调优后能提升几倍"的预测 官方未给出这类加速比数字,本课也不编
承诺"这套参数在你的模型上也有效" 官方明说特性需先完成代码适配;换模型即换适配,需现场确认
告诉你在裸机上跑快速入门那套容器命令 官方快速入门仅支持标准化 CANN 容器;裸机路径需现场确认

第五段 怎么确认就位:可照抄的采集与分析命令

本节命令全部来自官方文档,逐条标注出处;每条给「含义 / 拆解 / 用法 / 期望 / 不过会怎样」五项。 命令用行内码书写,参数含义见方括号内说明。

命令 ① npu-smi info

命令 npu-smi info

含义:查 NPU 设备信息与利用率——这是采集前唯一的"零成本粗判" 拆解:npu-smi(昇腾设备管理工具)+ info(显示设备信息) 用法:直接敲;官方快速入门把它列为"硬件算力"前置条件的验证方法(确认 NPU 卡状态正常) 期望:一张表,列出每张卡的型号、温度、显存、进程等;官方《Rec SDK》口径:利用率很高则"很有可能就是 bound",多个推理并行时利用率超过 80%被认为很高 不过会怎样:命令不存在 → 驱动没装(回 A1);有输出但看不到卡 → 权限问题; ⚠️ 官方明确:这里显示的利用率只含 cube 核、不含 vector core,所以仅供参考,不能当结论——具体要用 profiling 里的 cycle 自行计算

命令 ② msprof --application="python3 ${HOME}/train.py" --output=${HOME}/prof_output

命令 msprof --application="python3 ${HOME}/train.py" --output=${HOME}/prof_output

含义:用 msProf 拉起训练脚本并一键完成采集与自动解析 拆解:msprof(性能数据采集工具)+ --application="..."(要被采样的用户程序及其参数)+ --output=(性能数据存放路径) 用法:官方快速入门的写法;${HOME}/train.py 换成你的脚本,${HOME}/prof_output 换成你的输出目录 期望:屏幕打印 [INFO] Start profiling....,训练日志正常输出,末尾出现 [INFO] Profiling finished. 与 [INFO] Process profiling data complete. Data is saved in /home/prof_output/PROF_000001_...(后者表明数据已落盘) 不过会怎样:报 Init platform by driver faild! → 驱动库路径没进 LD_LIBRARY_PATH,见第八段官方案例 case_941011; 脚本提示"没有空闲 NPU" → 结束其他 NPU 任务或换空闲卡;超过 5 分钟不完成,可能是 NPU 异常或被抢占(官方提示)

命令 ③ msprof --output=/home/projects/output --ascendcl=on --runtime-api=on --task-time=on --aicpu=on --ai-core=on /home/projects/MyApp/out/main

命令 msprof --output=/home/projects/output --ascendcl=on --runtime-api=on --task-time=on --aicpu=on --ai-core=on /home/projects/MyApp/out/main

含义:按需打开若干采集开关,采一份较完整的 AI 任务运行性能数据(这条是官方"采集AI任务运行性能数据"章节的使用示例原文) 拆解:--ascendcl(acl 接口性能数据,默认 on)+ --runtime-api(Runtime API 数据,默认 off)+ --task-time(算子下发耗时与算子执行耗时,涉及 task_time、op_summary、op_statistic 等文件)+ --aicpu(AICPU 算子详细信息)+ --ai-core(AI Core 数据采集开关)+ 末尾直接跟用户程序(官方推荐方式一) 用法:想采 AI Core 性能指标再加 --aic-metrics=PipeUtilization(多数型号的默认值);只要更精准的耗时、不要算子基本信息,则把 --task-time 配成 l0(官方:不采集算子基本信息数据,采集时性能开销较小) 期望:--output 指定目录下生成 PROF_XXX 目录,内含自动解析后的性能数据; 目录通常有 host/data、device_{id}/data、msprof_{时间戳}.db、mindstudio_profiler_output/ 不过会怎样:--aic-metrics 用了某型号不支持的取值(如 PipelineExecuteUtilization 在 Atlas 推理系列/训练系列/A2/A3/950 上均标注"不支持")→ 采集项为空; --output 路径含特殊字符(官方列了一串禁止字符,含 %、>、<、|、&、$、;、反引号等)→ 落盘失败

命令 ④ msprof --export=on --output=/home/profiler_data/PROF_XXX

命令 msprof --export=on --output=/home/profiler_data/PROF_XXX

含义:解析并导出已有性能数据——官方明确"对于常规性能数据导出场景,建议优先使用 msprof --export=on,该命令为默认入口" 拆解:--export=on(解析并导出,默认 off)+ --output=(须指定为 PROF_XXX 目录或它的父目录) 用法:默认导出 text(json + csv + db);只要一个汇总 db 文件给 MindStudio Insight 看,加 --type=db(配 db 时仅支持 --output,不支持其他参数);省空间加 --clear=on(导出后删 device_{id} 下的 sqlite 目录) 期望:在 PROF_XXX 下生成 mindstudio_profiler_output 目录和 msprof_*.db;mindstudio_profiler_output 内含 msprof_*.json、step_trace_*.json、一批 *.csv 和 README.txt 不过会怎样:报解析失败或文件无法落盘 → 磁盘或用户目录空间已满(官方"数据落盘约束"原文); 找不到命令 → msprof 不在 PATH,回第 2 步查 ${INSTALL_DIR}/tools/profiler/bin; ⚠️ 官方权限约束:使用前请确保执行用户的 umask ≥ 0027,且本工具不应使用 root 等高权限账户,建议普通用户执行;本工具为开发调测工具,不建议在生产环境使用

命令 ⑤ python3 msprof.py query -dir /home/profiler_data/PROF_XXX

命令 python3 msprof.py query -dir /home/profiler_data/PROF_XXX

含义:查询性能数据文件信息,拿到 iteration(Iteration ID)/ model(Model ID),便于后续只导出某一段 拆解:msprof.py(msProf 解析工具的脚本封装,官方:"日常使用建议优先用 msprof 命令行入口;msprof.py 主要用于脚本化集成")+ query(查询)+ -dir(必选,PROF_XXX 目录或其父目录) 用法:执行前需先 python3 msprof.py import -dir <dir> 解析,否则查询结果无意义(官方注意事项); 脚本所在目录:${INSTALL_DIR}/tools/profiler/profiler_tool/analysis/msprof 期望:屏幕打印表格,字段含 Job Info / Device ID / Dir Name / Collection Time / Model ID / Iteration Number / Top Time Iteration / Rank ID——其中 Top Time Iteration 是"耗时最长的 5 个迭代",这是选采样区间的直接依据 不过会怎样:没先 import → 查询结果无意义; 采样数据是单算子场景或只采了系统数据(没配 --application)→ 官方明确 这些场景不支持 --iteration-id 和 --model-id 参数

命令 ⑥ python3 get_msprof_info.py -dir /home/1/PROF_000001_20220129014731273_KEDKPORHMAGPGD/device_0

命令 python3 get_msprof_info.py -dir /home/1/PROF_000001_20220129014731273_KEDKPORHMAGPGD/device_0

含义:从已采集的 Profiling 数据里回查设备信息——用来确认"这份数据是哪台设备、什么版本、采了多少迭代" 拆解:get_msprof_info.py(官方脚本,路径 .../analysis/interface)+ -dir(必选:非集群场景须指定为 PROF_XXX 下的 host 或 device_{id} 目录;集群场景须指定为 PROF_XXX 的父目录) 用法:集群场景 -dir 指到父目录,结果会生成 /query/cluster_info.json 期望:非集群场景直接打印字段,含 AI Core Number、AI CPU Number、Control CPU Number、Host CPU 信息,以及 version_info(analysis_version / collection_version / drv_version 驱动版本);集群场景生成 cluster_info.json(含 Rank Id / Prof Id / Models) 不过会怎样:-dir 指到了 PROF_XXX 根目录 → 非集群场景取不到(官方要求指到 host 或 device_{id}); 报路径不存在 → 该目录不存在或根本没采到对应侧数据

命令 ⑦ msprof-analyze advisor all -d /path/to/profiling_data/

命令 msprof-analyze advisor all -d /path/to/profiling_data/

含义:自动分析性能数据并输出调优建议——官方 msprof-analyze 的"专家建议(advisor)"功能 拆解:advisor(子命令,含 all / computation / schedule 三个)+ -d(必选,性能数据目录)+ 可选 -o(输出目录)、-bp(基准数据,computation 和 schedule 不支持)、-l en(英文)、--force(跳过属主与文件大小限制) 用法:不确定瓶颈来源就用 all;重点查 AICPU、动态 Shape、Block Dim、算子瓶颈、融合算子图、AI Core 降频 → 用 computation;重点查 GC、亲和 API、aclopCompile、SyncBatchNorm、流同步 → 用 schedule 期望:在当前目录(或 -o 指定目录)保存分析结果,覆盖 Overall Summary(计算/通信/空闲维度拆解)、环境变量设置推荐、slow rank 慢卡、slow link 慢链路、通信小包检测、字节对齐检测、内存申请释放异常 等功能点 不过会怎样:⚠️ 官方两条约束必看——CANN 8.0RC1 之前仅支持 text 格式文件分析,8.0RC1 及之后支持 text 和 db; Ascend 950 系列产品的 CCU 场景下不支持采集通信矩阵和通信算子带宽数据,因此该工具 slow rank / slow link / communication 的分析功能不具参考意义

命令 ⑧ export TASK_QUEUE_ENABLE=2

命令 export TASK_QUEUE_ENABLE=2

含义:Host 下发瓶颈的标准优化手段(官方:将任务异步下发到 Device,提升 Host/Device 并行度) 拆解:TASK_QUEUE_ENABLE 是 TorchNPU 侧环境变量,取值 2 为官方在"Host 下发瓶颈"场景给出的配置 用法:官方给的启用前置条件是"Host Bound 明显时"——即先确认 Free 时间占比偏高(Device 在等下发),再开 期望:作用在下一轮训练/推理里,表现为 Device Free 时间下降、Host 与 Device 并行度提高 不过会怎样:⚠️ 两个官方明说的副作用—— ① ASCEND_LAUNCH_BLOCKING=1 会强制关闭任务队列,使本配置失效; ② TASK_QUEUE_ENABLE=2 会提高内存访问并发度,可能增加运行期间的 NPU 峰值显存(峰值显存本就是官方要一起观测的指标之一)

命令 ⑨ export CPU_AFFINITY_CONF=2

命令 export CPU_AFFINITY_CONF=2

含义:配置 CPU 亲和性(绑核),减少线程迁移与跨 NUMA 访问,提高下发稳定性 拆解:取值 0/未配置 = 禁用绑核;1 = 粗粒度绑核(把单张 NPU 关联的所有线程绑到指定 CPU 核心区间);2 = 细粒度绑核(把主要线程分别绑到独立 CPU 核);扩展写法 npu0:0-1,npu1:2-5(仅在 mode 不为 0 时生效) 用法:官方给了三种示例——export CPU_AFFINITY_CONF=1(粗粒度)、=2(细粒度)、=1,npu0:0-1,npu1:2-5,npu3:6-6(自定义) 期望:作用在下一轮运行;适用场景是官方列的"任务调度能力不足、跨 NUMA 访问或快慢卡问题突出" 不过会怎样:⚠️ 官方约束原话——"需结合服务器 CPU 拓扑设置;错误绑核可能降低性能"; 所以先查清本机 CPU 拓扑再绑,不要照抄示例里的核号

⭐ 命令 ⑩(预览用,不在产线跑):chrome://tracing

命令 chrome://tracing

含义:官方指定的 Timeline 打开方式(在 Chrome 地址栏输入,再把 msprof_*.json 拖进去) 拆解:不是 shell 命令,是浏览器内部页;官方另给快捷键:w 放大、s 缩小、a 左移、d 右移 用法:打开后开启 Flow events 下的选项,可用连线查看"应用层算子 → NPU 算子"的下发到执行对应关系(官方列的对应关系有 async_npu、MsTx、async_task_queue、HostToDevice、fwdbwd) 期望:看到 timeline 分层:应用层 / CANN 层(Runtime 与 Node)/ 底层 NPU(Ascend Hardware 各 Stream、Communication、Overlap Analysis);点色块看详细信息 不过会怎样:文件太大打不开 → 官方提供性能数据文件分片(msprof_slice.json,slice_switch 默认 off); 注意官方限制:开启分片且文件 > 20GB 会导出失败;文件 < 200MB 不触发分片; 大文件更推荐直接用 MindStudio Insight 打开


第六段 判据:怎么算"看懂了数据"

⚠️ 先看这一行:下列阈值全部是"场景级参考值",不是通用红线。 每条都标了来源与口径。 官方未给出跨场景通用的"性能达标线"——通用阈值官方未给出,需现场建基线。

6.1 平台级参考值(来源:MindSpeed LLM 26.1.0《FSDP2 后端模型性能优化指南》)

关键路径项目 官方参考范围 官方"需要关注" 官方给的常见原因
未掩盖通信 ≤ 10% > 20% all-gather / reduce-scatter / all-to-all / send-recv 无法被计算掩盖
Free 时间 < 3% ≥ 3% Host 下发慢、CPU 争用、频繁小算子、同步 API 或线程配置不当
计算 通常是主要部分 利用率低且空隙多 未使用融合算子、shape 不友好、负载过小、专家不均衡

口径提醒(很重要):这一整张表来自 MindSpeed LLM 的 FSDP2 分布式训练场景, 官方原文还专门声明"本文不适用于在线推理、KV Cache、推理量化和服务化调度;推理性能不能直接套用本文的指标和结论"。 所以要把它当"方法与量级",不当"拿来即用的红线"。

6.2 算子级参考值(来源:Rec SDK 26.1.0《性能调优》)

判据 官方口径
访存 bound 初判 直接看 aiv_mte2_ratio 字段是否超过 0.8;"如果有大量超过 0.8 的算子出现,则这一部分是需要进行优化的"
非对齐导致带宽低 排查搬运数据量是否非 32 byte 对齐,"非对齐场景也会导致带宽低"
Cube 利用率手算公式 利用率 = CUBE 总 cycle 数 ÷ (总耗时(s) × AI Core 数 × 频率(MHz) × 10⁶)
公式的拆解(官方给的一例) aic_total_cycles 求和得总 cycle;总耗时取按 start time 排序后首尾时间戳之差(单位 us,除以 10⁶ 换成秒);示例芯片的 AI Core 数为 20、频率 1650 MHz;官方在该例中算出的 Cube 整体利用率为 78.9%
谁占大头 各流程占比"直接用时间可以算出来";官方例子:mte2 耗时占比为 ai_core 总耗时的 70.18%,据此推断"ai_core 上的耗时内存搬入占大头"

⚠️ 公式里的"AI Core 数"和"频率"是随芯片变的(官方示例用的是 20 与 1650)—— 具体到你的卡是多少,官方未在该处给出,需现场确认(可用命令 ⑥ 的 get_msprof_info.py 看 AI Core Number)。

6.3 通信/链路级参考值(来源:CANN 9.2.0-beta.2《性能调优工具 · 扩展功能》)

指标 官方定义 / 阈值
等待时长比例 Wait Time Ratio 等待时长 / (等待时长 + 通信时长);官方给的建议判据:一个迭代内是否存在该比例 > 阈值 0.2 的卡
传输前同步时长比例 传输前同步时长 / (传输前同步时长 + 通信时长);大于 0.2 时怀疑存在慢卡
带宽使用率 大于 0.8 说明带宽使用正常,全网链路无瓶颈
通信包比例 大于 0.8 说明通信包尺寸无异常;若通信包尺寸过小,则"每次通信传输的包太小,导致带宽使用率不高,存在带宽的瓶颈"
慢链路输出条件 链路带宽小于平均带宽 20% 时输出最慢链路相关信息

6.4 采集/环境级判据(自查用)

项 判据
采集完成 屏幕出现 [INFO] Profiling finished. 且打印了 Data is saved in .../PROF_XXX
数据可解析 PROF_XXX 下已生成 mindstudio_profiler_output 与 msprof_*.db(或经 --export=on 生成)
AI Core 指标存在 采到了 aic_* / aiv_* 字段 且 不是全 0 —— 全 0 或缺失见第八段 profilingcase_002
采集没把现象改掉 对比开/关采集时的 step 耗时差值(膨胀),官方案例 profilingcase_007 的判别口径

第七段 出问题怎么查

排查原则:先分"采不到"和"看不懂"两类,再往下查。

采不到(数据链)  ── 采不到数据 / 采到了但缺项 / 解析失败 / 文件过期
看不懂(分析链)  ── 采到了、也能解析,但判断不出瓶颈属于哪一类

7.1 先看现象 → 先查什么(排查顺序)

现象 大概是什么 先查什么
msprof 一拉起就报 Init platform by driver faild! 驱动库没进环境 echo $LD_LIBRARY_PATH 看有没有驱动目录(第八段 case_941011)
屏幕上显示解析数据,但没有 AI Core Metrics 采集开关的下发时机被代码顺序破坏了 看 Host 侧日志 $HOME/ascend/log/plog;检查代码里 aclInit 是否在 aclrtSetDevice 之前(第八段 profilingcase_002)
有 PROF_XXX 但没法解析 数据被"老化"删了 看是否配了 --storage-limit 或磁盘快满(第八段 topic_0000001538203562)
解析后文件异常,缺 modelid 或 iterid 解析参数/版本问题 官方案例 case_941012(第八段)
Timeline 打开卡到打不开 文件太大 用 msprof_slice.json 分片,或改用 MindStudio Insight;注意官方限制:>20GB 导出失败、<200MB 不触发分片
开了采集后模型本身变慢 性能膨胀,正常现象 看 with_stack 是否开着(官方:性能影响巨大,可用 with_modules 替代)、profiler_level 是否过高
NPU 没跑满,看不出 bound 压力不够 官方建议:先构造压力打满的场景(如本地压测脚本、多流大压力跑本模型),再分析瓶颈
设备侧有大段空隙 Host 下发瓶颈 看 Free 占比(>3% 看第八段优化方向);查 HostToDevice 连线是否密集且接近垂直、CPU 绑核与争用、小算子数量、同步调用
某个算子耗时异常高 计算瓶颈,但先别急着融合 看 aic_mac_ratio vs aic_mte2_ratio:MAC 高 = 计算 bound;MTE2 高 = 访存 bound
多卡时个别卡拖慢整体 慢卡 / 慢链路 用 msprof-analyze advisor 的 slow rank / slow link;手工看 Wait Time Ratio > 0.2
结果对不上但"也能跑" 这一般不是性能问题 回 F2 精度调试

7.2 按"瓶颈类型"排的排查顺序(分析链)

① 先量 Free(设备空闲)
   ├─ Free 高(≥3%)        → Host 下发瓶颈 → 命令 ⑧/⑨,并查小算子与同步调用
   └─ Free 低
       ├─ ② 再看 Overlap Analysis:通信有没有被掩盖
       │   ├─ 未掩盖通信高   → 通信瓶颈 → 查通信泳道带宽、慢卡、慢链路
       │   └─ 通信没问题
       │       └─ ③ 最后看算子:MAC 与 MTE2 谁占比高
       │           ├─ MAC 高   → 计算 bound → 融合 / 类型 / 图优化
       │           └─ MTE2 高  → 访存 bound → 对齐、融合、减搬运
       └─ ④ 若始终看不出 bound → 压力可能不够,先打满再分析

⚠️ 一条判断法(本课自用,非官方表述): "先看等着的时间,再看忙着的算力。" 设备大量在等 → 优化算力没用;设备确实在忙 → 才轮到谈算子怎么优化。

7.3 慢的时候,还有一个最容易漏的检查:是不是设备在降频

官方《性能数据文件参考》专门讲了 AI Core Freq 层级:

在 148089.72045898438 时刻下,AI Core 处于高频状态,而在 170178.44116210938 时刻频率降低,那么在该时间段下 AI 任务的性能必然下降。 AI Core 芯片可能因温度升高,触发保护机制,降低频率;也可能因当前无 AI 任务运行,AI Core 进入低功耗状态而降频。

并且官方给了一个精度提醒:

在发生变频时,实际变频时间与软件监测到的时间存在 0~1ms 的延时,该延时可能导致变频前后统计出的算子执行时间与实际不符。

⭐ 这条的价值:如果你发现"计时的口径和实际观感对不上",先排除变频与时间同步误差,不要一口咬定是算子的问题。 官方在 Flow events 那节也提示过:由于软件测量的频率与真实频率有误差、Host 与 Device 有时间同步误差,可能出现下层算子因错位而无法连线。


第八段 常见报错清单

检索口径(沿袭 E1):到官方案例库 https://www.hiascend.com/document/caselibrary 按报错里的稳定特征词检索, 不要按"性能调优"这种泛词检索。下表里的案例编号均为官方真实编号,另附浏览量供参考。

报错 / 现象 官方案例编号 查看量 根因与做法(官方原文口径)
msprof 拉起应用失败:Init platform by driver faild! case_941011 914 未添加驱动环境变量至 LD_LIBRARY_PATH;先 echo $LD_LIBRARY_PATH 排查,再补 export LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/common:/usr/local/Ascend/driver/lib64/driver:$LD_LIBRARY_PATH
执行 msprof 后未采集到 AI Core Metrics 数据 profilingcase_002 880 代码里aclInit 调在 aclrtSetDevice 之后,导致 Runtime 无法下发 AI Core 性能数据采集开关任务;调整代码使 aclInit 最先调用后重编重采
Profiling 数据老化导致无法正常解析数据 topic_0000001538203562 792 数据超过 storage_limit 限定值或剩余磁盘空间较小时,工具会自动老化删除最早的 Profiling 数据;采集前先看清盘
msprof 解析后输出文件异常,缺少 modelid 或 iterid case_941012 1197 官方案例:解析后文件缺 modelid/iterid;按该案例步骤处理
PyTorch 场景如何采集最小膨胀数据(开采集后 step 变慢) profilingcase_007 1373 官方给出"推荐配置"与"最小膨胀配置"两套 Profiler 写法;影响膨胀的因素按程度排序:with_stack(性能影响巨大,可用 with_modules 替代)> profiler_level > activities > 其余采集开关
Profiling 里出现 format 为 NHWC 的算子且性能较低 topic_0000001539375010 756 官方案例:NHWC 算子性能较低;结合格式转换类分析(可参考官方优化案例中的 TransData 占比高处理方向)
网络调测时 ReduceSum 算子性能差 topic_0000001261263136 980 官方定位口径:Profiling 里看该算子block_dim 字段值为 1,说明该算子未开启多核并行计算
AI Core 算子执行时间超时导致网络运行失败 topic_0000001308583121 1404 执行模型推理时返回模型执行失败,Device 侧日志有 ERROR 级别打印;按官方案例定位(注意这是"跑失败"不是"跑得慢",别混为一类)
部署 DeepSeek 服务化,性能不佳 topic_0000002193154190 7969 拉起后实测性能较差,与预期差异较大;这是服务化场景,与本课单机性能分析口径不同,注意区分
装了 --sys-hardware-mem 采集 memory 数据可能触发 glibc 已知 Bug 官方文档明示(非案例编号) — 官方原文:在 glibc < 2.34 的环境上采集 memory 数据,可能触发 glibc 的已知 Bug 19329,通过升级环境的 glibc 版本可解决

⚠️ 两条本课要明说的"没有答案":

  1. 没有"Profiling 采集一次固定花多长时间"的官方数字——采集开销与采集项、模型、硬件有关,官方未给出,只能用"开关采集前后各测一次 step 耗时取差值"的办法现场量化。
  2. 没有"什么利用率算合格"的通用官方红线——官方给的都是场景级参考(见第六段),通用阈值官方未给出。

第九段 小结与下一课

这一课要带走的三句话:

  1. 默认不采——"跑得慢"这件事,不主动打开 Profiling,屏幕上什么证据都不会有; 性能调优的第一个动作永远是采,不是猜。
  2. 先看等着的时间,再看忙着的算力——Free 时间与 Overlap Analysis 告诉你设备在等谁; 确认设备真在忙,才轮到用 aic_mac_ratio / aic_mte2_ratio 分"计算还是访存"。
  3. 阈值要带出处——Free < 3%、未掩盖通信 ≤10% 来自 MindSpeed LLM 的 FSDP2 场景, aiv_mte2_ratio > 0.8 来自 Rec SDK;通用红线官方未给出,要自己建基线。

一次完整排查的动作顺序(串联本课):

对齐口径(时延/QPS/吞吐/step 耗时 + batchsize + 数据类型)
   → npu-smi info 粗判设备忙不忙
   → 确认环境采得动(卡/驱动/工具路径/磁盘)
   → 采最小的一份(少量 step、少量 rank)
   → Timeline 先看间隙(Free / Overlap Analysis)
   → Summary 定量(op_statistic 定类型 → op_summary 定实例)
   → 定一个主瓶颈(计算/访存/通信/下发/显存)
   → 改一处 → 同口径重测 → 出证据
   → 官方没给的,明说"这是我建的基线"

下一课预告(F5): 到这里,迁移(F1)、精度(F2)、多卡(F3)、性能(F4)四件"单场景"的能力都齐了。 F5 把零件串成一条完整链路:从单卡推理这一件事出发,把"装好 → 跑通 → 结果对 → 性能达标 → 交出证据" 整条链路完整走一遍——那是 F 层把前面几层真正"用起来"的一课。


附录 A · 本课引用的官方出处

内容 来源文档(版本)
msProf 是什么、快速入门五步、前置条件表、容器的适用范围声明、msprof --application= 示例与 [INFO] 输出、PROF_XXX 目录结构、op_statistic / op_summary 的"分析方法举例" 《msProf 模型调优工具 · 快速入门》(CANN 9.2.0-beta.2 · 调试与分析工具 · 性能调优工具)
msprof [options] <app> 两种方式、--output / --type / --environment / --storage-limit、路径禁止字符列表 《msprof采集通用命令》(同上)
--ascendcl / --runtime-api / --task-time(l0/l1/l2/l3/on/off) / --aicpu / --ai-core / --aic-mode / --aic-metrics(含各取值与型号支持表、默认值 PipeUtilization)/ --sys-hardware-mem / --l2 / --ge-api / --task-memory / --task-block、完整采集示例 《采集AI任务运行性能数据》(同上)
msprof --export=on 为推荐入口、msprof.py 的 import/query/export、get_msprof_info.py、设备信息字段表、性能数据文件分片(msprof_slice.json)、权限/落盘/兼容性约束、工具路径 《msProf解析工具》+《扩展功能》(同上)
Timeline 四区域、chrome://tracing、Flow events 连线关系(async_npu / MsTx / async_task_queue / HostToDevice / fwdbwd)、AI Core Freq 与 0~1ms 变频延时、SIO、QoS、分片限制 《性能数据文件参考》(同上)
性能调优建议(通信耗时分析、Wait Time Ratio > 0.2、带宽使用率 > 0.8、通信包比例 > 0.8、慢链路 < 平均带宽 20%) 《扩展功能 · 性能调优建议》(同上,官方注明该功能已不再演进,改用 msprof-analyze)
推理场景"采集&解析性能数据"、默认采集文件表、json/csv 打开方式、按 Total Time / Task Duration 排序的分析法 《模型推理性能调优建议 · 采集&解析性能数据》(CANN 9.2.0-beta.2)
msprof-analyze advisor 三个子命令、速查表、参数(-d / -bp / -o / -l / --force / -cv / -tv / -pt)、完整功能点表、两条约束 《msprof-analyze · 专家建议》(MindStudio 26.1.0)
单 step 时间三分解、核心指标(step 耗时 / tokens/s / MFU / 峰值显存)、关注项与参考范围(未掩盖通信 ≤10%/>20%、Free <3%/≥3%)、采集等级 Level0/Level1、性能数据文件清单、Timeline 泳道表、op_statistic.csv 与 kernel_details.csv 字段定义、AI Core / AI Vector 指标与判据、四类瓶颈的推荐顺序与特性表、TASK_QUEUE_ENABLE=2、CPU_AFFINITY_CONF、显存瓶颈、常见优化案例(TransData、冗余代码、allow_internal_format) 《MindSpeed LLM · FSDP2 后端模型性能优化指南》(MindSpeed 26.1.0)
性能调优流程与需对齐指标(时延 / batchsize / QPS=请求数÷秒 / 吞吐量=QPS×batchsize / 数据类型)、npu-smi info 利用率粗判与"不含 vector core"的口径、Cube 利用率计算公式与 78.9% 示例、mte2 占比 70.18%、aiv_mte2_ratio > 0.8、非 32 byte 对齐、cube/vector bound 优化手段、访存/Pcie 分析方向、案例分享 《Rec SDK · 性能调优》(MindSDK 26.1.0)
案例 case_941011、profilingcase_002、profilingcase_007、case_941012、topic_0000001538203562、topic_0000001539375010、topic_0000001261263136、topic_0000001308583121、topic_0000002193154190 官网 案例库(https://www.hiascend.com/document/caselibrary/detail/<案例编号>)
默认不采集 Profiling、借助 Profiling"准确定位系统的软、硬件性能瓶颈" 《Profiling数据采集与分析》(TensorFlow 商用版 9.0.0;含 TensorFlow / Keras / Estimator / sess.run 与"环境变量方式"的采集写法)

本课未写的东西(数据纪律:官方未给出,故不编)

  • 任何加速比 / 提升倍数 / 耗时绝对值——官方文档未给出可迁移的数字,本课一个都不编。
  • 通用"性能达标线"——官方只有场景级参考值(第六段已逐条标注来源与口径),通用阈值官方未给出。
  • aic_metrics 的通用最优取值——官方给的是"默认值 + 各型号支持情况"表;选哪个取决于你要查什么(本课给的是选择依据,不是推荐值)。
  • Profiling 采集的固定耗时/膨胀比例——官方未给数字,只给"影响膨胀的因素排序"。
  • Cube 利用率公式里各芯片的 AI Core 数与频率——官方示例用的是 20 与 1650,你的卡是多少需现场确认。
  • 裸机/虚拟机场景下的完整采集流程——官方《msProf 快速入门》明确仅支持标准化 CANN 容器;裸机路径须按主文档逐条确认。

附录 B · 命令与代码逐条详解

B.1 msprof 的两种调用方式(官方原文)

方式 写法 官方说明
方式一(推荐) msprof [options] <app> 在 msprof 命令末尾直接传入用户程序或执行脚本
方式二 msprof [options] --application=<app> 通过 --application 参数传入

官方给的一条重要提醒:

若 parameter 中存在异常符号时将无法识别参数,因此推荐使用方式一传入用户程序。 使用方式一时,若配置的用户程序命令中存在配置参数值需要加引号的情况, 请将命令写入 Shell 脚本后,通过执行 Shell 脚本的方式在 msprof 命令上添加用户程序命令。

⭐ 实践含义:命令里参数带引号、带空格、带重定向 → 先写成 .sh,再让 msprof 跑这个脚本,别硬塞。

B.2 采集侧关键参数速查

参数 取值 官方要点
--output 路径 优先级高于 ASCEND_WORK_PATH;路径不能含特殊字符(官方列了一长串:换行、%、>、<、|、&、$、;、反引号等)
--type text(默认)/ db text = 解析出 json、csv 和 db;db = 只出一个汇总 .db,配 db 时仅支持 --output
--environment "K=V;K2=V2" 采集时需要的自定义环境变量
--storage-limit [200, 4294967295] MB,如 200MB 到限或剩余总空间 ≤20MB 时,老化删除最早的文件;未配置时,采集前若可用空间 < 20MB 则不落盘
--task-time l0 / l1 / l2 / l3 / on(=l1,默认)/ off 采"算子下发耗时 + 算子执行耗时";l0 不采算子基本信息,开销较小、耗时更精准;l1/l2 支持采集集合通信算子数据;l3 为试用特性,不支持用于生产
--ai-core on / off 默认值随 --task-time 变:on/l1 时默认 on;off/l0 时默认 off
--aic-mode task-based(默认)/ sample-based 采集粒度;前提是 --ai-core=on;官方建议 AI 任务场景用 task-based
--aic-metrics 见 B.3 前提是 --ai-core=on
--sys-hardware-mem on / off(默认 off) 片上内存读写速率、QoS 带宽、LLC 三级缓存带宽、加速器带宽、SoC 传输带宽、组件内存占用;不同型号采集内容略有差异
--sys-hardware-mem-freq [1,100] Hz,默认 50 前提是 --sys-hardware-mem=on;⚠️ 官方:A2 / A3 / 200I·500 A2 采集结束后不建议改频率,否则可能丢数据
--l2 on / off L2 Cache、TLB 页表缓存命中率;aclgraph 场景执行模型阶段开启则不生效;A2/A3 分析 AI Core 命中 L2 官方推荐用 --aic-metrics=L2Cache
--ge-api off(默认)/ l0 / l1 采动态 Shape 算子在 Host 调度阶段的耗时
--task-memory on / off CANN 算子级内存占用,用于优化内存使用

B.3 --aic-metrics 的取值(这一项直接决定你能看到哪些指标)

取值 采什么
ArithmeticUtilization 计算类指令耗时占比
PipeUtilization 计算类和搬运类指令耗时和占比(多数型号的默认值)
Memory 内存读写带宽速率
MemoryL0 / MemoryUB L0 / UB 读写带宽速率
ResourceConflictRatio 资源冲突占比
L2Cache L2 Cache 命中率
PipelineExecuteUtilization 计算类和搬运类指令耗时和占比(⚠️ Atlas 推理系列 / 训练系列 / A2 / A3 / Ascend 950PR·950DT 均标注"不支持")
MemoryAccess ⚠️ Atlas 200I·500 A2 / Atlas 推理系列 / Atlas 训练系列 / Ascend 950PR·950DT 均标注"不支持"
Custom:0x..,0x.. 自定义 PMU 寄存器;最多 8 个,范围 [0x1, 0x7FFFFFFF];无对应寄存器的值采集结果可能为 0

B.4 为什么 kernel_details.csv 里那些 aic_* / aiv_* 字段看不到

官方写明:这些字段需配置 aic_metrics=PipeUtilization 且 profiler_level >= Level1。 两条不满足任一条,指标列就是空的——这跟"采到了但没用"不是一回事。

B.5 采集等级与"能看哪些界面"(MindSpeed LLM 口径)

采集等级 生成的额外文件 能看的界面 官方说明
ProfilerLevel.Level0 trace_view.json、msprof_*.json、operator_details.csv、kernel_details.csv(无 AI Core 性能指标)、memory_record.csv、operator_memory.csv 时间线、内存、算子 基础级别,不采通信数据和 AI Core 性能指标
ProfilerLevel.Level1 Level0 全部 + communication.json、communication_matrix.json、kernel_details.csv(含 AI Core 性能指标) Level0 全部 + 概览(Summary)、通信 中等级别,额外采通信数据和 AI Core 性能指标

⭐ 一句话记法:要看"计算还是访存",至少 Level1 + PipeUtilization。 只想看时序和算子耗时,Level0 更省开销。

B.6 op_statistic.csv 字段("哪一类贵")

字段 含义
Device_id 设备 ID
Model Name 模型名称(默认或单算子场景可能不显示)
OP Type 算子类型
Core Type Core 类型:AI_CORE / AI_VECTOR_CORE / AI_CPU 等
Count 算子调用次数
Total Time(us) 算子调用总耗时(us)——按它降序就是分析入口
Avg Time(us) / Min Time(us) / Max Time(us) 平均 / 最小 / 最大耗时(us)

B.7 kernel_details.csv 关键字段("哪一个贵、贵在算还是搬")

字段 说明
Name / Type 算子名称 / 算子类型(如 Conv2D、MatMulV2、TransData)
Accelerator Core 加速器核心:AI_CORE / AI_VECTOR_CORE / DSA_SQE / MIX_AIV
Start Time(μs) / Duration(μs) / Wait Time(μs) 开始时间 / 持续时间 / 等待时间(通信场景的 Wait Time Ratio 就取它)
Input/Output Shapes、Input/Output Data Types、Input/Output Formats 形状 / 数据类型 / 数据格式(如 NCHW、NC1HWC0、FRACTAL_Z、FORMAT_ND)
aicore_time(μs)、aic_total_cycles、aic_mac_time(μs)、aic_mac_ratio、aic_scalar_ratio、aic_mte1_ratio、aic_mte2_ratio、aic_fixpipe_ratio、aic_icache_miss_rate AI Core(Cube)侧指标
aiv_time(μs)、aiv_total_cycles、aiv_vec_time(μs)、aiv_vec_ratio、aiv_scalar_ratio、aiv_mte2_ratio、aiv_mte3_ratio、aiv_icache_miss_rate、cube_utilization(%) AI Vector 侧指标

每个 _ratio 的本质都是同一个式子:该单元耗时 ÷ 总耗时。所以看 _ratio 就是看时间被谁吃掉了。

B.8 官方给的一段可直接照抄的 Profiler 采集配置(案例 profilingcase_007)

官方原话:该配置用于"采集性能数据推荐配置——使用推荐配置可获取一般性能分析问题所需的 Host 和 Device 侧数据"。

experimental_config = torch_npu.profiler._ExperimentalConfig(
    export_type=torch_npu.profiler.ExportType.Text,
    aic_metrics=torch_npu.profiler.AiCMetrics.PipeUtilization,
    profiler_level=torch_npu.profiler.ProfilerLevel.Level1,
    l2_cache=False,
    data_simplification=False
)
with torch_npu.profiler.profile(
    activities=[
        torch_npu.profiler.ProfilerActivity.CPU,
        torch_npu.profiler.ProfilerActivity.NPU
    ],
    schedule=torch_npu.profiler.schedule(wait=1, warmup=1, active=2, repeat=2, skip_first=10),
    on_trace_ready=torch_npu.profiler.tensorboard_trace_handler("./result"),
    experimental_config=experimental_config) as prof:
    for step in range(steps):
        train_one_step(step, steps, train_loader, model, optimizer, criterion)
        prof.step()

同一案例给的"最小膨胀"配置(官方用途:一般用于和 GPU 性能数据对比使用):

with torch_npu.profiler.profile(
    activities=[torch_npu.profiler.ProfilerActivity.NPU],
    schedule=torch_npu.profiler.schedule(wait=1, warmup=1, active=1, repeat=1, skip_first=20),
    on_trace_ready=torch_npu.profiler.tensorboard_trace_handler("./npu-profling-least-inflation")
) as prof:
    for step, x in enumerate(train_dataloader):    # train_one_step
        ...
        prof.step()

两段的差别值得琢磨:最小膨胀那段只采集 NPU 一个 activity、active=1 repeat=1; 官方给的影响膨胀的因素排序第一位是 with_stack(性能影响巨大,可用 with_modules 替代)—— 所以"对比 GPU"就用最小膨胀配置,"查瓶颈"才上推荐配置,两者目的不同,不要混用。

B.9 训练场景 Profiler 的步数与 rank 控制(MindSpeed LLM)

参数 官方示例值 作用
--training.profile_step_start / profile_step_end 5 / 6 采集区间是左闭右开 [start, end)
--training.profile_ranks 0 采哪些 rank;首轮只采 0 号
--training.profile_level level1 采集等级(见 B.5)
--training.profile_with_cpu true 同时采 CPU 与 NPU
--training.profile_with_stack true 定位热点算子的代码位置用;增加开销与体积
--training.profile_with_memory true 分析算子显存申请用
--training.profile_record_shapes true 记录 shape(深采才加)
--training.profile_save_path ./profile_fsdp2_rank0 落盘路径

官方提醒:确认通信或慢 rank 问题后,再选择少量代表 rank 或所有 rank;深采的三个开关会增加采集开销和结果体积。

B.10 落盘约束与安全提示(官方原文,采集前必读)

  • 权限:执行用户 umask ≥ 0027;不应使用 root 等高权限账户,建议普通用户;为开发调测工具,不建议在生产环境使用;性能数据应保存在不含软链接的当前用户目录下。
  • 落盘:解析过程中若落盘路径磁盘或用户目录空间已满,会解析失败或文件无法落盘。
  • 版本:工具支持 Python 3.7.5 及以上;如需复现快速入门样例,建议 Python 3.9 及以上。
  • 路径:需要指定路径的参数,不得包含特殊字符(官方列了完整清单)。
选修 · 昇腾 AI 部署实操 本机读完 0/51
选修 C · 昇腾 AI 部署实操
从零把昇腾 AI 部署学一遍:先看懂分几层,再逐层装起来,最后出问题能自己定位到哪一层。不需要先有卡就能开始。
看完整学习路径(6 站 + 3 门选修) · 进度只存在你这台设备的浏览器里,不用登录
辽ICP备2026019944号-1