🎯 Add HuggingFace Model Support for STT, TTS & LLM in Agent Pipeline ​
Priority: Medium | Type: Feature | Estimated Effort: 3-5 days ​
Context ​
We currently support a limited set of STT/TTS/LLM providers (Deepgram, Cartesia, ElevenLabs, Murf, Google, OpenAI, Sarvam). We want to expand our model testing capabilities by integrating HuggingFace the largest open-source AI model hub so we can benchmark different models for phone call agent quality, latency, and cost. Especially for Hindi language support.
This issue covers everything you need to know about HuggingFace, how the AI industry uses OpenAI-compatible APIs, and how to implement this cleanly in our existing provider architecture.
Background Knowledge (Read Before Starting) ​
What is HuggingFace? ​
HuggingFace (https://huggingface.co) is the largest platform for open-source AI models. Think of it as "GitHub for AI models". Key things to understand:
| Concept | What it is | Analogy |
|---|---|---|
| HuggingFace Hub | Repository hosting 800K+ AI models (LLMs, STT, TTS, image, etc.) | Like npm/PyPI but for AI models |
| Transformers library | Python library to download and run models locally | Like TensorFlow/PyTorch wrapper |
| Inference API (Serverless) | Free/paid API to run models without your own GPU. Rate-limited on free tier | Like a cloud function for AI |
| Inference Endpoints (Dedicated) | Deploy a model on a dedicated GPU server you control | Like AWS EC2 but for AI models |
| Text Generation Inference (TGI) | HuggingFace's optimized server for running LLMs. Exposes an OpenAI-compatible /v1/chat/completions endpoint | Like vLLM or Ollama |
| HF API Token | Your authentication key (starts with hf_) | Like an API key for any service |
What is the "OpenAI-Compatible API" Pattern? ​
This is an industry standard you must understand. OpenAI defined the API format for chat completions (/v1/chat/completions), and now almost every LLM provider copies this exact format. This means:
- You write code for OpenAI's API once
- You swap
base_urlandapi_keyto use a completely different provider - The request/response format stays the same
Providers that follow this pattern:
- HuggingFace TGI, Groq, DeepSeek, Fireworks AI, Together AI, OpenRouter, Ollama, vLLM, Cerebras, Perplexity, xAI, Mistral, and 50+ more
LiveKit's OpenAI plugin already supports this every openai.LLM(), openai.STT(), and openai.TTS() class accepts a base_url parameter to point to any compatible endpoint.
# OpenAI (default)
llm = openai.LLM(model="gpt-4o-mini")
# Same code, different provider just change base_url + api_key
llm = openai.LLM(
model="meta-llama/Llama-3.3-70B-Instruct",
base_url="https://router.huggingface.co/v1",
api_key="hf_xxxxx"
)HuggingFace Products We'll Use ​
1. Serverless Inference API (for LLM) ​
- URL:
https://router.huggingface.co/v1(OpenAI-compatible) - Auth:
Authorization: Bearer hf_YOUR_TOKEN - Free tier: Rate-limited, good for testing
- Pro tier ($9/mo): Higher rate limits
- Models: Llama 3.3, Mistral, Qwen, DeepSeek, Gemma, etc.
- Docs: https://huggingface.co/docs/api-inference/
2. Serverless Inference API (for STT) ​
- URL:
https://api-inference.huggingface.co/models/{model_id} - NOT OpenAI-compatible sends raw audio bytes, returns JSON
{"text": "..."} - Models:
openai/whisper-large-v3-turbo,vasista22/whisper-hindi-large-v2, etc. - Limitation: Not streaming sends full audio chunk, gets full text back
3. Serverless Inference API (for TTS) ​
- URL:
https://api-inference.huggingface.co/models/{model_id} - NOT OpenAI-compatible sends text, returns raw audio bytes
- Models:
facebook/mms-tts-hin(Hindi),ai4bharat/indic-parler-tts(Hindi),Qwen/Qwen3-TTS, etc. - Limitation: Not streaming sends full text, gets full audio back
4. Inference Endpoints (Dedicated for production) ​
- Deploy any model on a dedicated GPU
- TGI endpoints ARE OpenAI-compatible for LLMs
- Custom endpoints for STT/TTS need the same raw audio/text API
- Docs: https://huggingface.co/docs/inference-endpoints/
Key Python Libraries ​
| Library | Purpose | Install |
|---|---|---|
huggingface_hub | Official HF Python client. Handles auth, API calls, model downloads | pip install huggingface_hub |
openai | OpenAI Python client. Works with any OpenAI-compatible endpoint including HF | Already installed (via livekit-agents) |
aiohttp | Async HTTP client. Use for raw STT/TTS API calls to HF | Already installed |
transformers | Run models locally (NOT needed for API-based approach) | Don't install unless doing local inference |
Important: For our use case, we primarily need huggingface_hub for the STT/TTS raw API calls, and the existing openai library (via LiveKit's OpenAI plugin) for LLM. We do NOT need transformers since we're calling APIs, not running models locally.
What to Implement ​
Task 1: HuggingFace LLM Provider ​
Difficulty: Easy HuggingFace LLM API is OpenAI-compatible, so we use LiveKit's existing OpenAI plugin.
File: Agent/src/providers/llm_providers.py
Add a HuggingFace class to the existing registry:
import os
from livekit.plugins import openai, google
class HuggingFaceLLM:
def __init__(self, model="meta-llama/Llama-3.3-70B-Instruct", temperature=0.2, max_tokens=200):
self.model = model
self.temperature = temperature
self.max_tokens = max_tokens
def build(self):
return openai.LLM(
model=self.model,
base_url="https://router.huggingface.co/v1",
api_key=os.getenv("HUGGINGFACE_API_KEY"),
temperature=self.temperature,
max_completion_tokens=self.max_tokens
)
# Add to registry
LLM_REGISTRY = {
"openai": OpenAI,
"google": Google,
"huggingface": HuggingFaceLLM,
}Hindi-capable LLM models to test:
meta-llama/Llama-3.3-70B-Instructgood multilingual, Hindi includedQwen/Qwen2.5-72B-Instructstrong Hindigoogle/gemma-2-27b-itdecent Hindimistralai/Mistral-Small-24B-Instruct-2501fast, decent Hindi
Task 2: HuggingFace STT Provider (Custom Plugin) ​
Difficulty: Medium HuggingFace STT API is NOT OpenAI-compatible. We need to write a custom LiveKit STT class.
File: Agent/src/providers/stt_providers.py
HuggingFace STT API works like this:
POST https://api-inference.huggingface.co/models/{model_id}
Headers: Authorization: Bearer hf_xxxxx
Body: raw audio bytes (wav/flac/mp3)
Response: {"text": "transcribed text here"}You need to implement a class that:
- Extends LiveKit's
stt.STTbase class - Receives audio frames from the LiveKit pipeline
- Buffers audio (HF API is not streaming it needs complete audio chunks)
- Sends audio to HuggingFace API
- Returns
SpeechEventobjects that LiveKit understands
Key considerations:
- HuggingFace STT is NOT streaming it processes complete audio chunks, not real-time streams
- You MUST use LiveKit's
StreamAdapter+sileroVAD to buffer speech segments before sending to HF - Audio format: HF expects wav/flac bytes. LiveKit provides raw PCM frames you'll need to convert
- Latency will be higher than Deepgram (which is streaming). This is expected for testing purposes
Follow the existing BaseSTT pattern in stt_providers.py. The custom STT class should be a separate file (e.g., Agent/src/providers/custom/huggingface_stt.py) that gets imported into the registry.
Hindi STT models to test:
openai/whisper-large-v3-turbobest overall, supports Hindivasista22/whisper-hindi-large-v2fine-tuned specifically for Hindiai4bharat/indicwhisper-large-v2-hiIndian language specialistopenai/whisper-large-v3highest accuracy, slower
Reference: Look at how LiveKit's own StreamAdapter works for non-streaming STT: https://docs.livekit.io/agents/v1/integrations/stt/ (see "VAD and StreamAdapter" section)
Task 3: HuggingFace TTS Provider (Custom Plugin) ​
Difficulty: Medium-Hard HuggingFace TTS API is NOT OpenAI-compatible. Needs custom LiveKit TTS class.
File: Agent/src/providers/tts_providers.py
HuggingFace TTS API works like this:
POST https://api-inference.huggingface.co/models/{model_id}
Headers: Authorization: Bearer hf_xxxxx
Body: {"inputs": "Text to speak"}
Response: raw audio bytes (wav/flac)You need to implement a class that:
- Extends LiveKit's
tts.TTSbase class - Receives text from the LLM output
- Sends text to HuggingFace API
- Converts returned audio bytes to
SynthesizedAudioframes that LiveKit can play - Handles chunking for long text, split into sentences and synthesize each chunk
Key considerations:
- HuggingFace TTS is NOT streaming it generates the full audio at once
- Latency will be higher than Cartesia (which streams audio). This is expected for testing
- Audio format: HF returns wav/flac. LiveKit needs raw PCM frames at the right sample rate you'll need to decode
- For sentence chunking, use LiveKit's built-in
tts_text_transformsor implement your own sentence splitter - Some HF TTS models have a max input length (usually ~500 chars). Handle this gracefully
Follow the existing BaseTTS pattern in tts_providers.py. Put the custom class in Agent/src/providers/custom/huggingface_tts.py.
Hindi TTS models to test:
facebook/mms-tts-hinMeta's Massively Multilingual Speech, good Hindiai4bharat/indic-parler-ttsIndian language specialist, natural soundingQwen/Qwen3-TTS-12Hz-1.7B-CustomVoicenewer, high qualityparler-tts/parler-tts-large-v1good quality, English + some Hindi
Task 4: Environment & Config Updates ​
Files to update:
.envAdd:HUGGINGFACE_API_KEY=hf_xxxxxxxxxxxxxxxxxxxxxxxxxrequirements.txtAdd:huggingface_hub>=0.25.0(The
openailibrary is already installed vialivekit-agents[openai])agent_meta_schema.pyNo changes needed. The existingstt_provider,tts_provider,llm_providerfields already accept any string. Just pass"huggingface"from the frontend/config.shared/agent_config.jsonAdd a test preset:json{ "id": "preset_huggingface_test", "name": "HuggingFace Test", "description": "Testing with HuggingFace open-source models", "cost_per_min": 1, "show": false, "llm_provider": "huggingface", "llm_model": "meta-llama/Llama-3.3-70B-Instruct", "tts_provider": "huggingface", "tts_model": "facebook/mms-tts-hin", "stt_provider": "huggingface", "stt_model": "openai/whisper-large-v3-turbo", "supported_languages": ["hi", "en"], "default_tts_language": "hi", "default_stt_language": "hi" }
Code Quality Requirements ​
Follow Existing Patterns ​
- STT/TTS providers MUST extend
BaseSTT/BaseTTSwithfrom_meta()+build()pattern - LLM provider follows the constructor +
build()pattern - All providers register in their respective
*_REGISTRYdicts - Use
setup_logger("huggingface_xxx")for all logging
Error Handling ​
- Handle HuggingFace API rate limits (HTTP 429) with exponential backoff
- Handle model loading delays (HF serverless models can take 20-60s to cold start HTTP 503 with
estimated_timein response) - Handle audio format conversion errors gracefully
- Log all API errors with provider name, model name, and HTTP status
- Never crash the agent session fall back to default provider if HF fails
Production Readiness ​
- API key from env var only (
HUGGINGFACE_API_KEY), never hardcoded - Timeout configuration: HF API can be slow on cold starts. Set reasonable timeouts (30s for first call, 10s for subsequent)
- Add
X-Wait-For-Model: trueheader for serverless API calls this tells HF to wait for model to load instead of returning 503 - Audio conversion: Use
wavestdlib module for wav encoding/decoding. Avoid heavy dependencies
File Structure ​
Agent/src/providers/
├── llm_providers.py # Add HuggingFaceLLM class here
├── stt_providers.py # Add HuggingFaceSTT to registry here
├── tts_providers.py # Add HuggingFaceTTS to registry here
└── custom/
├── __init__.py
├── huggingface_stt.py # Custom STT implementation
└── huggingface_tts.py # Custom TTS implementationTesting Plan ​
Phase 1: LLM Only (Day 1) ​
- Implement
HuggingFaceLLMinllm_providers.py - Test with existing Deepgram STT + Cartesia TTS (only swap the LLM)
- Verify Hindi conversation quality with Llama 3.3 70B
- Compare response latency vs current Google Gemini
Phase 2: STT (Day 2-3) ​
- Implement
HuggingFaceSTTcustom plugin - Test with Whisper large-v3-turbo for Hindi transcription
- Compare accuracy vs Deepgram nova-3 on Hindi phone calls
- Measure latency impact (non-streaming vs Deepgram streaming)
Phase 3: TTS (Day 3-4) ​
- Implement
HuggingFaceTTScustom plugin - Test with
facebook/mms-tts-hinfor Hindi speech - Compare voice quality vs Cartesia sonic-3
- Measure latency impact (non-streaming vs Cartesia streaming)
Phase 4: Full Pipeline Test (Day 5) ​
- Run full HuggingFace pipeline: HF STT → HF LLM → HF TTS
- Make test phone calls and evaluate end-to-end quality
- Document latency, quality, and cost comparison
Useful Links ​
| Resource | URL |
|---|---|
| HuggingFace Inference API docs | https://huggingface.co/docs/api-inference/ |
| HuggingFace Inference Endpoints | https://huggingface.co/docs/inference-endpoints/ |
| HF OpenAI-compatible Messages API | https://huggingface.co/docs/text-generation-inference/messages_api |
| HuggingFace Hub Python library | https://huggingface.co/docs/huggingface_hub/ |
| LiveKit custom STT docs | https://docs.livekit.io/agents/v1/integrations/stt/ |
| LiveKit custom TTS docs | https://docs.livekit.io/agents/integrations/tts/ |
| LiveKit OpenAI plugin (base_url) | https://docs.livekit.io/python/livekit/plugins/openai/index.html |
| LiveKit all plugins list | https://docs.livekit.io/reference/python/livekit/plugins/index.html |
| Hindi STT models on HF | https://huggingface.co/models?language=hi&pipeline_tag=automatic-speech-recognition |
| Hindi TTS models on HF | https://huggingface.co/models?language=hi&pipeline_tag=text-to-speech |
Acceptance Criteria ​
- [ ]
huggingfaceworks asllm_providerin agent config uses HF Inference API via OpenAI-compatible endpoint - [ ]
huggingfaceworks asstt_providercustom STT class handles audio → text via HF API - [ ]
huggingfaceworks astts_providercustom TTS class handles text → audio via HF API - [ ] Hindi language works for all three (STT, TTS, LLM)
- [ ] Proper error handling for rate limits, cold starts, and API failures
- [ ] Falls back gracefully if HF API is unavailable
- [ ]
HUGGINGFACE_API_KEYenv var documented in.env.example - [ ] Test preset added to
agent_config.json - [ ] Code follows existing provider registry pattern
- [ ] Logging matches existing format using
setup_logger()