Spaces:
Running
Running
| # backend/voice/stt.py | |
| # Real STT using faster-whisper (local) with Deepgram fallback | |
| import os | |
| APP_DATA_DIR = os.environ.get("JARVIS_APP_DATA_DIR", ".") | |
| class STTPipeline: | |
| def __init__(self, model_size="large-v3"): | |
| import torch | |
| from faster_whisper import WhisperModel | |
| # Downloads real Whisper model to {app_data_dir}/models/whisper/ | |
| self.model = WhisperModel(model_size, | |
| device="cuda" if torch.cuda.is_available() else "cpu", | |
| compute_type="float16" if torch.cuda.is_available() else "int8", | |
| download_root=f"{APP_DATA_DIR}/models/whisper") | |
| async def transcribe(self, audio_bytes: bytes) -> tuple[str, str]: | |
| # language=None forces auto-detection | |
| segments, info = self.model.transcribe(audio_bytes, beam_size=5, language=None) | |
| text = " ".join(s.text for s in segments) | |
| detected_lang = info.language | |
| if info.duration < 2.0 and hasattr(self, "last_known_language"): | |
| detected_lang = self.last_known_language | |
| else: | |
| self.last_known_language = detected_lang | |
| import gc, torch | |
| del segments | |
| gc.collect() | |
| if torch.cuda.is_available(): | |
| torch.cuda.empty_cache() | |
| return text, detected_lang | |
| def unload(self): | |
| import gc | |
| import torch | |
| if hasattr(self, 'model'): | |
| del self.model | |
| gc.collect() | |
| if torch.cuda.is_available(): | |
| torch.cuda.empty_cache() | |