File size: 2,292 Bytes
d797bdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4e3de1b
 
d797bdc
4e3de1b
 
 
 
 
 
 
 
d797bdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""
Whisper STT wrapper — ROCm-compatible.

Two modes:
  1. Local Whisper (runs on the same MI300X, via openai-whisper or faster-whisper)
  2. Remote endpoint (OpenAI-compatible /v1/audio/transcriptions)

Set STT_MODE env var to "local" or "remote". Defaults to "remote" in HF Space.
"""

import os
from pathlib import Path

STT_MODE     = os.getenv("STT_MODE", "remote")
STT_URL      = os.getenv("STT_URL", "")
WHISPER_SIZE = os.getenv("WHISPER_SIZE", "base")   # tiny/base/small/medium


# ---------------------------------------------------------------------------
# Remote path (OpenAI-compatible endpoint — used in HF Space)
# ---------------------------------------------------------------------------

def _transcribe_remote(audio_path: str) -> str:
    import httpx
    url = f"{STT_URL.rstrip('/')}/v1/audio/transcriptions"
    with open(audio_path, "rb") as f:
        r = httpx.post(
            url,
            files={"file": (os.path.basename(audio_path), f, "audio/wav")},
            data={"model": "whisper-1"},
            timeout=30.0,
        )
    r.raise_for_status()
    return r.json()["text"].strip()


# ---------------------------------------------------------------------------
# Local path (runs on MI300X with ROCm)
# ---------------------------------------------------------------------------

_whisper_model = None

def _load_whisper():
    global _whisper_model
    if _whisper_model is None:
        import whisper
        _whisper_model = whisper.load_model(WHISPER_SIZE)
    return _whisper_model


def _transcribe_local(audio_path: str) -> str:
    model = _load_whisper()
    result = model.transcribe(audio_path, fp16=True, language="en")
    return result["text"].strip()


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def transcribe(audio_path: str) -> str:
    """Transcribe audio file to text. Returns empty string on failure."""
    if not audio_path or not Path(audio_path).exists():
        return ""
    try:
        if STT_MODE == "local":
            return _transcribe_local(audio_path)
        return _transcribe_remote(audio_path)
    except Exception as e:
        print(f"[STT] Error: {e}")
        return ""