On-device voice AI + RAG for macOS — STT, LLM, TTS, all local
C++
4
15 commits
updated Mar 25, 2026
On-device voice AI + RAG for macOS. Ask questions about your documents by voice — 100% local.
localhost:8080Everything runs on your machine. No API keys, no cloud, no data leaves the device.
# Prerequisites
xcode-select --install
brew install cmake
# Build
git clone https://github.com/user/sona.git && cd sona
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(sysctl -n hw.ncpu)
# Download AI models (~1GB, first time only)
./sona setup
# Start
./sona
# Open http://localhost:8080
| Command | Description |
|---|---|
sona | Start web server on port 8080 |
sona setup | Download default AI models |
sona cleanup | Remove unused models to free disk space |
sona upgrade-stt | Upgrade to Parakeet TDT (better transcription) |
sona upgrade-llm | Switch to a different LLM |
sona voices | Change TTS voice |
sona metalrt install | Install MetalRT engine (M3+ only) |
--port <n> Server port (default: 8080)
--gpu-layers <n> GPU layers for LLM (default: 99 = all)
--models <dir> Models directory (default: ~/Library/Sona/models)
--verbose, -v Debug logs
| Method | Endpoint | Description |
|---|---|---|
GET | / | Web UI |
POST | /api/upload | Upload document (multipart) |
POST | /api/query | Ask a question (JSON {query}) |
POST | /api/transcribe | Transcribe audio (WAV body) |
POST | /api/speak | Text-to-speech (JSON {text}) |
POST | /api/clear | Clear conversation history |
GET | /api/status | Engine info |
All POST endpoints require X-Sona-Token header when accessed remotely. The token is printed to stderr on startup and auto-injected into the web UI.
Share your instance with others via Cloudflare Tunnel:
brew install cloudflared
cloudflared tunnel --url http://localhost:8080 --protocol http2
The generated https://xxx.trycloudflare.com link includes auth — send it to anyone.
| Model | Size | Speed | Notes |
|---|---|---|---|
| Llama 3.2 3B Instruct | 1.8 GB | ~100 t/s | Default |
| Qwen3.5 4B | 2.7 GB | ~75 t/s | Best small model, 262K context |
| Liquid LFM2 1.2B | 731 MB | ~180 t/s | Recommended |
| Qwen3 0.6B | 456 MB | ~250 t/s | MetalRT: ~486 t/s |
| Liquid LFM2 350M | 219 MB | ~350 t/s | Fastest, 128K context |
| Model | WER | Notes |
|---|---|---|
| Parakeet TDT 0.6B v3 | ~1.9% | Best accuracy (sona upgrade-stt) |
| Whisper base.en | ~5% | Default fallback |
| Zipformer | — | Streaming (always active for live mic) |
| Model | Notes |
|---|---|
| Piper Lessac | Default, low latency |
| Kokoro v0.19 | Multiple speakers |
┌─────────────────────────────────┐
│ Web UI / API │
│ localhost:8080 (cpp-httplib) │
└──────────┬──────────┬────────────┘
│ │
voice │ │ document
query │ │ upload
▼ ▼
┌───────────────────────────────────────┐ ┌──────────────────────────┐
│ Voice Pipeline │ │ RAG Pipeline │
│ │ │ │
│ ┌─────┐ ┌─────┐ ┌─────────┐ │ │ ┌────────┐ ┌───────┐ │
│ │ VAD ├──▶│ STT ├──▶│ LLM │ │ │ │ Doc ├─▶│Embed │ │
│ └─────┘ └─────┘ │ │◀────┼──┼──│Processor│ │Engine │ │
│ │ llama.cpp│ │ │ └────────┘ └──┬────┘ │
│ ┌─────┐ │ or │ │ │ ┌──▼────┐ │
│ │ TTS │◀─────────────│ MetalRT │ │ │ ┌────────┐ │Vector │ │
│ └──┬──┘ └─────────┘ │ │ │ BM25 │ │Index │ │
│ │ │ │ └───┬────┘ └──┬────┘ │
└─────┼─────────────────────────────────┘ │ │ RRF │ │
▼ │ └────┬─────┘ │
┌─────────┐ │ ▼ │
│CoreAudio│ │ top-K chunks │
│ Output │ └──────────────────────────┘
└─────────┘
Engines: sherpa-onnx (STT/TTS/VAD) · llama.cpp (LLM) · MetalRT (M3+ GPU)
Storage: USearch HNSW (vectors) · BM25 (term index) · mmap'd chunks
src/
api/ C API — public interface for embedding Sona
audio/ CoreAudio I/O, WAV encoding
cli/ Web server, embedded frontend, CLI commands
core/ Lock-free ring buffer, types, config
engines/ STT, TTS, LLM, embedding, MetalRT backends
models/ Model registry, download, priority-based auto-selection
pipeline/ Voice pipeline orchestrator (STT → LLM → TTS)
rag/ Hybrid retrieval: USearch HNSW + BM25 + RRF fusion
Dependencies: llama.cpp (LLM + Metal GPU), sherpa-onnx (STT/TTS/VAD), USearch (vector index), cpp-httplib (HTTP server)
15 commits
C++
97.3%
C
1.5%
On-device voice AI + RAG for macOS — STT, LLM, TTS, all local
C++
4
15 commits
updated Mar 25, 2026
On-device voice AI + RAG for macOS. Ask questions about your documents by voice — 100% local.
localhost:8080Everything runs on your machine. No API keys, no cloud, no data leaves the device.
# Prerequisites
xcode-select --install
brew install cmake
# Build
git clone https://github.com/user/sona.git && cd sona
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(sysctl -n hw.ncpu)
# Download AI models (~1GB, first time only)
./sona setup
# Start
./sona
# Open http://localhost:8080
| Command | Description |
|---|---|
sona | Start web server on port 8080 |
sona setup | Download default AI models |
sona cleanup | Remove unused models to free disk space |
sona upgrade-stt | Upgrade to Parakeet TDT (better transcription) |
sona upgrade-llm | Switch to a different LLM |
sona voices | Change TTS voice |
sona metalrt install | Install MetalRT engine (M3+ only) |
--port <n> Server port (default: 8080)
--gpu-layers <n> GPU layers for LLM (default: 99 = all)
--models <dir> Models directory (default: ~/Library/Sona/models)
--verbose, -v Debug logs
| Method | Endpoint | Description |
|---|---|---|
GET | / | Web UI |
POST | /api/upload | Upload document (multipart) |
POST | /api/query | Ask a question (JSON {query}) |
POST | /api/transcribe | Transcribe audio (WAV body) |
POST | /api/speak | Text-to-speech (JSON {text}) |
POST | /api/clear | Clear conversation history |
GET | /api/status | Engine info |
All POST endpoints require X-Sona-Token header when accessed remotely. The token is printed to stderr on startup and auto-injected into the web UI.
Share your instance with others via Cloudflare Tunnel:
brew install cloudflared
cloudflared tunnel --url http://localhost:8080 --protocol http2
The generated https://xxx.trycloudflare.com link includes auth — send it to anyone.
| Model | Size | Speed | Notes |
|---|---|---|---|
| Llama 3.2 3B Instruct | 1.8 GB | ~100 t/s | Default |
| Qwen3.5 4B | 2.7 GB | ~75 t/s | Best small model, 262K context |
| Liquid LFM2 1.2B | 731 MB | ~180 t/s | Recommended |
| Qwen3 0.6B | 456 MB | ~250 t/s | MetalRT: ~486 t/s |
| Liquid LFM2 350M | 219 MB | ~350 t/s | Fastest, 128K context |
| Model | WER | Notes |
|---|---|---|
| Parakeet TDT 0.6B v3 | ~1.9% | Best accuracy (sona upgrade-stt) |
| Whisper base.en | ~5% | Default fallback |
| Zipformer | — | Streaming (always active for live mic) |
| Model | Notes |
|---|---|
| Piper Lessac | Default, low latency |
| Kokoro v0.19 | Multiple speakers |
┌─────────────────────────────────┐
│ Web UI / API │
│ localhost:8080 (cpp-httplib) │
└──────────┬──────────┬────────────┘
│ │
voice │ │ document
query │ │ upload
▼ ▼
┌───────────────────────────────────────┐ ┌──────────────────────────┐
│ Voice Pipeline │ │ RAG Pipeline │
│ │ │ │
│ ┌─────┐ ┌─────┐ ┌─────────┐ │ │ ┌────────┐ ┌───────┐ │
│ │ VAD ├──▶│ STT ├──▶│ LLM │ │ │ │ Doc ├─▶│Embed │ │
│ └─────┘ └─────┘ │ │◀────┼──┼──│Processor│ │Engine │ │
│ │ llama.cpp│ │ │ └────────┘ └──┬────┘ │
│ ┌─────┐ │ or │ │ │ ┌──▼────┐ │
│ │ TTS │◀─────────────│ MetalRT │ │ │ ┌────────┐ │Vector │ │
│ └──┬──┘ └─────────┘ │ │ │ BM25 │ │Index │ │
│ │ │ │ └───┬────┘ └──┬────┘ │
└─────┼─────────────────────────────────┘ │ │ RRF │ │
▼ │ └────┬─────┘ │
┌─────────┐ │ ▼ │
│CoreAudio│ │ top-K chunks │
│ Output │ └──────────────────────────┘
└─────────┘
Engines: sherpa-onnx (STT/TTS/VAD) · llama.cpp (LLM) · MetalRT (M3+ GPU)
Storage: USearch HNSW (vectors) · BM25 (term index) · mmap'd chunks
src/
api/ C API — public interface for embedding Sona
audio/ CoreAudio I/O, WAV encoding
cli/ Web server, embedded frontend, CLI commands
core/ Lock-free ring buffer, types, config
engines/ STT, TTS, LLM, embedding, MetalRT backends
models/ Model registry, download, priority-based auto-selection
pipeline/ Voice pipeline orchestrator (STT → LLM → TTS)
rag/ Hybrid retrieval: USearch HNSW + BM25 + RRF fusion
Dependencies: llama.cpp (LLM + Metal GPU), sherpa-onnx (STT/TTS/VAD), USearch (vector index), cpp-httplib (HTTP server)
15 commits
C++
97.3%
C
1.5%