170、NPU的编译器开发:调试与日志系统

📅 2026/7/28 22:46:18
170、NPU的编译器开发:调试与日志系统
NPU的编译器开发:调试与日志系统去年夏天,我在调试某款自研NPU的编译器时,遇到一个极其隐蔽的bug——模型推理结果在特定输入下会随机出现1%的精度损失。这个bug在仿真环境里完全复现不了,一上FPGA就冒出来。我花了整整两周,最后发现是编译器在生成DMA指令时,对tensor的地址对齐处理出了偏差,而日志系统里打印的地址信息被我默认忽略了,因为“看起来都差不多”。从那以后,我彻底重构了NPU编译器的调试和日志体系。今天聊聊这个过程中积累的经验。调试NPU编译器的特殊难点NPU编译器跟普通CPU编译器有个本质区别:你生成的不是可执行文件,而是一堆指令序列和数据配置,最终要在硬件上跑。这意味着传统的gdb断点调试基本用不上——你没法在NPU的指令流里设断点。更麻烦的是,NPU的并行计算特性让状态空间爆炸。一个卷积层可能同时有几十个PE(处理单元)在工作,每个PE内部还有多级流水线。当输出结果不对时,你根本不知道是哪个环节出了问题:是指令调度顺序错了?是数据地址算偏了?还是硬件本身有bug?我见过最离谱的情况:一个同事调试了三个月,最后发现是编译器生成的权重重排指令和硬件实际支持的格式差了1个bit。这个bug在日志里完全看不出来,因为日志只打印了“权重加载完成”这种废话。日志系统的分层设计:别把所有信息都塞进一个文件NPU编译器的日志不能像普通软件那样只分info/warning/error。我现在的做法是分四个层级,每个层级对应不同的调试场景:第一层:指令流日志