Skip to main content

📟 mcufit

Know if your AI model fits your microcontroller - before you flash it.

PyPI CI Python License: MIT

🌐 Try it in your browser - drop a model, get a verdict, nothing to install

Runs entirely client-side. Your model never leaves your device.


mcufit demo - ✅ fits on ESP32-S3, ❌ won't fit on Arduino Uno

Deploying ML to a microcontroller today works like this: train, convert, flash, watch it crash with Arena size is too small, guess a bigger number, re-flash, repeat. The official TFLite Micro docs literally say the memory size "may need to be determined by experimentation."

mcufit replaces the experimentation with an answer in one second.

pip install mcufit
mcufit check model.tflite --board esp32-s3

Features

  • Instant fit verdict - RAM & flash bars, headroom, and the exact layer where memory peaks
  • 🎯 Exact mode - runs your model through the real TFLite Micro runtime compiled for your machine: activations measured exactly, interpreter overhead an upper bound, zero hardware
  • 🌐 Browser version - same engine via WebAssembly, fully private, no install
  • 🔌 31 boards - ESP32 family, Pico, STM32, Teensy, Arduino, and more
  • 🤖 CI guard - a GitHub Action that fails the PR when your model outgrows the chip
  • 💡 Actionable suggestions - int8 quantization preview (simulated, not guessed) and which boards do fit
  • ⏱️ Speed, measured - ms/inference on the boards actually benchmarked on hardware, and silence on the rest
  • 📦 ONNX support - pip install 'mcufit[onnx]' for the PyTorch world

Commands

Command What you get
mcufit check model.tflite -b esp32-s3 Fit verdict (exit code 1 on ❌ - CI-friendly)
mcufit check ... --exact Measured by the real TFLM runtime (upper bound, see below)
mcufit compare model.tflite Verdict matrix across all 31 boards
mcufit inspect model.tflite Layer-by-layer memory profile
mcufit boards The board database
mcufit setup-exact Native fallback build, only if node is unavailable
... --json Machine-readable output for scripts & CI

Exact mode

Static analysis is instant but approximate - real runtimes allocate per-operator working memory no file analysis can see. Exact mode runs your model through the actual TFLite Micro interpreter and reads its recorded allocations:

mcufit check model.tflite -b esp32-s3 --exact   # needs node, nothing to build

The interpreter ships in the wheel, compiled to wasm32 and run under node. There is no setup step and no compiler. On the person-detection reference model: estimate ~74 KB → measured 84,428 bytes.

How close it gets

Activation tensors come straight from the model, so their size is identical everywhere and that half of the number is exact. The interpreter's own bookkeeping is full of pointers, so its size follows the pointer width of whatever the interpreter was compiled for.

Measured against a real ESP32-D0WDQ6 at 240 MHz, person_detect (mcufit-bench, 2026-08-16):

arena section host build, 64-bit wasm32 real device
activations 55,296 55,296 55,296
interpreter overhead 33,952 29,132 27,004
total 89,248 84,428 82,300
error vs device +8.4% +2.6% -

wasm32 is 32-bit like the chip, which is why --exact uses it. What is left is struct padding that differs from Xtensa. It reads high rather than low, which is the safe direction for a fit check, but it is not the device's exact number and the tool says so in its output.

mcufit setup-exact still builds the native 64-bit interpreter, for machines without node. It is the less accurate path and the CLI warns when it uses it.

Speed

Only esp32 and nano33ble have been measured on hardware. Every other board returns no speed number.

board validated error
esp32 -6% to +4%
nano33ble -11% to +20%

Speed is not derivable from a datasheet. Which operators run fast depends on which kernels the vendor wrote, and that is not documented anywhere. Measured per operator, in MACs/cycle:

operator ESP32 (esp-nn) Nano 33 BLE (CMSIS-NN)
CONV_2D 0.073 0.190
DEPTHWISE_CONV_2D 0.044 0.063
FULLY_CONNECTED 0.022 0.186

Each chip is slow at a different operator. On the ESP32 fully-connected costs 3.2x more than convolution, because esp-nn ships no kernel for it and it falls back to reference C. On the nRF52840 fully-connected is fine and depthwise is the slow one, at 3.3x.

Before this, every board carried a hand-written macs_per_cycle. Those were wrong by up to 3.2x and ranked the two chips the wrong way round. They are gone. Numbers come from mcufit-bench.

Guard your model in CI

- uses: avionicharshit-byte/mcufit@main
  with:
    model: models/wake_word.tflite
    board: esp32-s3

A model that grows past the board's RAM now fails the pull request instead of the field deployment.

Supported boards (31 across 7 vendors - click to expand)
Vendor Boards
Arduino Uno R3/R4, Mega 2560, Nano 33 BLE Sense, Nano 33 IoT, Portenta H7
Espressif ESP32, S2, S3, C3, C6, P4, ESP8266, ESP32-CAM, M5Stack Core2
Raspberry Pi Pico, Pico W, Pico 2
STM32 F103 Blue Pill, F411 BlackPill, F407 Discovery, F746 Discovery, H743 Nucleo
Seeed Studio XIAO ESP32S3 Sense, XIAO nRF52840 Sense, Wio Terminal
Teensy 4.0, 4.1
Other SparkFun Edge, BBC micro:bit v2, nRF52832 DK

Missing yours? Adding a board is a 10-line PR to boards.yaml - CI validates it automatically.

How it works

The RAM bottleneck on microcontrollers is the tensor arena: every intermediate tensor alive at the same moment must fit in SRAM at once. mcufit parses the model file directly (weights → flash, activations → RAM), computes tensor lifetimes across the execution schedule, and finds the peak - the same quantity TFLM's memory planner must pack. Exact mode skips the math and asks the real runtime, with the pointer-width caveat above. Board verdicts account for the RAM your RTOS/Wi-Fi stack already eats before your app gets any.

Why this exists

Pre-deployment memory estimation has been requested in the TensorFlow repos since 2019 - never shipped. A TFLite Micro maintainer, March 2024:

"We don't have a python based tool for determining arena size…"

Vendor tools (STM32Cube.AI, eIQ) answer only for their own silicon. mcufit is the neutral, open version.

License

MIT

Release files for mcufit 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcufit 0.4.0
File Size Uploaded
mcufit-0.4.0.tar.gz 727.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcufit 0.4.0
File Interpreter ABI Platform
mcufit-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 982.8 kB

Release files / mcufit-0.4.0.tar.gz

Download URL mcufit-0.4.0.tar.gz
Size 727.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f3871c607bdc08576a8cbf12eb368ab4b3109606d4d4057c8f0d8ce2bed1a549
BLAKE2b-256 checksum
How to use checksums
9bb8edb4aad67a4ef7404860b680229aada01b812660f1ce0224f68fe33857d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / mcufit-0.4.0-py3-none-any.whl

Download URL mcufit-0.4.0-py3-none-any.whl
Size 254.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5f91c49d450bce5150185c2133dc417eac99fdf8c62ebd61bea2b65503afaa90
BLAKE2b-256 checksum
How to use checksums
8f243322936ca205c86e0373a8b10d2dfefdb9c95c267eb233732658da917ec2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release history Release notifications | RSS feed

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page