1. 从一张"看不懂"的监控截图说起
第一次在昇腾服务器上敲下npu-smi info的时候,我盯着满屏的表格愣了好一会儿。左边一列是 NPU 编号,右边跟着一堆HBM、AICore、Chip、Health、Power、Temp之类的字段,数字密密麻麻,看着像那么回事,但真要我判断"这块卡现在到底健不健康、有没有在干活、瓶颈在哪",说实话心里没底。
后来带团队做推理服务压测,问题就来了:业务侧反馈吞吐上不去,日志里也没报错,模型加载正常,进程也活着。这时候能救命的只有npu-smi info——它相当于昇腾 NPU 的"体检报告单",把芯片利用率、显存占用、功耗、温度、健康状态一次性摊在你面前。问题是,这张报告单你得会读。读错了,你会把"正常待机"当成"卡死了",也会把"显存泄漏"当成"业务量太大"。
这篇内容就是把我这几年在昇腾环境里读npu-smi info的经验完整拆一遍。它适合刚接触昇腾 NPU 的算法工程师、负责推理服务运维的 SRE、以及做国产化算力适配的开发者。核心就一件事:把npu-smi info每一列指标的含义、正常范围、异常特征、以及它和真实业务性能之间的对应关系讲透,让你下次看到这张表,能像看自己体检报告一样一眼抓住重点。
需要先说明一点:npu-smi是昇腾提供的一套命令行管理工具,info只是它众多子命令中的一个,负责输出设备与芯片的实时状态快照。它不依赖任何额外的监控组件,装好驱动和固件就能用,这也是它成为排查第一入口的原因。下面所有内容都围绕这个命令展开,涉及的具体数值范围基于常见昇腾型号的公开资料和实际观察,不同型号、不同固件版本会有差异,请以你手头设备的实际表现为准。
2. npu-smi info 到底打印了什么
2.1 输出结构:三层信息从粗到细
npu-smi info的输出不是一张表,而是分区块的。理解它的结构比记住某个数字更重要。典型输出大致分三块:
第一块是设备级概览,通常以NPU为行标识,给出每张卡的编号、健康状态、功耗、温度、以及整体资源占用。这一块回答的是"这张卡活着吗、烫不烫、费不费电"。
第二块是芯片级明细,以Chip为行标识,把一张卡上的多个芯片(比如昇腾 910 系列一颗封装里可能有多个 die)分别列出,给出AICore利用率、HBM使用率等更细的指标。这一块回答的是"算力用起来了吗、显存够不够"。
第三块是进程级信息,通过npu-smi info -t proc-mem之类的子参数可以拉出每个进程占用的显存。这一块回答的是"到底是谁在吃显存"。
很多人只盯着第一块看,觉得"卡在、温度正常"就万事大吉,结果显存被某个僵尸进程占满,新任务死活起不来。所以读这张表,必须三层一起看。
2.2 为什么是这些指标而不是别的
你可能会问,为什么npu-smi info偏偏选了 AICore、HBM、功耗、温度这几个维度?这背后是 NPU 的工作模型决定的。
NPU 和 CPU 最大的区别在于它是数据流驱动的:大量矩阵乘加运算在 AICore(AI 计算核心)里并行跑,而支撑这种高并发计算的是 HBM(高带宽显存),它负责把权重和激活值以极高带宽喂给计算单元。所以:
- AICore 利用率反映"计算单元忙不忙",是算力是否被榨干的核心指标;
- HBM 使用率反映"显存够不够",直接决定你能开多大 batch、能不能多实例共存;
- 功耗和温度是这两个高密度部件工作的副产品,也是稳定性的先行指标。
换句话说,这四个指标构成了一个闭环:算力在跑 → 吃显存 → 发热耗电。任何一个环节异常,都会在另外几个上留下痕迹。理解了这层因果,你读表就不是死记数字,而是顺着逻辑推。
2.3 一个容易被忽略的前提:驱动与固件版本
在解读任何指标之前,先确认一件事:npu-smi的输出版本和你的驱动、固件版本是匹配的。不同版本的npu-smi字段名和排列顺序会有微调,比如早期版本可能把某些信息合并显示,新版本拆得更细。
实操建议:拿到一台新机器,先跑npu-smi info看能不能正常出表,再跑npu-smi -v看工具版本,对照官方文档确认字段含义。如果npu-smi info直接报错或者输出残缺,八成是驱动没装好或者设备没被识别,这时候纠结指标没意义,先把环境弄干净。
提示:
npu-smi info是快照式输出,执行一次打印一次。想看连续变化,得配合watch或者写脚本循环采集,这一点后面会专门讲。
3. 逐列拆解:每个数字背后的含义与正常区间
3.1 NPU 编号与 Health:先确认"人在不在"
输出最左边通常是NPU编号,从 0 开始递增。多卡机器上,这个编号就是你后续指定设备时用的 ID,比如ASCEND_RT_VISIBLE_DEVICES=0,1里的 0 和 1 就对应这里。
紧挨着的是Health字段,一般显示OK或Alarm、Warning之类。这是第一优先级要看的字段。如果这里不是 OK,后面所有性能指标都不用看了,先处理硬件告警。常见的非 OK 状态包括温度过高触发降频、ECC 显存错误累积、供电异常等。
我踩过的一个坑:有次压测中途吞吐突然掉一半,npu-smi info里 Health 显示Warning,但业务日志毫无异常。后来查出来是某颗芯片温度触顶,硬件自动降频保护。如果当时只看 AICore 利用率(它确实降了),很容易误判成"业务代码效率低",方向就全错了。Health 是总开关,先看它。
3.2 AICore 利用率:算力到底用了几成
AICore这一列(有的版本叫AICore(%)或Utilization)是大家最关心的。它表示在采样周期内,AI 计算核心处于忙碌状态的时间占比。
正常区间怎么理解?分场景:
| 场景 | AICore 典型值 | 说明 |
|---|---|---|
| 空闲待机 | 0% ~ 5% | 没有任务,或任务在 CPU 侧准备数据 |
| 推理服务正常 | 40% ~ 80% | 有稳定请求,计算与数据搬运交替 |
| 训练/压测满载 | 85% ~ 99% | 计算密集,接近算力上限 |
| 长期 100% | 需警惕 | 可能是死循环或异常任务占满 |
这里有个反直觉的点:AICore 不是越高越好。推理场景下,如果它长期贴着 100%,往往说明数据预处理(在 CPU 上做)跟不上,或者 batch 设置不合理导致计算单元空转等待。真正健康的推理服务,AICore 应该在一个区间内波动,而不是钉死在顶部。
另一个坑:npu-smi info的 AICore 是瞬时采样值,不是累计平均值。你执行命令那一瞬间它可能正好在等数据,显示 20%,但实际平均利用率有 70%。所以单次采样不可信,必须连续看。我一般会watch -n 1 npu-smi info盯上一两分钟,看它的波动形态。
3.3 HBM 使用率:显存是硬约束
HBM这一列(可能显示为HBM-Usage或Memory-Usage)给出显存已用容量和总量,通常格式是已用 / 总量,单位 MB 或 GB。
显存是 NPU 上最刚性的资源,因为它不像 CPU 内存可以 swap。一旦 HBM 打满,新任务直接 OOM 失败,没有任何缓冲余地。所以这一列要重点盯两个东西:
- 绝对值:还剩多少余量。如果余量低于模型单次推理的峰值需求,随时可能崩。
- 增长趋势:是不是在缓慢爬升。稳定服务的显存占用应该是平的,如果看到它像楼梯一样一级级往上走,基本可以判定显存泄漏。
显存泄漏是推理服务里最阴险的问题之一。它不会立刻报错,而是跑几个小时甚至几天后突然 OOM。定位方法就是定期采集npu-smi info的 HBM 数值,画成曲线。一旦发现单调上升,再配合npu-smi info -t proc-mem找到具体是哪个进程在涨,问题就锁定了。
3.4 功耗与温度:稳定性的先行指标
Power(功耗,单位 W)和Temp(温度,单位 ℃)这两列经常被忽略,但它们是最早发出预警的信号。
功耗方面,昇腾 NPU 有明确的 TDP(热设计功耗)上限。正常满载时功耗会接近但不超过这个值。如果发现功耗异常低(比如满载任务下只有标称的一半),可能是芯片被降频了,原因通常是温度或供电。如果功耗异常高且波动剧烈,要排查是不是有异常任务在反复申请释放资源。
温度方面,一般芯片结温在 80℃ 以下算安全,超过 85℃ 就要警惕,接近 90℃ 硬件会主动降频。温度问题往往是环境问题:机箱风道堵塞、机房空调故障、相邻卡互相烘烤。我遇到过一台 8 卡服务器,中间两张卡温度比边缘高 15℃,原因是风道设计导致中间散热差,最后靠调整卡的排布和加导风罩解决。
把功耗和温度、AICore 放一起看,能推出很多结论。比如 AICore 高但功耗低,可能是降频;AICore 低但温度高,可能是散热坏了或者有别的热源。
3.5 一张速查表:指标、正常范围与异常含义
为了让你现场排查时能快速对照,我把核心指标整理成下面这张表。再次强调,具体数值因型号而异,这里给的是经验区间。
| 指标 | 正常范围 | 异常表现 | 可能原因 |
|---|---|---|---|
| Health | OK | Alarm/Warning | 温度、ECC、供电异常 |
| AICore | 场景相关,40%~99% | 长期 0% 或长期 100% | 任务未启动 / 数据瓶颈或死循环 |
| HBM | 有余量且平稳 | 接近满载或持续上升 | batch 过大 / 显存泄漏 |
| Power | 接近但不超过 TDP | 异常低或剧烈波动 | 降频 / 异常任务 |
| Temp | < 85℃ | > 85℃ 并持续 | 散热问题 |
这张表建议截图存手机里,现场排查时比翻文档快得多。
4. 把静态快照变成动态监控
4.1 为什么单次 npu-smi info 会骗你
前面反复提到"单次采样不可信",这里展开说清楚原因。
npu-smi info打印的是执行那一瞬间的状态。而 NPU 上的负载是高度动态的:一个推理请求进来,数据从 Host 搬到 Device,AICore 开始算,算完结果搬回去,这中间 AICore 有大量时间在等数据。你随机采样,可能正好采到等待期,看到 10%;也可能采到计算期,看到 95%。同一个健康服务,两次采样能差出十倍。
所以判断一个服务是否健康,靠的是一段时间的统计特征,而不是某个点。具体要看:均值、峰值、波动幅度、以及趋势。这些都得靠连续采集才能得到。
4.2 用 watch 做快速观察
最简单的动态观察方式就是watch:
watch -n 1 npu-smi info这会让命令每秒刷新一次,你盯着看一两分钟,就能对波动形态有个直观感受。适合快速判断"这卡到底在不在干活"。
但watch有个缺点:它把整张表刷来刷去,你很难对比历史值。而且它不落盘,看完就没了。所以它只适合临时快速观察,不适合长期监控。
4.3 写脚本采集时序数据
要做真正的监控,得把数据采下来存起来。npu-smi info支持一些机器可读的输出格式(具体参数因版本而异,常见的有指定输出字段的选项),可以配合脚本解析。
思路是这样的:定时执行npu-smi info,把关键字段(NPU 编号、AICore、HBM、Power、Temp)抽出来,带上时间戳写进日志或时序数据库。伪代码大概长这样:
while true; do timestamp=$(date '+%Y-%m-%d %H:%M:%S') # 解析 npu-smi info 输出,提取关键字段 # 具体解析逻辑依赖你的 npu-smi 版本和输出格式 echo "$timestamp, $npu_id, $aicore, $hbm, $power, $temp" >> npu_metrics.log sleep 5 done采集频率建议 5 到 10 秒一次。太密了日志膨胀快,太疏了抓不到瞬时尖峰。5 秒是个比较平衡的值。
采下来的数据可以喂给 Prometheus + Grafana 这类通用监控栈,也可以先用最简单的文本 + 脚本画图。关键不是工具多高级,而是你得有历史数据可回溯。出问题时能翻出过去几小时的曲线,定位效率完全不是一个量级。
4.4 采集时容易踩的三个坑
第一个坑:采集脚本本身消耗资源。如果采集频率过高、解析逻辑太重,脚本自己会占 CPU,间接影响业务。所以解析逻辑要轻,能用 shell 就别上重型语言。
第二个坑:多卡机器上字段错位。多卡输出里每张卡占几行,解析时如果按固定行号取,一旦某张卡状态变化导致行数变化,就会错位。稳妥做法是按 NPU 编号做锚点解析,而不是按行号。
第三个坑:忽略时间同步。如果采集脚本跑在多台机器上,时间没同步,事后对齐曲线时会发现对不上。上 NTP 是基本操作。
5. 从指标异常到根因:几条实战排查链路
5.1 吞吐上不去,AICore 却不高
这是最典型的"看起来没瓶颈其实有瓶颈"的场景。业务反馈 QPS 上不去,你一看 AICore 只有 30%,第一反应可能是"算力没用满,加并发"。但加了并发还是上不去,为什么?
因为瓶颈不在 NPU,而在数据供给。NPU 算得再快,数据从 CPU 内存搬到 HBM 的速度跟不上,AICore 就得饿着。这时候 AICore 低是结果,不是原因。
排查链路:先看 AICore 波动形态,如果是"高一下、低很久"的锯齿状,基本确认是数据搬运瓶颈。然后去查 Host 侧的预处理代码——是不是在做耗时的图像解码、tokenize、或者同步 IO。优化方向是把预处理并行化、用更高效的库、或者做数据预取。
我做过一个图像推理服务,AICore 死活上不去,最后发现是 Python 的 PIL 解码成了瓶颈,换成更快的解码库后 AICore 直接从 30% 拉到 70%,QPS 翻倍。NPU 监控指标低,不代表 NPU 是瓶颈,这点一定要记住。
5.2 显存缓慢上涨,服务几天后 OOM
前面提过显存泄漏,这里给完整排查链路。
第一步,确认是泄漏而不是正常波动。正常服务的 HBM 占用应该是平的,有小的起伏但不会单调上升。采集几小时数据画曲线,如果斜率稳定为正,基本确认泄漏。
第二步,定位进程。用npu-smi info -t proc-mem拉出每个进程的显存占用,对比不同时间点,看是哪个进程在涨。
第三步,定位代码。常见泄漏点包括:推理框架的缓存没清理、动态 shape 导致反复申请显存、异常分支里忘了释放 tensor。昇腾的框架一般有显存池机制,如果池子配置不当,也会表现为"占用只增不减"。
第四步,验证修复。改完后重新压测,盯 HBM 曲线至少跑够原来出问题的时间长度,确认平稳才算修好。
5.3 温度告警引发的性能雪崩
温度问题的特点是连锁反应:温度升高 → 硬件降频 → AICore 利用率下降 → 业务吞吐下降 → 但业务侧只看到"变慢了",看不到温度。
排查链路:先看npu-smi info的 Temp 和 Health。如果 Temp 偏高且 Health 有告警,基本锁定。然后查环境:机房温度、机箱风道、风扇转速、相邻卡温度。很多时候不是单卡问题,而是整机散热设计问题。
处理方式分两层:短期可以限制负载、错峰调度;长期要解决散热,比如调整卡间距、加导风罩、改善机房空调。温度问题不解决,性能永远上不去,而且会缩短硬件寿命。
5.4 功耗异常:被忽视的线索
功耗异常有两种典型表现。一种是满载任务下功耗偏低,说明芯片没跑满,可能被降频了,去查温度和供电。另一种是空闲时功耗偏高,说明有后台任务在偷偷跑,去查进程列表。
功耗这个指标单独看意义不大,但和 AICore、Temp 组合看,能快速区分"真忙"和"假忙"。真忙是 AICore 高、功耗高、温度高;假忙是 AICore 高但功耗低(降频),或者 AICore 低但功耗高(异常任务)。
6. 几个只有踩过才知道的细节
6.1 多芯片封装下的"卡"与"芯片"不是一回事
昇腾有些型号一颗封装里有多个芯片(die),npu-smi info会分别列出。这时候"一张卡"和"一个计算单元"不是一一对应的。做资源调度时如果按卡分配,可能出现一张卡里某个芯片满载、另一个空闲的情况,利用率统计也会失真。
实操建议:调度粒度尽量细到芯片级,监控时也按芯片维度采集,别只看卡级平均。卡级平均会把芯片间的不均衡掩盖掉。
6.2 容器环境里的可见性问题
在容器里跑npu-smi info,看到的可能是宿主机全部设备,也可能是被限制后的子集,取决于容器怎么挂载设备。如果发现容器里看到的卡数和预期不符,先查设备挂载配置,别急着怀疑驱动。
另外,容器里跑npu-smi有时需要额外的权限或挂载/dev下的设备节点。这些环境配置问题会伪装成"监控工具坏了",实际是权限没给够。
6.3 采样时机对判断的影响
前面说过单次采样不可信,这里补充一个细节:采样时机要避开业务启动和停止的瞬间。服务刚启动时,模型加载会瞬间吃满显存和算力,这时候采样会看到异常高的值;服务停止时,资源释放又会让指标骤降。这些瞬态不代表稳态性能。
判断稳态性能,要在服务跑稳之后、持续压测期间采样。我一般会等服务起来后先跑 5 分钟预热,再开始正式采集。
6.4 别把 npu-smi 当唯一真相
npu-smi info很强,但它只是硬件视角。业务性能问题可能出在框架层、通信层、甚至网络层。NPU 指标正常不代表服务没问题,NPU 指标异常也不一定就是 NPU 的锅。
正确的姿势是把 NPU 指标和业务指标、系统指标放一起看。NPU 的 AICore 对应业务的 QPS,NPU 的 HBM 对应框架的显存日志,NPU 的 Temp 对应机房的温度监控。多源数据交叉验证,才能快速定位真正的根因。
7. 我个人的使用习惯
最后分享几个我日常用下来觉得最省事的习惯。
第一,新机器上手先跑一遍基线。空载状态下把npu-smi info的输出存一份,记下空闲时的功耗、温度、显存占用。以后任何异常,先和基线比,差异一目了然。
第二,压测时必开连续采集。不管问题最后出在哪,有历史曲线在手,排查至少省一半时间。我现在的习惯是任何压测都挂一个采集脚本,数据留着,哪怕当时没问题,事后复盘也用得上。
第三,Health 字段永远第一个看。养成肌肉记忆,看到非 OK 就先处理硬件,别在软件层瞎折腾。
第四,温度问题优先怀疑环境。芯片本身很少无缘无故过热,八成是散热环境的问题。先查机房、查风道,比查代码快得多。
npu-smi info这个命令看着简单,但真把它读透,能省下大量"盲猜"的时间。它给的是硬件最原始的信号,而排查问题的本质,就是把这些原始信号翻译成业务语言。翻译得越准,定位越快。这套东西没有捷径,就是多看、多采、多对比,看多了自然就有感觉了。