064、NPU的ResNet加速:残差块的硬件映射
064、NPU的ResNet加速:残差块的硬件映射
去年做一款边缘AI芯片的驱动适配时,遇到一个诡异的精度问题。ResNet-50在PC端跑FP32推理,top-1准确率76.1%,移植到NPU上直接掉到68.3%。排查了三天,最后发现是残差连接的加法操作在硬件上被优化成了“先截断再相加”——NPU的MAC阵列对中间特征图做了8bit量化,但残差路径和主路径的量化参数不一致,导致加法时精度崩塌。这个坑让我意识到,ResNet在NPU上的加速远不是“把卷积映射过去就完事”那么简单。
残差块的“反直觉”硬件开销
ResNet的核心创新是残差学习,但站在NPU架构师的角度看,残差块引入了一个非常“反直觉”的问题:计算量没增加多少,数据搬运量却翻倍了。
一个标准卷积层,输入特征图经过MAC阵列计算,输出直接写回DDR。残差块呢?主路径做完卷积,还得等旁路的数据过来做加法。这意味着NPU的片上SRAM必须同时缓存两份特征图——主路径的中间结果和残差路径的直连数据。以ResNet-50的bottleneck结构为例,输入是56x56x256,主路径经过1x1、3x3、1x1三个卷积,输出56x56x256。残差路径直接是恒等映射。加法操作需要从SRAM中读取两份256通道的特征图,计算完再写回。
我见过一个团队在FPGA上实现ResNet-18,他们天真地把每个卷积层单独映射到MAC阵列,结果发现残差加法时DDR带宽被撑爆了——因为MAC阵列算完主路径后,残差数据还在DDR里躺着,每次加法都要从片外搬数据。残差块加速的第一要义,是让残差数据“赖”在片上不走
