lokutor-ai / oido
git clone https://github.com/lokutor-ai/oido.git
Oído: open-vocabulary speech recognition that fits in a $5 ESP32-S3. 3.7% LibriSpeech WER, no cloud, no NPU.
+3
stars, 24h · #8,271
+~7
stars, 7 days · #14,951
+120
stars, 30 days · #5,955
120
★ total · +6% this week
7
forks · 2 open issues
Star history (as recorded here)
LanguageC
LicenseGPL-3.0
Created2026-09-30 (23d ago)
Last push2d ago
Watchers1
OwnerOrganization
GitHub topics
asrconformeredge-aiembeddedesp-idfesp32esp32-s3microcontrolleron-device-aispeech-recognitionspeech-to-texttinyml
Links
- GitHub: github.com/lokutor-ai/oido
- Homepage: https://lokutor.com
- Releases · Issues · Hacker News mentions
README excerpt
# Oído: speech recognition that fits in a $5 chip
*¡Oído!* is what cooks call out in a Spanish kitchen to confirm an order: *heard, got it*.
*Animated demo; full video with sound.
The transcripts are Oído's output, sped up. Footage from a physical board is coming.*
Speech-to-text for any English or Spanish sentence, running entirely on an **ESP32-S3** (240 MHz dual-core Xtensa LX7, 8 MB PSRAM,
16 MB flash). No cloud, no command list, no neural accelerator. Built by Lokutor.
Models on Hugging Face: int8 ·
int4.
**Audio samples**: random clips in a quiet room, a car, a kitchen, a cafeteria,
reverberant rooms and real meetings, each with the reference, the on-chip transcript (errors marked) and the compute
it took on the chip.
> **Status (9 October 2026).** Measured on an ESP32-S3-WROOM-1-N16R8 board, one core at 240 MHz: the English int8 model with
> the language model runs at **1.97× real time** (1.91–2.02 over 27 clips of 3.6–10.6 s). Spanish runs at 2.06×, int4 at 1.76×,
> the transducer at 1.89× (see Speed and memory). **That is not real time yet:** a 4-second command shows its
> text about 8.7 s after it ends (including the 0.8 s end-of-speech wait). The two-core mode, which emulation had predicted would
> approach real time, gives wrong transcripts on silicon and is disabled (see Dual core).
> The board's transcripts are identical to the instruction-exact emulator's on all 27 clips. Accuracy numbers come from the host
> build of the same C code; it differs from the board on some hard clips because of the laptop's math library (22 of the 27
> clips are identical, and the word error rate on those 27 clips is the same, 7.14 %).
## Which model should I use?
There is **one model per language**, and the models that stream also run in full-context ("utterance") mode.
| I want | Use | Language | Modes | Size | License |
|---|---|---|---|---|---|
| The best English accuracy | `models/nemo8.tnm` + `nemo_lm.tlm` (Hugging Face) | English | utterance only: text about 3 s after you stop | 14.0 + 1.3 MB | CC-BY-4.0 |
| English with the least flash | `models/nemo4.tnm` (Hugging Face) | English | utterance only | 8.3 MB | CC-BY-SA-4.0 |
| English, low latency (voice agents) | `models/oido_stream.tnm` (Hugging Face) | English | **streaming** (final text about 4 s after a 4 s command ends, measured; see below) and full-context | 14.0 MB | CC-BY-SA-4.0 |
| Spanish | `models/oido_es.tnm` + `oido_es.tlm` (Hugging Face) | Spanish | **streaming and full-context, in the same file** | 14.0 + 1.3 MB | CC-BY-4.0 |
- **Streaming vs utterance:** `oido_stream.tnm` and `oido_es.tnm` carry a streaming flag. The firmware's microphone mode and
`live_demo.py` stream with them automatically; the full-context (utterance) accuracy figures in the tables come from the
same files run through `tasr_nemo_transcribe` / `eval_engine.py`. The original English models (`nemo8`, `nemo4`) are
utterance-only.
- **What streaming costs:** some accuracy (English LibriSpeech 4.9 / 11.0 instead