TEST / README.md
EYEDOL's picture
Upload 10 files
0115b20 verified
|
Raw
History Blame Contribute Delete
4.4 kB
metadata
title: Open-Source Voice Agent
emoji: 🎀
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0

🎀 Open-Source Voice Agent

End-to-end English voice agent built entirely from open-source HuggingFace models with a streaming overlap pipeline β€” TTS synthesis for sentence N starts the moment sentence N is detected in the LLM token stream, while the model continues generating sentences N+1, N+2 … in parallel.


Models

Stage Model Params Device
VAD silero-vad 2 MB CPU
STT openai/whisper-base.en 74 M GPU / CPU
LLM HuggingFaceTB/SmolLM2-1.7B-Instruct 1.7 B GPU / CPU
TTS facebook/mms-tts-eng ~430 M CPU

Lighter CPU-only alternative: swap STT β†’ whisper-tiny.en (39 M) and LLM β†’ SmolLM2-360M-Instruct (360 M) in models.py.


Architecture

Browser mic  (16 kHz PCM)
     β”‚
     β–Ό  WebSocket binary frames
Silero VAD  ──────────────────────► discard noise/silence
     β”‚ speech segment detected
     β–Ό
Whisper base.en  ──────────────────► transcript text
     β”‚
     β–Ό
SmolLM2-1.7B  (TextIteratorStreamer)
     β”‚  token stream
     β–Ό
SentenceBuffer  ──► complete sentence
     β”‚                    β”‚
     β”‚          MMS-TTS-eng  (CPU executor)   ← overlap: LLM still generating!
     β”‚                    β”‚
     β”‚          PCM bytes ──► ws.send_bytes()
     β”‚                    β”‚
     β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  repeat until stream ends
     β”‚
     β–Ό
Browser  AudioQueue  ──► AudioContext playback

Streaming overlap benefit: while the browser plays sentence 1, the server is already synthesising sentence 2. This removes the full TTS latency from the inter-sentence gap, giving noticeably more natural turn-taking.


Project structure

sts-pipeline/
β”œβ”€β”€ app.py                      FastAPI server + WebSocket handler
β”œβ”€β”€ models.py                   All model loading & inference (STT/LLM/TTS/VAD)
β”œβ”€β”€ pipeline.py                 Streaming overlap pipeline
β”œβ”€β”€ sentence_buffer.py          Token-stream β†’ sentence boundary detector
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
└── static/
    β”œβ”€β”€ index.html              Browser UI
    β”œβ”€β”€ app.js                  WebSocket client + audio queue
    └── audio-capture-worklet.js  Mic capture @ 16 kHz (AudioWorklet)

Local development

# 1. Clone
git clone https://huggingface.co/spaces/<your-user>/voice-agent
cd voice-agent

# 2. Install (GPU)
pip install -r requirements.txt

# 2b. Install (CPU-only)
pip install torch==2.5.1+cpu torchaudio==2.5.1+cpu \
    --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt

# 3. Run
python app.py        # or: uvicorn app:app --port 7860
# Open http://localhost:7860

Models are downloaded automatically on first run (3 GB total) and cached in `/.cache/huggingface/hub`.


HuggingFace Spaces deployment

  1. Create a new Space β†’ Docker SDK.
  2. Push this repo as-is.
  3. The Space will build the Docker image and serve on port 7860.
  4. For GPU hardware: remove the CPU-only torch lines in Dockerfile and uncomment the plain pip install -r requirements.txt.

WebSocket protocol reference

Direction Frame type Payload
Client β†’ Server binary PCM int16, mono, 16 kHz, 640 B chunks
Client β†’ Server text {"type":"start"} or {"type":"stop"}
Server β†’ Client binary PCM int16, mono, 16 kHz (TTS audio)
Server β†’ Client text {"type":"transcript","text":"..."}
Server β†’ Client text {"type":"agent_start"}
Server β†’ Client text {"type":"agent_done","text":"...","latency_ms":000}
Server β†’ Client text {"type":"error","message":"..."}

License

Apache 2.0 β€” all component models carry their own licenses; see their respective HuggingFace model cards for terms of use.