Zant (Zig-Ant) is an open-source SDK designed to simplify deploying Neural Networks (NN) on microcontrollers. Written in Zig, Zant prioritizes cross-compatibility and efficiency, providing tools to import, optimize, and deploy NNs seamlessly, tailored to specific hardware.
- Many microcontrollers (e.g., ATMEGA, TI Sitara) lack robust deep learning libraries.
- No open-source solution exists for end-to-end NN optimization and deployment.
- Inspired by cutting-edge research (e.g., MIT Han Lab), we leverage state-of-the-art optimization techniques.
- Collaborating with institutions like Politecnico di Milano to advance NN deployment on constrained devices.
- Built for flexibility to adapt to new hardware without codebase changes.
- Optimized Performance: Supports quantization, pruning, and hardware acceleration (SIMD, GPU offloading).
- Efficient Memory Usage: Incorporates memory pooling, static allocation, and buffer optimization.
- Cross-Platform Support: Works on ARM Cortex-M, RISC-V, and more.
- Ease of Integration: Modular design with clear APIs, examples, and documentation.
- Real-Time Applications: Object detection, anomaly detection, and predictive maintenance on edge devices.
- IoT and Autonomous Systems: Enable AI in IoT, drones, robots, and vehicles with constrained resources.
We are actively working towards achieving key milestones for Zant's development and optimization:
- March 5, 2025: Run MNIST inference on a Raspberry Pi Pico 2, importing models from ONNX.
- April 30, 2025: Get YOLO running efficiently on Raspberry Pi Pico 2.
- Transition to a Shape Tracker, optimizing tensor operations.
- Develop a frontend interface for easier interaction with the library.
- Implement im2tensor, converting JPEG/PNG images into our optimized tensor format.
- Optimize code generation, allowing users to choose between flash storage or RAM for execution.
- Expand ONNX operation support, ensuring compatibility with more layers and architectures.
- Begin work on pruning and quantization to improve network efficiency.
- Support additional microcontrollers and architectures.
- Develop benchmarking tools for profiling model execution on constrained devices.
- Improve the compiler backend, integrating more advanced optimization passes.
- Enhance support for real-time inference, focusing on low-latency applications.
- Install the latest Zig compiler.
- Brush up your Zig skills with Ziglings exercises.
Navigate to the project folder and execute:
zig build run
- Add new test files to
build.zig/test_list
if not already listed. - Run:
(Ignore stderr warnings.)
zig build zig build test --summary all
To run all tests, including computationally heavy ones, use:
zig build test -Dheavy --summary all
Generated using Zig's standard documentation format.
To use Zant effectively, you can create and train neural networks using a structured approach. Below is an example of how to define and configure a simple model.
const allocator = @import("pkgAllocator").allocator;
var model = Model(f64){
.layers = undefined,
.allocator = &allocator,
.input_tensor = undefined,
};
try model.init();
var conv1 = ConvolutionalLayer(f64){
.input_channels = 1,
.kernel_shape = .{ 32, 1, 3, 3 },
.stride = .{ 1, 1 },
.allocator = &allocator,
};
var conv1_layer = conv1.create();
try conv1_layer.init(&allocator, @constCast(&conv1));
try model.addLayer(conv1_layer);
var conv1_activ = ActivationLayer(f64){
.n_inputs = 32 * 26 * 26,
.n_neurons = 32 * 26 * 26,
.activationFunction = ActivationType.ReLU,
.allocator = &allocator,
};
var conv1_act = ActivationLayer(f64).create(&conv1_activ);
try conv1_act.init(&allocator, @constCast(&conv1_activ));
try model.addLayer(conv1_act);
var dense1 = DenseLayer(f64){
.n_inputs = 64 * 5 * 5,
.n_neurons = 512,
.allocator = &allocator,
};
var dense1_layer = DenseLayer(f64).create(&dense1);
try dense1_layer.init(&allocator, @constCast(&dense1));
try model.addLayer(dense1_layer);
var load = loader.DataLoader(f64, u8, u8, 64, 3){};
const image_file_name: []const u8 = "datasets/t10k-images-idx3-ubyte";
const label_file_name: []const u8 = "datasets/t10k-labels-idx1-ubyte";
try load.loadMNIST2DDataParallel(&allocator, image_file_name, label_file_name);
try Trainer.TrainDataLoader2D(
f64, u8, u8, &allocator, 64, 784, &model, &load, 30,
LossType.CCE, 0.005, 0.9, 0.0001, 1.0
);
model.deinit();
Follow the Docker Guide for containerized usage.
Contribute to Zant on GitHub. Let’s make NN deployment on microcontrollers efficient, accessible, and open!