开源一个能在 ZYBO7010 上跑通 KWS 闭环的 TinyML NPU

开源一个能在 ZYBO7010 上跑通 KWS 闭环的 TinyML NPU
最近我把毕业设计中的 NPU 部分整理成了一个开源项目TinyML_NPU。项目地址TinyML_NPU GitHub 仓库TinyML_NPU v0.1.0 Release后续我又把围绕这个 NPU 搭起来的 SoC 和 Tang Primer 25K 实时 KWS demo 单独整理成了另一个项目TinyML_SOC 项目介绍TinyML_SOC GitHub 仓库这篇文章只介绍TinyML_NPU本身。TinyML_NPU 的核心加速器叫VenusCore它是一个面向研究和教学的 INT8 TinyML NPU 参考实现目前已经在原版 DigilentZybo / XC7Z010上跑通 KWS testvector 闭环。它不是商用 IP也不是通用 ONNX Runtime。它的定位是把 compiler、uOP、参数布局、SpinalHDL RTL、Zynq PS 固件和 FPGA 板级验证串起来形成一个可以拆开学习的 TinyML NPU 工程。1. 项目基本规格项目v0.1.0 配置项目名TinyML_NPUNPU 核心VenusCoreFPGA 板卡Digilent ZyboFPGA 器件XC7Z010PL 时钟50 MHzCluster1Lanes4SIMD per lane4Activation / Weightsigned INT8AccumulatorINT32控制接口APB3DMA 接口AHB-LitePS/PL 共享存储128 KiB BRAMRTL 语言SpinalHDL软件侧Python compiler bare-metal Zynq PS firmwareLicenseApache-2.0当前数据通路是1 cluster x 4 lanes x SIMD4也就是每个 cycle 最多提供 16 个 INT8 乘法槽。这个结构适合教学型 TinyML 网络不适合大模型或高吞吐通用推理。2. 支持的算子TinyML_NPU v0.1.0 支持的是一个受约束的 INT8 算子集合。算子IR / compilerVenusCore v0.1 RTLZYBO7010 KWS 覆盖Conv 3x3支持支持是Pointwise Conv 1x1支持支持是Depthwise Conv 3x3, multiplier1支持支持是AveragePool 2x2 / 3x3支持支持是MaxPool编码与约束支持支持否Fully Connected / MatMul可规范化为 1x1 路径ISA 保留 opcode否Add / Concatplan 可表示 CPU fallbackNPU 不执行否这里的“支持”不是指任意 ONNX 模型、任意 shape、任意广播规则都能跑而是指在当前 compiler 和硬件约束内可以生成 uOP并由 RTL 正确执行。主要约束包括输入、权重、输出为 signed INT8内部累加为 INT32activation 布局为 NCHWc4Conv stride 支持 1 或 2padding 每边当前覆盖 0 或 1Depthwise Conv 当前覆盖 multiplier1单个 IBUF 行 compiler 保守限制为 3840 bytesWBUF 总容量为 8 KiBshared BRAM 只有 128 KiB所以它更适合研究“一个受约束 TinyML NPU 如何完整跑起来”而不是作为通用推理框架使用。3. 板级验证结果v0.1.0 在 ZYBO7010 上跑的是 KWS testvector不是空壳寄存器测试。测试集信息项目数值KWS 样本数120类别数12每类样本10uOP 数44NPU version0x0005000012 个类别为yes, no, up, down, left, right, on, off, stop, go, noise, silence板级结果指标结果samples120label accuracy117 / 120 97.50%reference top1 match120 / 120 100.00%max INT8 abs error0total INT8 byte mismatches0resultPASS输出示例TINYML_NPU_VERSION0x00050000 TINYML_NPU_RESULT code0 ... samples120 label_correct117 ref_top1_match120 max_abs_error0 TINYML_NPU_BOARD_PASS这里有两个口径label accuracy117/120硬件输出 top1 和真实 label 一致的比例reference top1 match120/120硬件 top1 和 VenusCore reference logits 的 top1 完全一致也就是说硬件执行结果和参考实现一致117/120 反映的是该固定 KWS testvector 上模型本身的分类结果。4. 性能与资源Vivado 2021.1 post-route 结果如下项目结果FPGAXC7Z010PL clock50 MHzWNS3.025 nsUnrouted / partial nets0 / 0Unconstrained internal endpoints0LUT7,328FF / Registers6,738BRAM tiles42DSP7NPU active-cycle 结果项目结果单样本 active cycles563,188120 样本 active cycles67,582,560单样本 active-cycle equivalent11.26376 ms 50 MHz120 样本 active-cycle equivalent1351.6512 ms 50 MHz这里要明确一点11.26376 ms/sample 不是端到端延迟。它只统计 NPU busy 期间的 PL clock cycle不包含PS 复制 bundlePS 写入 inputcache flush / invalidatebare-metal 程序启动UART 打印JTAG 下载XSDB 轮询所以更准确的说法是当前 KWS testvector 在 50 MHz 下单样本 NPU active-cycle equivalent 为 11.26376 ms。不能把这个数字直接宣传成系统端到端吞吐率。5. 整体数据流TinyML_NPU 的板级闭环如下ONNX QDQ / manual IR | v Python compiler | v uops.bin / params.bin / bundle.h | v Zynq PS bare-metal firmware | v 128 KiB shared BRAM | v VenusCore PL NPU | v INT8 logits write-back | v PS compare reference top1 / label accuracy / tolerance | v UART JTAG result block在 ZYBO7010 上PS 和 PL 之间主要有两条路径路径作用AXI4-Lite - APB3PS 配置 NPU 寄存器AHB-Lite DMA - BRAM native portNPU 读取 uOP、参数、输入并写回输出地址映射区域地址NPU control0x43C0_0000Shared BRAM0x4000_0000..0x4001_FFFFBoard result0x4001_FFC0..0x4001_FFFFIRQIRQ_F2P[0]shared BRAM 是首版设计中的关键简化。它避开 DDR、复杂 cache coherency 和 Linux 驱动把重点放在 NPU 数据流、uOP 执行和板级验证上。6. 编译器输出compiler 会把受约束的 ONNX QDQ 模型或手写 IR 编译成文件内容uops.bin连续的 32-byte little-endian uOPparams.bin权重、bias、scale、shift 等参数块metadata.json张量范围、地址模式、tile/uOP 映射bundle.h给 bare-metal firmware 使用的 C header板级 KWS demo 当前 bundle 大小如下字段大小uOP stream1,408 bytes / 44 uOPsparameter block58,112 bytesactivation peak64,000 bytesinput8,000 bytesoutput12 bytes板级路径使用 offset address mode。固件加载 bundle 后会把 uOP 中的参数、输入、输出 offset 重定位到 shared BRAM 的实际地址。7. 如何复现初始化并检查gitclone https://github.com/XuZhanhe-Chi/TinyML_NPU.gitcdTinyML_NPUmakesetupmakecheck生成 RTLmakertl构建 ZYBO7010 bitstream 和 Vitis appmakezybo-bitstreammakezybo-app下载到板子并运行makezybo-run板级流程依赖Vivado/Vitis 2021.1原版 Digilent ZyboDigilent board files可用 JTAG 连接当前仓库不启用 GitHub-hosted CI。验证方式是本地make check、Vivado/Vitis 构建和实体开发板验收。8. 开源边界这个版本只保留 ZYBO7010 KWS testvector 闭环需要的内容。包含VenusCore SpinalHDL 源码compiler 核心路径uOP / bundle parser / relocation checkZYBO7010 glue RTLbare-metal KWS testvector firmware120-sample KWS testvector header文档和 release package 脚本不包含训练数据集KWS ONNX 模型训练脚本实时麦克风链路ASIC / 工艺库 / 后端功耗材料GW5A、VexRiscv SoC 等非首版路径Vivado/Vitis 生成工程大型仿真缓存和波形文件这不是历史工程打包而是一个可理解、可复现、可修改的最小闭环。9. 和 TinyML_SOC 的关系TinyML_NPU 解决的是一个 INT8 TinyML NPU 如何从 compiler 到 RTL 再到 Zynq 板级验证跑通。后续的 TinyML_SOC 解决的是如何把这个 NPU 放进一个 VexRiscv SoC在 Tang Primer 25K 上做实时麦克风 KWS demo。两者的区别很明确项目TinyML_NPUTinyML_SOC重点NPU IP 和 compiler完整 SoC 和实时 demo板卡Digilent Zybo / XC7Z010Tang Primer 25K / GW5A-25A输入KWS testvectorI2S 麦克风CPUZynq PSVexRiscv固件bare-metalFreeRTOS输出UART/JTAG result blockUART structured log LED目标验证 NPU 执行正确性验证实时 KWS 系统闭环如果只关心 NPU 架构、uOP、compiler 和硬件执行正确性看 TinyML_NPU。如果关心完整 FPGA SoC、Flash 启动、I2S 音频、CPU frontend 和实时 KWS上板路径看 TinyML_SOC。10. 适合学习什么这个项目适合参考TinyML NPU 基本组成compiler 如何生成硬件 uOPINT8 / INT32 量化数据通路SpinalHDL RTL 设计Zynq PS 和 PL 协同APB/AHB 风格的加速器接口FPGA 加速器板级 demo毕业设计整理成开源项目的方式它的重点不是性能指标多高而是把一个 TinyML 加速器从软件到硬件的关键边界公开出来。11. 总结TinyML_NPU / VenusCore v0.1.0 当前具备以下特点支持 Conv3x3、Pointwise Conv1x1、Depthwise Conv3x3、AveragePool 等 TinyML 常用算子采用 1 cluster、4 lanes、SIMD4 的 INT8 / INT32 数据通路在 ZYBO7010 上完成 120 个 KWS testvector 板级验证reference top1 match 为 120/120label accuracy 为 117/120单样本 NPU active-cycle equivalent 为 11.26376 ms 50 MHzpost-route WNS 为 3.025 ns项目源码以 Apache-2.0 开源项目地址TinyML_NPU GitHub 仓库TinyML_NPU v0.1.0 ReleaseTinyML_SOC 项目介绍