esp32.diy

Ivy AI: Fully Offline Voice Assistant on ESP32-S3

Oct 19, 2026 · 5 min read

Advanced 58 stars 7 forks C GPL-3.0 Updated 2026-10-13

Ivy AI running on the Freenove FNK0104B — the board listens, transcribes, generates a response with its on-device LLM, and speaks the answer.

TL;DR Ivy AI is a fully offline voice assistant that runs wake-word detection, speech transcription, a 19.7M-parameter quantized language model, and text-to-speech entirely on a Freenove ESP32-S3 board. No network, no server — just say 'Hey Ivy' and it answers out loud.
What you need
  • Freenove FNK0104B (ESP32-S3R8)
  • ILI9341 240x320 LCD (on-board)
  • FT6336U touch controller (on-board)
  • ES8311 codec with microphone and speaker (on-board)
  • microSD card (SDMMC, on-board slot)
  • Li-ion battery with charging (on-board)
BoardFreenove FNK0104B (ESP32-S3R8, 8 MB PSRAM, 16 MB flash)
FrameworkESP-IDF v6.1 (native, no Arduino)
LanguageC
LLMTinyTalk 2 8M v8 — 19.7M parameters, 4-bit quantized
LicenseGPL-3.0-or-later
DifficultyAdvanced

What You Will Build

Ivy AI turns a single $20 microcontroller into a self-contained voice assistant. Say "Hey Ivy", ask a question in plain speech, and the board transcribes your words, runs a small language model, and speaks an answer — all without touching the internet. Wi-Fi is only used to set the clock over NTP once an hour; after that the radio shuts off.

The full pipeline looks like this:

mic → [LISTEN: energy VAD] → [TRANSCRIBE: conformer CTC]
    → [THINK: 19.7M-parameter LLM, 4-bit] → [SPEAK: SVOX Pico] → speaker

Beyond the AI path, the board also handles timers, date and time queries, and an on-screen T9 keyboard in plain C — no model weight needed for those. A built-in demo mode lets the device ask itself questions and answer them hands-free, which is handy for filming or showing it off.

What You Need

Hardware

Software

All large assets — the conformer STT weights, SVOX Pico TTS data, and the LLM — live on the SD card rather than in flash, so the 16 MB flash is not a bottleneck.

Typical use cases

Fully Offline Voice Assistant

Answer questions, set timers, and check the time by voice — with no cloud dependency and no data leaving the device.

On-Device LLM Research

A working baseline for running quantized language models on resource-constrained microcontrollers, with measured benchmarks and documented memory budgets.

Edge AI Development Platform

Host-side build harnesses let you develop and test the LLM, UI, and arena allocator on a PC before touching hardware, shortening the iteration loop.

Custom Model Experiments

Drop any compatible GGUF file onto the SD card or convert a Hugging Face checkpoint to try different small language models on the same hardware.

How It Works

The main engineering challenge is that STT alone needs 5.4 MB of RAM and the LLM needs 6.5 MB, but the board only has 8 MB of PSRAM and about 300 KB of usable internal SRAM. Ivy solves this with a phase-based memory arena: two large arenas (7 MB PSRAM, ~145 KB internal) are reserved at boot, and STT and the LLM never run at the same time. Each phase claims the whole arena, does its work, then returns it. Every transition logs free, largest, and minimum-ever bytes to the screen, so an allocation failure is visible rather than silent.

Speed comes from several places at once: weights are stored at 4-bit with int8 activations, there is a hand-written ESP32-S3 PIE SIMD kernel (dot_q4_pie.S) for the inner dot product, and matrix-vector multiplication is offloaded to the second Xtensa core. The result is 5.4–5.9 tokens per second with the default TinyTalk v8 model (6.5 MB), or up to 30 tok/s with a tiny storytelling GGUF.

The wake word engine (Espressif WakeNet9) runs continuously at very low power, even from sleep. When it fires, the VAD captures audio, the conformer CTC model transcribes it from SD-streamed tensors, and the resulting text goes to whichever LLM is selected. SVOX Pico en-US synthesises the reply and sends it to the ES8311 codec.

Build and Flash

1. Flash the firmware

The PowerShell wrapper sets the correct IDF environment and flashes in one step. Replace COM22 with your board's port:

powershell -ExecutionPolicy Bypass -File tools/idf.ps1 -p COM22 flash

The compiled app is 2.8 MB. The WakeNet9 model is written to its own flash partition automatically during the build.

2. Copy assets to the SD card

The STT, TTS, and LLM files are too large for flash. Upload everything listed in the manifest over the serial console at about 700 KB/s with CRC checking:

python tools/sd_put.py --manifest

To update a single model instead of the full set, use --only <name>.

3. Verify over serial

The serial_cmd.py tool drives the device's own command console — the same code paths the touchscreen UI uses, so results reflect real behaviour:

python tools/serial_cmd.py "models" "model 13" "ask what is half of twelve"

Useful commands: models / model <n> to list and switch models, ask <question>, say <text>, bat for battery level, time, wifi <ssid> <pw> to configure Wi-Fi for NTP, and wakemon on to watch the microphone peak level while the wake word engine is listening.

4. Test without hardware

Most components — arenas, the LLM engine, and the UI renderer — also build for PC. The host test runner checks them without needing a board:

powershell -ExecutionPolicy Bypass -File tools/hosttest.ps1

Adding Your Own Models

Ivy supports two model formats, both selected from the on-device /model page:

TinyTalk / CRDP — a folder on the SD card containing model.bin, tok.bin, and an optional name.txt. These are converted from Hugging Face GPT-Neo checkpoints using the tools in the tools/ directory.

GGUF — any llama.cpp-format file dropped into /sd/models/. Supported architectures: llama. Supported quantisations: F32, F16, Q8_0, Q4_0, with SentencePiece tokeniser. The practical size limit is about 5.8 MB, which fits roughly 10M parameters at 4-bit. docs/GGUF.md in the repository covers the fit rules, conversion steps, and a vocabulary-shrinking tool that can push a borderline model under the limit.

The model selection is saved in NVS and shown in the header so you always know what is loaded.

Limitations and Ideas to Extend It

Known limits to keep in mind:

Ways to take it further:

Verdict

Ivy AI is a serious piece of embedded systems engineering: a fully self-contained voice pipeline — wake word, STT, LLM, TTS — running on a single $20 board with no cloud and no compromises on functionality. The phase-based memory arena, hand-written SIMD kernels, and dual-core dispatch show careful work to squeeze every byte and cycle out of the hardware. This is a challenging build aimed at experienced ESP-IDF developers, but the host-side test harnesses and well-documented memory budget make it unusually approachable for a project of this complexity.

Sources

github.comiamankushpandit/esp_ai — repository & README iamankushpandit.github.ioOfficial website

Facts in this article come from the project's public README and GitHub metadata at the time of writing. Images belong to their respective owners and link back to the original source.