O1-Sound
A greeting wake-word spotter built on the O-Series liquid core.
Always-on keyword spotting on a battery: the model listens continuously, holds a fixed-size state no matter how long the microphone has been open, and fires when it hears a greeting — "hello", "hola", "bonjour", "你好".
mic → log-mel (fixed, no weights) → liquid core (multi-timescale τ) → wake / not-wake
↑ carried state: 5,120 bytes, constant
Files
| File | Description |
|---|---|
o1sound.pt |
Binary wake/not-wake research checkpoint (Run 7, 2026-08-18), 4.8 MB |
o1sound_multiclass.pt |
Multiclass experiment checkpoint (2026-09), one class per greeting + "other" |
o1sound.onnx |
Streaming ONNX graph (fp32, single-frame step()), 5.04 MB |
o1sound.metrics.json / o1sound_multiclass.metrics.json |
Per-language metrics for each checkpoint |
test.json / test_multiclass.json |
Held-out test results |
Honest status — what is and isn't validated
Validated (runs today, in CI)
- 32 tests pass: streaming
step()is numerically identical to the batchedforward(), carried state stays constant over 500 frames. - ONNX export: 5.03 MB fp32, 1.27 MB int8, max |onnx − torch| = 3.7e-09.
- Carried state: 5,120 bytes per stream, independent of stream length — a property of the recurrence, verified by test.
Measured — the architecture works, the multilingual framing does not (yet)
- Run 2 (2026-08-01, English only, 301 wake clips): FRR 0.146 at FAR 0.046 on held-out test; dev accuracy 0.919 against a 0.780 never-fire baseline.
- Run 1 (2026-07-31, 9 languages, 91 wake clips): FRR 0.909 at FAR 0.049 — worse than saying no unconditionally at that data scale.
- Run 7 (2026-08-18, 10 languages, full MSWC): dev acc 0.885 (balanced 0.849); English is the only language with meaningful data (FRR 0.098 at FAR 0.133, 41 clips). Worst-language FRR is 1.000 (2 positive clips) — the multilingual claim is bounded by per-language data, not the architecture.
- Multiclass experiment (2026-09, 10 languages, OR-head): dev balanced accuracy 0.84; test FRR 0.35 @ FAR 0.046 overall — multilingual remains unsupported at this data scale.
Not production-grade. Deployed wake words run single-digit FRR at a
false-accept rate quoted per hour, not per clip. Latency and power are
unmeasured on real hardware (the Python step() loop runs ~0.5 ms/frame on a
desktop CPU). On out-of-domain audio (e.g. pure tones) it can false-trigger.
Model sizes (measured, n_classes=2)
| hidden | layers | params | fp32 | int8 | carried state |
|---|---|---|---|---|---|
| 384 | 2 | 483,984 | 1.94 MB | 0.48 MB | 3,072 B |
| 512 | 2 | 841,872 | 3.37 MB | 0.84 MB | 4,096 B |
| 640 | 2 | 1,298,064 | 5.19 MB | 1.30 MB | 5,120 B |
| 512 | 3 | 1,367,184 | 5.47 MB | 6,144 B | |
| 768 | 2 | 1,852,560 | 7.41 MB | 1.85 MB | 6,144 B |
hidden=640, layers=2 is the default: the largest 2-layer configuration that
still clears 7 MB in fp32 once ONNX graph overhead is counted.
Usage
The exported ONNX graph is the single-frame step() — one frame in, logits and
the next state out. Full training / export / streaming-demo code lives in the
GitHub repository:
- Code, training and streaming demo: AwareLiquid/O1-Sound
- Research release notes: release
research-2026-08-18
Why a liquid core
Each channel carries its own learnable time constant τ, parameterised as
softplus(log_tau) + tau_min and initialised geometrically across 10–240 ms.
Short-τ channels track the current phoneme; long-τ channels hold the envelope of
the whole word — separating a wake phrase from a phonetically close neighbour
without stacking depth. Streaming is O(1): the state does not grow with how long
the microphone has been open.
Related
- AwareLiquid/M1 — the MT-LNN / O-Series research line this core comes from
- AwareLiquid/M2 — next-generation architecture research
- awareliquid.ai — benchmarks and retractions
License
MIT.