Python API
Overview
Section titled “Overview”from vaak import get_backend, load_audio
audio = load_audio("clip.wav") # float32 numpy, 16 kHz monobackend = get_backend("faster-whisper:small") # lazy: weights load on first useresult = backend.transcribe(audio, language="hi") # language=None -> auto-detectresult.text # strresult.language # "hi"result.segments # list[Segment(start: float, end: float, text: str)]result.duration # audio secondsresult.rtf # real-time factor = processing_time / duration (lower is faster)result.backend # "faster-whisper"result.model # "small"load_audio
Section titled “load_audio”from vaak import load_audio
audio = load_audio(src, sample_rate=16000)src: a path, a file-like object, or raw bytes. Anything ffmpeg can decode.- Returns a mono
np.ndarrayof dtypefloat32in the range[-1, 1]atsample_rate.
All backends expect 16 kHz. If you already have a numpy array at another rate, pass sample_rate to transcribe() and the backend resamples.
get_backend
Section titled “get_backend”from vaak import get_backend
backend = get_backend("faster-whisper:small", device="auto")spec:<backend>:<model>. See model specs.device:"auto","cpu"or"cuda".autopicks CUDA when available.**kwargsare passed to the backend constructor. For examplecompute_type="int8"for faster-whisper.
Construction is cheap. Weights load on the first transcribe() call, or when you call backend.load() explicitly, which is useful to pay the cost at startup.
Backend
Section titled “Backend”Every backend implements this ABC from vaak/backends/base.py:
class Backend(ABC): name: str # registry key, e.g. "faster-whisper" model_id: str # part after the colon languages: set[str] | None # ISO 639-1 codes supported; None = multilingual/any device: str # "auto" | "cpu" | "cuda" def load(self) -> None # idempotent def transcribe(self, audio: np.ndarray, sample_rate: int = 16000, language: str | None = None) -> TranscriptCheck backend.languages before sending audio in a language the model cannot handle. None means the model is multilingual, for example Whisper. indic-conformer:hi reports {"hi"}.
Transcript and Segment
Section titled “Transcript and Segment”@dataclassclass Segment: start: float # seconds end: float # seconds text: str
@dataclassclass Transcript: text: str language: str segments: list[Segment] duration: float rtf: float backend: str model: strBoth are plain dataclasses. dataclasses.asdict(result) gives the same JSON the HTTP API returns.
Registry
Section titled “Registry”from vaak.backends import list_backends
for info in list_backends(): print(info.name, info.available, info.example)list_backends() returns a BackendInfo per registered backend without importing heavy runtimes. available is whether the runtime imports cleanly.
Metrics
Section titled “Metrics”from vaak.metrics import wer, cer, normalize_text
ref = normalize_text("यह एक परीक्षण है।", "hi")hyp = normalize_text(result.text, "hi")print(wer(ref, hyp), cer(ref, hyp))normalize_text applies NFC normalisation, lowercases Latin script, strips punctuation including । and ॥, and collapses whitespace. Always normalise both sides. See the benchmarks methodology.
Batch example
Section titled “Batch example”from pathlib import Pathfrom vaak import get_backend, load_audio
backend = get_backend("faster-whisper:large-v3-turbo", device="cuda")backend.load()
for path in sorted(Path("calls").glob("*.wav")): result = backend.transcribe(load_audio(path), language="hi") print(path.name, f"rtf={result.rtf:.3f}", result.text[:80])Writing a backend
Section titled “Writing a backend”Subclass Backend, implement load() and transcribe(), and register it in vaak/backends/__init__.py under a new prefix. Keep the heavy import inside load() so vaak models and the registry stay fast. See contributing.