BitNetMCU: 在低端微控制器上实现高精度低位量化神经网络
BitNetMCU是一个专注于低位量化神经网络的训练和推理的项目,专门设计用于在CH32V003等低端微控制器上高效运行。通过量化感知训练(QAT)以及模型结构和推理代码的微调,在16x16 MNIST数据集上实现了超过99%的测试准确率,而且不使用乘法指令,仅使用2kb的RAM和16kb的闪存。
训练流程基于PyTorch,应该可以在任何地方运行。推理引擎使用Ansi-C实现,可以轻松移植到任何微控制器上。
您可以在docs/
目录中找到关于该项目的详细报告点击这里
项目结构
BitNetMCU/
│
├── docs/ # 报告
├── mcu/ # CH32V003特定的MCU代码
├── modeldata/ # 预训练模型
│
├── BitNetMCU.py # Pytorch模型和QAT类
├── BitNetMCU_inference.c # C语言推理代码
├── BitNetMCU_inference.h # C语言推理代码的头文件
├── BitNetMCU_MNIST_test.c # MNIST数据集的测试脚本
├── BitNetMCU_MNIST_test_data.h# 头文件格式的MNIST测试数据(生成的)
├── BitNetMCU_model.h # C语言头文件格式的模型数据(生成的)
├── exportquant.py # 将训练好的模型转换为量化格式的脚本
├── test_inference.py # 测试C语言实现的推理脚本
├── training.py # 神经网络训练脚本
└── trainingparameters.yaml # 训练参数配置文件
训练流程
数据流程分为几个Python脚本,以提高灵活性:
-
配置:修改
trainingparameters.yaml
以设置模型训练的所有超参数。 -
训练模型:使用
training.py
脚本训练模型,并将权重以.pth
文件格式存储在modeldata/
文件夹中。此阶段的模型权重仍为浮点格式,因为它们在训练过程中动态量化。 -
导出量化模型:使用
exportquant.py
脚本将模型转换为量化格式。量化后的模型权重被导出到C语言头文件BitNetMCU_model.h
中。 -
可选:测试C模型:编译并执行
BitNetMCU_MNIST_test.c
以测试十个数字的推理。模型数据包含在BitNetMCU_MNIST_test_data.h
中,测试数据包含在BitNetMCU_MNIST_test_data.h
文件中。 -
可选:在完整数据集上验证C与Python模型:推理代码和模型数据被编译成DLL。
test-inference.py
脚本调用DLL并将结果与原始Python模型进行比较。这允许对整个MNIST测试数据集(10,000张图像)进行准确比较。 -
可选:在MCU上测试推理:按照
mcu/readme.md
中的说明操作。移植到CH32V003以外的架构很简单,mcu
目录中的文件可以作为参考。
更新
- 2024年4月24日 - 首次发布,支持二进制、三元、2位、4位和8位量化。
- 2024年5月2日 - 标记版本0.1a
- 2024年5月8日 - 添加FP1.3.0量化,实现完全无乘法推理,准确率达98.9%。
- 2024年5月11日 - Linux修复。感谢@donn
- 2024年5月19日 - 添加非对称4位量化方案支持,便于在带乘法器的MCU上进行推理。推理代码现在只在不带乘法器的RV32架构上使用针对无乘法器MCU优化的代码。
- 2024年5月20日 - 添加
quantscale
作为超参数,影响权重缩放。更新了新量化方案的文档。 - 2024年5月26日 - 标记版本0.2a
- 2024年7月19日 - 添加octav算法计算最佳裁剪和量化参数。
- 2024年7月26日 - 添加NormalFloat4(NF4)量化支持。更新文档