十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用msprof精准定位AI Core利用率瓶颈:CANN性能分析实战

用msprof精准定位AI Core利用率瓶颈:CANN性能分析实战 最近在帮团队做模型迁移和算子优化好几个同事跑来问我同一个问题明明已经把模型搬到CANN平台上了用上了昇腾AI处理器整机的算力却一直上不去看着跑起来了底下的计算单元到底在忙还是闲着没人说得清。这种时候我会先让他们跑一轮msprof把加速卡的利用率数据拉出来看看大多数瓶颈一眼就能定位。msprof是CANN Toolkit自带的性能分析工具主要用来采集和统计加速卡上各个计算单元的使用情况、算子耗时、任务下发和同步等待时间。很多人误以为它只是一个简单的profiler能看看算子耗时排行实际上msprof的GPU利用率分析能力远比这个深入它能拆解到AI Core内部各种执行单元的忙闲状态帮你回答一个核心问题算力到底是被用上了还是被白白等掉了。这篇文章我会从实际使用角度出发把msprof做利用率分析这件事讲透包括工具怎么装、报告怎么读、哪些指标要重点看、哪些场景容易误判以及我踩过的坑。1. 为什么算力跑不满才是真正的优化起点先说一个很多刚接触CANN生态的人容易忽略的事实程序能跑和算力被用满是两码事。我见过不少团队做性能优化一上来就盯着端到端时延推理慢了就死磕算子实现训练慢了就去调batch size。其实在动手改任何代码之前应该先搞清楚计算资源到底被利用了多少。如果你的AI Core利用率只有30%那问题根本不在某几个算子的实现细节而在整体调度、数据供给、模型结构这种更宏观的层面。这里说的利用率不是指加速卡“有没有在工作”而是指计算单元真正在执行有效计算的时间占比。举个例子一次矩阵乘法如果计算本身只要5微秒但数据从内存搬运到片上缓存花了15微秒那AI Core在这20微秒里真正“干活”的时间只有25%剩下的时间都在等待。msprof能把这些等待时间精确量化出来这才是做性能优化的第一手依据。我个人的经验是在CANN生态里做性能优化优化的起点不应该是“哪个算子慢”而应该是“算力去哪儿了”。慢只是表象算力闲置、数据等待、任务串行才是真正需要解决的问题。2. msprof从安装到拿到第一份利用率报告2.1 工具安装与版本确认msprof随CANN Toolkit一起安装不需要单独下载。安装完成后确认环境变量的方法很简单source /usr/local/Ascend/ascend-toolkit/set_env.sh which msprof正常情况下会输出msprof的可执行文件路径。如果找不到检查一下CANN Toolkit是否完整安装或者环境变量有没有source成功。这里有个容易踩的坑很多人在自定义shell环境下忘记source set_env.sh导致msprof命令根本找不到还以为工具没装。2.2 一条最基础的profile命令拿到第一份利用率报告用一条最简单的命令就够了msprof --application./your_app --output./prof_data这条命令会启动你的应用程序采集整个运行期间的性能数据然后输出到prof_data目录。跑完之后目录下会生成一个名为msprof_*.csv或者sqlite格式的汇总文件具体取决于版本里面就包含了整体利用率数据。如果要针对特定阶段分析msprof支持按step或者时间区间去过滤数据。我常用的做法是先全量采集再根据时间戳切分到具体某个训练stepmsprof --application./your_app --max_steps10 --output./prof_data --start_time1000 --end_time5000这里的--start_time和--end_time是采集的起始和结束时间微秒级适合已知问题发生窗口的情况。2.3 采集原理简述msprof之所以能给出利用率数据核心在于CANN的运行时会在AI Core执行指令时打点记录每个计算任务的开始时间、结束时间、使用的计算单元类型、等待原因等信息。msprof把这些打点数据汇总统计出各种耗时占比。理解这一点很重要因为它决定了msprof统计口径的准确范围。它统计的是任务级的忙闲不是晶振级别的指令级分析但对于绝大多数性能优化场景已经足够细了。如果你需要看AI Core内部流水线级别的stall原因那就得用更底层的工具msprof的职责范围不在这。3. 报告里每个百分比到底在说什么3.1 核心指标拆解打开msprof的汇总报告你会看到一堆指标。很多新手容易一头扎进算子耗时TopN却忽略了最开头的几个全局指标。我按优先级高低整理一下最值得关注的字段指标含义关注优先级AI Core利用率AI计算单元忙碌时间占总时间的比例极高判断算力整体水位AI CPU利用率控制类CPU核的忙碌比例高判断是否存在调度瓶颈内存搬运耗时占比数据在DDR和片上缓存之间搬运的时间占比高判断数据供给是否充足任务下发耗时占比Host侧下发计算任务的开销中多卡场景要重点看整机空闲占比所有计算单元都空闲的时间中配合利用率看同步等待占比算子之间同步等待的时间中过长说明流水有问题其中AI Core利用率是最直接反映“算力用没用上”的指标。这个数字如果长期低于50%基本可以判定存在严重的等待或者调度问题不需要再去看单个算子的实现了。3.2 不同场景下的合理水位参考利用率这个数字脱离了场景去谈就是耍流氓。我分三种典型场景说一下合理的预期水位大模型训练场景数据准备充分、计算密集的任务AI Core利用率通常能跑到70%到90%以上。如果低于这个区间优先检查数据加载管线、通信同步、梯度累积逻辑。推理服务场景单次推理的启动和收尾开销占比高利用率普遍在30%到60%之间。这种情况不用太焦虑因为推理请求本身是离散的算力有空闲是正常现象。关键是看有效计算时间占比是不是稳定如果忽高忽低说明请求调度可能有波动。小算子密集场景模型里大量小shape算子串行执行每个算子计算量不大但启动开销占比高利用率会明显偏低可能只有10%到30%。这种情况的优化方向是算子融合而不是去调单个算子的实现。4. 利用率“假低”与“真低”先分清再动手利用率低不一定代表有问题。我在实际项目中见过太多因为误判而白忙一场的案例所以单独拎出来说。4.1 容易被误判为“利用率低”的三种情况第一种是启动和收尾阶段。程序刚开始加载权重、初始化上下文的那几秒钟AI Core根本还没有计算任务利用率自然趋近于零。如果你把整个运行时间都统计进去这个启动阶段的拉低效应会很明显。看数据时应该把启动阶段排除掉只看稳定运行阶段。第二种是固定shape的小batch推理。模型每次只处理一个很小的输入计算量极小算力可能只用了不到一毫秒就完成了剩下的大部分时间都在等待下一个请求。这时候利用率看着低但实际性能和能耗都是合理的。第三种是算子队列排空。计算任务是一条条下发到加速卡上的如果下发指令传输速度跟不上计算速度AI Core就时不时要等新任务过来。这种等待从报告上看是“空闲”但实际上是因为Host侧下发速度不够典型的“喂不饱”问题优化方向在调度和任务下发路径上。4.2 真正需要警惕的三种低利用率相对应的真正需要动手优化的低利用率有比较明确的特征。算完等数据AI Core空闲时段有明显规律性且与某个算子的结束时间强相关。比如Conv算完后总要等几百微秒数据才能开始下一个计算说明数据搬运路径有瓶颈。优化思路是提前预取数据或者调整算子切分方式让搬运和计算重叠。算完等同步多算子之间存在强同步依赖后面的算子必须等前面的全部算完才能开始。这种情况在报告里会表现为一个算子的结束时间和下一个算子的开始时间之间存在明显间隔。优化思路是用多流并行化掉无依赖关系的算子减少同步点。算完干等锁整机空闲占比很高但任务并没有在等待数据而是在等Host侧的锁或者事件通知。这种情况通常和框架层的调度机制有关单个算子优化已经解决不了问题需要从框架层面去看。5. 当利用率真的偏低从这三个方向去查5.1 方向一算子耗时TopN和等待归因先看汇总报告里的算子耗时TopN重点不是看“谁最慢”而是看“谁在等”。msprof的算子统计里通常能看到每个算子的执行时间、等待时间和等待原因。比如一个矩阵乘算子计算时间只有50微秒但总耗时300微秒多出来的250微秒在干什么是等待数据就绪还是等待前面算子的结果这个归因信息是判断瓶颈在哪一步的最重要依据。我一般按这个逻辑去排查把耗时前20的算子列出来看它们的计算时间占比。计算时间低、等待时间高的算子标记为“等待型瓶颈”。等待型瓶颈如果集中在数据搬运环节优先优化数据流集中在同步环节优先优化并行策略。5.2 方向二数据搬运与计算的重叠程度AI Core利用率偏低很大一部分原因可以归结为数据搬运和计算没有充分重叠。CANN的算子执行流水线在理想情况下是这样的计算单元在执行第N个算子时数据搬运单元同时在搬运第N1个算子所需的数据指令下发单元在准备第N2个算子。三层并行利用率才能上去。msprof报告里如果显示搬运耗时占比很高而AI Core利用率又低那就说明流水线没有建立起来。实践中我通常会做两件事检查算子的数据输入是否在计算开始前就已经预取到片上缓存如果没有试试用流式数据预取的方式把搬运提前。检查是否存在因为中间结果写回DDR又读回来的情况如果在的话试着用算子融合把中间结果留在片上缓存里避免反复搬运。这两步做完很多场景下利用率能直接提升20个百分点以上。5.3 方向三AI Core内部的单元使用情况msprof还可以拆分到AI Core内部的执行单元使用率比如矩阵计算单元和向量计算单元的忙闲比例。这一点容易被忽略但非常关键。如果一个模型里全是卷积和矩阵乘法AI Core的矩阵单元会忙到起飞向量单元基本闲着这很正常。但如果你的模型里向量运算占大头矩阵单元利用率很低说明模型结构本身的算子构成以逐元素计算为主这类场景优化时应该先把能转成矩阵运算的逻辑转过去而不是去抠某个算子的实现细节。我在处理一个NLP模型时就遇到过类似问题——报告显示矩阵单元利用率只有个位数但AI Core整体利用率还挺高。仔细看算子构成才知道大量时间耗在了LayerNorm这类逐元素算子上。后来把LayerNorm和前面的矩阵乘做了算子融合端到端性能直接提升了将近一倍。6. 实际项目中msprof报告的三个陷阱6.1 只抓一次采集就下结论性能数据是有波动的。尤其是推理场景网络抖动、系统定时任务、其他进程抢占CPU都会直接影响当次采集的结果。我通常至少采集三次取中位数或者看分布才敢判断真实水平。如果三次结果离散度特别大优先找外部干扰因素而不是急着优化算子。6.2 漏看Host侧瓶颈很多人只盯着加速卡侧的数据忽略了Host侧的任务下发耗时。msprof的总体耗时统计里包含Host侧的任务下发和同步等待当这个占比偏高时说明瓶颈其实在CPU侧加更多加速卡也解决不了问题。这种场景下优化方向是减少算子下发次数——也就是做算子融合把多个小算子的下发合并成一次或者用多线程异步下发让Host侧的准备工作和计算重叠起来。6.3 小算子的“隐形耗时”被掩盖msprof的报告会根据算子类型聚合统计但很多小算子的耗时是分散的。单个看都不起眼加起来却成了大头。我习惯把耗时排名靠后的算子做一次累加看看这一类小算子总共占了多少时间。如果占比超过15%它们对整体性能的影响就已经值得动手了。聚合小算子的手段很明确能融合就融合能改写成一整个大算子就改写。CANN这边有提供算子融合的接口和最佳实践翻译成普通开发者能理解的话就是——减少“计算单元启动”和“数据跑腿”的次数很多小算子的开销其实不是算出来的是启动出来的。7. 把msprof放进日常开发流程性能优化这件事最容易犯的错是等到性能问题爆发了才想起来做分析。我更推荐把msprof的利用率分析做成日常流程的一部分。做法很简单在模型的自动化评测脚本里加一步每次跑完benchmark之后自动执行msprof采集解析报告里的AI Core利用率、搬运耗占比、TopN算子耗时落到一个固定格式的Excel或者表格里。这样每次代码改动后性能指标的变化趋势一目了然谁把利用率改好了、谁把搬运路径搞砸了都很直观。我现在带着团队做算子开发时会把利用率数据直接写到PR描述里要求每个涉及性能改动的PR附上改动前后的对比数据。这个习惯一旦养成性能问题的发现时间会大幅提前很多优化空间在编码阶段就被发现了比上线前再排查效率高得多。最后分享一个小经验msprof的report看多了之后你会慢慢建立起一种“性能直觉”——看到某个模型的架构、算子的排列方式就能大致猜到利用率瓶颈在哪里。这种直觉没什么技术含量纯粹是靠反复看真实数据积累出来的。所以如果你刚开始接触CANN生态不要怕麻烦每次性能调优都跑一轮msprof把数据和你的直觉对照起来用不了多久你对“算力到底去哪儿了”这个问题就会有非常准确的判断。
返回列表