uncloseai.

Open-Source Speech-to-Text

Speech-to-Text

uncloseai-speech listens as well as speaks: send any recording to POST https://speech.ai.unturf.com/v1/audio/transcriptions and get its words back, with word timestamps or ready-made subtitles. Free, no API keys, and OpenAI-compatible: model stt-1-parakeet also answers to whisper-1.

We recommend Parakeet for listening (CPU or GPU) and F5-TTS for speaking. Your audio stays on our own hardware, never a browser vendor's or a cloud speech API.

Try It

Tap our microphone and speak, or pick an audio file (up to 25 MB).

Recommended: Parakeet

NVIDIA Parakeet TDT 0.6B v3 (CC-BY-4.0), run through onnx-asr. 25 languages detected automatically, with punctuation: Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Ukrainian.

Runs onMemorySpeed
CPU (fp32)~2.4 GB RAM~25x realtime
GPU (fp16, our prod)~1.7 GB VRAM~140x realtime: 84 s of audio in about a second

Word error rate on LibriSpeech test-clean through our production settings: 1.93% on 200 short utterances and 2.69% on 12 long recordings, with no sentences lost. fp16 matches fp32. Never use int8: our test build lost up to 41 percent of words on long audio.

Quick Start

curl https://speech.ai.unturf.com/v1/audio/transcriptions -F file=@clip.wav -F model=whisper-1
# {"text":"but the windows are patched with wooden panes, and the door, I think, is like the gate. It is never opened.","usage":{"type":"duration","seconds":8.03}}

curl https://speech.ai.unturf.com/v1/audio/transcriptions -F file=@talk.mp4 -F response_format=srt -o talk.srt
from openai import OpenAI

client = OpenAI(api_key="not-needed", base_url="https://speech.ai.unturf.com/v1")
print(client.audio.transcriptions.create(model="whisper-1", file=open("meeting.mp3", "rb")).text)

words = client.audio.transcriptions.create(
    model="whisper-1", file=open("meeting.mp3", "rb"),
    response_format="verbose_json", timestamp_granularities=["word"],
).words
// Browser, with uncloseai.js loaded
const text = await window.uncloseai.transcribeAudio(audioBlob);
const mic = window.uncloseai.createMicButton(document.querySelector("textarea"));

API Reference

FieldValues
fileRequired. Any audio or video ffmpeg reads (wav, mp3, m4a, mp4, ogg, webm, flac), up to 25 MB.
modelstt-1-parakeet (default), whisper-1, parakeet-tdt-0.6b-v3
response_formatjson (default), text, verbose_json, srt, vtt
timestamp_granularities[]With verbose_json: segment (default), word
languageOptional and echoed back; Parakeet detects language itself.

Segments are whole sentences, so subtitles read cleanly. Real verbose_json, trimmed:

{
  "duration": 8.03,
  "text": "but the windows are patched with wooden panes, and the door, I think, is like the gate. It is never opened.",
  "segments": [
    {"id": 0, "start": 0.436, "end": 6.436, "text": "but the windows are patched with wooden panes, and the door, I think, is like the gate."},
    {"id": 1, "start": 6.436, "end": 8.03, "text": "It is never opened."}
  ],
  "words": [{"word": "but", "start": 0.436, "end": 0.596}, {"word": "the", "start": 0.596, "end": 0.756}]
}

Errors return HTTP 400 with JSON (undecodable audio, unknown model, over 25 MB). Silent clips return empty text.

Self-Hosting

Transcription ships in uncloseai-speech beside F5-TTS. On any Linux CPU:

git clone https://git.unturf.com/engineering/unturf/uncloseai-speech.git
cd uncloseai-speech
make apt-deps && make venv && make venv-run   # F5-TTS + Parakeet on :8000
make test

For GPU transcription set STT_DEVICE=cuda with onnxruntime-gpu matching torch's CUDA version; it falls back to CPU if CUDA cannot start. NVIDIA, AMD and Mac setup live in our README (AGPL v3).

Questions & Community

Ask questions, share your deployments, or tell us how transcription works for your language below!