46 lines
1.3 KiB
Python
46 lines
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Robo Pest STT relay — faster-whisper on nightmare's RTX 4080 SUPER.
|
|
|
|
POST /transcribe (body: raw PCM 16kHz s16le mono bytes) -> {"text": "..."}
|
|
GET /health -> {"status": "ok", "model": ...}
|
|
"""
|
|
import io
|
|
import os
|
|
import struct
|
|
import numpy as np
|
|
from fastapi import FastAPI, Request
|
|
from faster_whisper import WhisperModel
|
|
|
|
MODEL_NAME = os.environ.get("STT_MODEL", "small.en")
|
|
DEVICE = os.environ.get("STT_DEVICE", "cuda")
|
|
|
|
app = FastAPI()
|
|
model = WhisperModel(MODEL_NAME, device=DEVICE, compute_type="float16")
|
|
|
|
|
|
def pcm16_to_float32(data: bytes) -> np.ndarray:
|
|
n = len(data) // 2
|
|
ints = struct.unpack(f"<{n}h", data[: n * 2])
|
|
return np.array(ints, dtype=np.float32) / 32768.0
|
|
|
|
|
|
@app.get("/health")
|
|
def health():
|
|
return {"status": "ok", "model": MODEL_NAME, "device": DEVICE}
|
|
|
|
|
|
@app.post("/transcribe")
|
|
async def transcribe(request: Request):
|
|
body = await request.body()
|
|
if not body:
|
|
return {"text": ""}
|
|
audio = pcm16_to_float32(body)
|
|
segments, info = model.transcribe(audio, language="en", beam_size=1, vad_filter=True)
|
|
text = " ".join(s.text.strip() for s in segments).strip()
|
|
return {"text": text, "duration": round(info.duration, 2)}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=8765)
|