155、NPU的编译器开发:Profiling与PGO(Profile-Guided Optimization) NPU的编译器开发:Profiling与PGO(Profile-Guided Optimization)去年调一个端侧人脸检测模型,在RK3588的NPU上跑,量化后精度掉得不多,但推理延迟死活压不到目标帧率。看NPU的profiling报告,发现某个卷积层占用了40%的cycle,但明明这个层的计算量只有全模型的15%。当时盯着报告看了半小时,突然意识到——NPU的硬件调度器对某些tensor shape有“偏好”,而编译器默认的调度策略完全没考虑这个偏好。后来手动改了编译器的cost model,把那个层的tiling策略从4x4改成8x2,延迟直接降了18%。这就是Profiling和PGO的价值——让编译器学会“看人下菜碟”。为什么NPU编译器需要ProfilingCPU和GPU的编译器优化已经相当成熟,LLVM的PGO能根据运行时的分支概率做内联和布局优化。但NPU的情况完全不同——NPU的硬件架构千奇百怪,有的有专用的Winograd加速器,有的对depthwise卷积有特殊的数据通路,有的MAC阵列只能处理特定维度的tensor。编译器如果不知道这些硬件特性,生成的指令序列就是“盲人摸象”。更麻烦的是,NPU的硬件行为高度依赖数据。同样的卷积层,输入feature map的数值分布不同,NPU内部的激活值稀疏度可能差一个数量级。而稀疏度直接影响NPU的零值跳过(zero-skipping)效率。没有profiling,编译器只能按最坏情况做调度,性能自然上不去。