2. 推理性能指标

各位同学,今天我们来聊聊NPU推理性能的四个核心指标。说实话,这玩意儿就像汽车的仪表盘——你不看它,车也能开,但什么时候爆缸了你都不知道。我在调优NPU的这些年,见过太多人一上来就堆算子、改模型,结果性能纹丝不动。为什么?因为你连瓶颈在哪都没搞清楚。

吞吐量(Throughput)——你到底能处理多少活儿?

吞吐量,说白了就是单位时间内能处理多少个请求。比如你的NPU一秒能跑100张图片,那吞吐量就是100 FPS(Frames Per Second)。

计算公式很简单:

Throughput = 总处理样本数 / 总耗时

我个人习惯用batch size来调吞吐量。你想想看,单张图片跑一次推理,和一次塞进去32张图片跑推理,哪个吞吐量高?当然是后者。但这里有个坑——batch size不是越大越好。

关键点:当batch size超过某个阈值,NPU的算力利用率会饱和,再增加batch size只会增加延迟,吞吐量反而上不去。

我在项目中遇到过这样一个案例:某视觉模型,batch size从1调到32,吞吐量提升了5倍;但从32调到64,只提升了10%。这时候就该停了,因为内存带宽已经成了新瓶颈。

延迟(Latency)——用户等得起吗?

延迟,就是单个请求从进来到出去花了多久。注意,这里说的是端到端延迟,包括数据搬运、预处理、推理、后处理。

吞吐量和延迟,其实是跷跷板的两头。你追求高吞吐,就得攒一批请求一起处理,那单个请求的延迟自然就高了。反过来,你想让每个请求秒回,那就得牺牲吞吐量。

我的建议:在线服务(比如人脸识别门禁)优先保延迟,离线批处理(比如视频分析)优先保吞吐量。别搞反了。

我曾经踩过一个坑:为了压延迟,把batch size设成1,结果NPU利用率只有5%,白白浪费算力。后来改成动态batch,根据当前排队请求数自动调整,才平衡了延迟和吞吐。

算力利用率(Utilization)——你的NPU在摸鱼吗?

算力利用率,就是NPU实际干活的时间占比。理想情况下,NPU应该一直满负荷运转。但现实是,它经常在等数据。

利用率低的原因通常有两个:

  • 数据搬运瓶颈:数据从DDR搬到NPU片上存储的速度跟不上计算速度
  • 算子调度开销:小算子太多,启动和同步的时间比计算还长

我记得有一次调一个NLP模型,NPU利用率只有20%。查了半天,发现是LayerNorm这个小算子被反复调用,每次都要等数据从DDR搬过来。后来我把多个LayerNorm合并成一个,利用率直接飙到70%。

注意:利用率不是越高越好。如果利用率接近100%,说明NPU已经满负荷,这时候再优化算子也没用,得从算法层面下手。

内存带宽瓶颈识别——数据到底卡在哪?

这是最容易被忽视的指标。很多同学一看NPU利用率低,就以为是算子没写好,其实往往是内存带宽不够。

怎么识别?看计算密度(Arithmetic Intensity):

计算密度 = 计算量(FLOPs) / 数据访问量(Bytes)

如果计算密度低,说明模型是带宽敏感型,优化方向应该是减少数据搬运,而不是优化算子。

我常用的诊断方法:

  1. 跑一次推理,记录NPU的计算时间和数据搬运时间
  2. 如果数据搬运时间占比超过50%,基本可以断定是带宽瓶颈
  3. 用Roofline模型画图,看看当前操作落在哪个区域

实战技巧:我曾经优化一个3D卷积模型,发现计算密度只有0.5 FLOPs/Byte。这意味着NPU每算一次,就要搬2个Byte的数据。后来我把多个卷积层做算子融合,让中间结果留在片上,数据搬运量减少了60%,推理速度直接翻倍。

四个指标的关系——一张图看懂

下面这张图是我自己总结的,把四个指标串起来了。你仔细看,就能明白它们之间的制约关系。

NPU推理性能四维分析框架 吞吐量 (Throughput) 单位时间处理样本数 受batch size和算力影响 优化方向:增大batch、算子融合 延迟 (Latency) 单次请求端到端耗时 受数据搬运和算子调度影响 优化方向:减少搬运、算子并行 算力利用率 (Utilization) NPU实际计算时间占比 受数据搬运和算子效率影响 优化方向:减少等待、提高并行度 内存带宽瓶颈 数据搬运速度限制计算速度 通过计算密度识别 优化方向:算子融合、数据复用 跷跷板关系 影响 影响 共同制约 四个指标互相制约,优化时需找到当前最短板

你看,吞吐量和延迟是跷跷板,算力利用率和内存带宽是底层制约因素。我每次拿到一个新模型,第一件事就是跑这四个指标,看看哪个是短板。说白了,瓶颈永远只有一个,找到它,干掉它,再找下一个。

实战:如何快速定位瓶颈?

给你一个我常用的三步法:

步骤 操作 判断依据
1 跑一次推理,记录总耗时 如果延迟远高于预期,进入下一步
2 查看NPU利用率 利用率低 → 数据搬运或算子调度问题
利用率高 → 算力或带宽饱和
3 计算计算密度 密度低 → 带宽瓶颈
密度高 → 算力瓶颈

小技巧:如果你手头没有profiling工具,可以手动插桩——在推理前后加时间戳,分别统计数据搬运时间和计算时间。虽然粗糙,但够用。

嗯,今天就先讲到这里。这四个指标是NPU性能优化的基石,后面的所有技巧都是围绕它们展开的。你先把这张图刻在脑子里,下次调优的时候,就知道该往哪个方向使劲了。