malloc-app / app /speech.py
sudhanshu388's picture
Upload 64 files
0d374d2 verified
Raw
History Blame Contribute Delete
1.55 kB
"""
Speech-to-text via faster-whisper.
Model loads lazily on first use and is cached for the process lifetime
(loading is slow, ~seconds; keep it out of the request hot path after
the first call). Runs on CPU by default -- fine for short voice memos,
not tuned for long-form transcription.
"""
import logging
from functools import lru_cache
logger = logging.getLogger("memora.speech")
# "tiny" / "base" / "small" - tradeoff between speed and accuracy.
# "base" is a reasonable default for short voice commands.
WHISPER_MODEL_SIZE = "base"
class TranscriptionError(RuntimeError):
"""Raised when audio transcription fails."""
@lru_cache(maxsize=1)
def _get_model():
from faster_whisper import WhisperModel
logger.info("Loading faster-whisper model (%s) - first call only", WHISPER_MODEL_SIZE)
return WhisperModel(WHISPER_MODEL_SIZE, device="cpu", compute_type="int8")
def transcribe(audio_path: str) -> str:
"""
audio_path: path to a local audio file (wav/mp3/m4a/etc).
Returns the transcribed text. Raises TranscriptionError on failure.
"""
try:
model = _get_model()
segments, _info = model.transcribe(audio_path)
text = " ".join(segment.text.strip() for segment in segments)
except Exception as exc: # faster-whisper doesn't expose a narrow exception type
logger.exception("Transcription failed")
raise TranscriptionError(str(exc)) from exc
if not text.strip():
raise TranscriptionError("No speech detected in audio")
return text.strip()