Skip to content

Repository files navigation

ru-stt-tui

Russian speech-to-text terminal TUI powered by GigaAM-v3 (Hugging Face Hub, revision e2e_rnnt).

Push-to-talk Russian speech recognition in your terminal. Records from your microphone, transcribes with GigaAM-v3-e2e-rnnt, and shows timestamped text in a chat-style TUI. Copies to clipboard with Ctrl+C, saves to .txt or .md with Ctrl+S, and exits cleanly with Ctrl+Q.

The console-script entry point is wired via pyproject.toml's [project.scripts]; the package entry is src/ru_stt_tui/__main__.py. The root-level main.py from the initial empty repo is not part of this project.

Features

  • Push-to-talk: press Space to start, press again to stop & transcribe
  • In-app device picker: lists microphones at startup, persists your choice in config.toml
  • Atomic transcription: status bar shows Transcribing 1.4s while the model runs, then text appears in one shot
  • Russian text with punctuation and casing preserved (e2e_rnnt model variant)
  • GPU auto-detect: PyTorch fp16 on CUDA when available; CPU fallback is plain PyTorch (no ffmpeg or ONNX runtime needed)
  • Clipboard: Ctrl+C copies the last segment via pyperclip
  • Save: Ctrl+S opens an in-TUI path/format picker (.txt or .md)
  • Worker recovery: Ctrl+R restarts the ASR worker on failure
  • Cancellation: Esc cancels an in-flight recording or transcription
  • Cross-platform: Windows, macOS, Linux (Python 3.10+)

TUI layout

┌─ Transcript ─────────────────────────────────────────────────────┐
│ [14:23:01] Привет, мир.                                         │
│ [14:23:18] Как дела?                                             │
│ [14:24:02] Сегодня хорошая погода.                              │
└──────────────────────────────────────────────────────────────────┘
┌─ Status ─────────────────────────────────────────────────────────┐
│ READY  |  Space: record  Ctrl+C: copy  Ctrl+S: save  Ctrl+Q: quit│
└──────────────────────────────────────────────────────────────────┘

Requirements

  • Python 3.10 or newer (tested on 3.12)
  • A working microphone (PortAudio backend; sounddevice ships its own wheels on Windows, macOS, and Linux)
  • ~3 GB free disk for the GigaAM-v3 model cache (~/.cache/huggingface/)
  • First run downloads the model (~2.5 GB) from ai-sage/GigaAM-v3 (revision e2e_rnnt) on Hugging Face Hub

The model is loaded via transformers.AutoModel.from_pretrained(...) and weights are stored under the standard HF cache directory — no separate ~/.cache/gigaam/ directory is used.

Install

Primary (editable, for development):

pip install -e .

Alternatives:

uv pip install -e .
# or
pipx install .

Usage

Basic launch:

ru-stt-tui

Useful flags:

Flag Purpose
--list-devices List available input devices and exit
--device N Override the audio device (skips the picker)
--setup-only Download the model (~2.5 GB) and exit (no TUI)
--cpu Force CPU inference (skip the CUDA probe)
--no-progress Print progress to stderr (no TUI progress bar)
--timing Print per-transcription timing to stderr and append a JSONL line to ~/.cache/ru-stt-tui/timings.jsonl
--config PATH Override the config file path
--version Print version and exit
--help Show help and exit

Hotkeys (in the TUI)

Key Action
Space Toggle push-to-talk (start/stop recording)
Ctrl+C Copy the last segment to clipboard
Ctrl+S Open the save dialog (path + format)
Ctrl+R Restart the ASR worker (recovery)
Esc Cancel in-flight recording or transcription
Ctrl+Q Quit cleanly

Config

The app reads and writes a TOML config file at:

  • Windows: %APPDATA%\ru-stt-tui\config.toml
  • macOS: ~/Library/Application Support/ru-stt-tui/config.toml
  • Linux/other: ~/.config/ru-stt-tui/config.toml (or $XDG_CONFIG_HOME/ru-stt-tui/config.toml)

The path falls back through a three-tier chain (platform-native dir → OS env-var override → /tmp/ru-stt-tui) so the app never crashes on a non-ASCII Windows username. Use --config PATH to override.

Troubleshooting

"No audio input devices found" / crash at startup

The TUI's device picker requires a working PortAudio backend. If you see a crash at startup (e.g. PortAudioError), your system may be missing PortAudio libraries or you may be on a headless server without audio.

  • Linux: apt install libportaudio2 (Debian/Ubuntu) or equivalent
  • macOS: PortAudio ships with the OS; check brew list portaudio
  • Windows: wheels ship with PortAudio; check microphone permissions

Known v1 issue (F9): when PortAudio raises inside sounddevice.query_devices() (e.g. on a headless server), list_input_devices() surfaces the underlying KeyError/PortAudioError and the TUI can crash before rendering the picker. A graceful "no devices" fallback is tracked for v1.1. Workaround for now: ensure PortAudio is installed before running the TUI.

Cyrillic displays as mojibake on Windows legacy console

If you're on Windows using cmd.exe (not Windows Terminal), the console may default to a non-UTF-8 code page. The TUI auto-fixes this on startup by running chcp 65001. If that fails, run it manually before launching the app:

chcp 65001
ru-stt-tui

Model cache corruption

If the GigaAM-v3 download is interrupted, the cache may be incomplete. Delete the cache and re-run:

# Linux/macOS
rm -rf ~/.cache/huggingface/hub/models--ai-sage--GigaAM-v3

# Windows (PowerShell)
Remove-Item -Recurse -Force "$env:USERPROFILE\.cache\huggingface\hub\models--ai-sage--GigaAM-v3"

Then run ru-stt-tui --setup-only to re-download.

Out of disk space during model load

The first run needs ~3 GB free in your home directory. The app checks for this before downloading; if you're below the threshold it prints a clear error and aborts (no partial download).

Slow CPU inference

GigaAM-v3-e2e-rnnt on a modern CPU transcribes a 2-second utterance in a few seconds. For real-time-ish feedback, use a GPU. The first CUDA-capable GPU detected is used automatically.

ffmpeg is NOT a dependency

Unlike the upstream GigaAM README, this project bypasses the model's internal ffmpeg-based load_audio path. Microphone audio is written to a temporary 16 kHz mono WAV via soundfile and fed to model.embed_audio(...) directly. You do not need to install ffmpeg to use the app.

Development

Clone and install with dev dependencies:

git clone <repo-url>
cd ru-stt-tui
pip install -e ".[dev]"

Run tests:

pytest tests/ -v

Lint:

ruff check src tests

End-to-end (requires real mic + downloaded model):

RUN_E2E=1 pytest tests/test_e2e_recording.py -v

Architecture

The app has a single async event loop (Textual's asyncio loop) running on the main thread, a PortAudio callback that captures microphone frames into a worker-fed queue, and a dedicated threading.Thread ASR worker that decodes RNN-T output and posts results back to the UI via app.call_from_thread.

  [mic] -> sounddevice.InputStream (16 kHz mono int16)
            -> AudioCapture (PTT, 60s cap, watchdog)
            -> Recording (in-memory NumPy + temp WAV path)
                  v
            queue.Queue -> ASRWorker (background thread)
                  v
            HuggingFace GigaAM-v3-e2e-rnnt (~2.5 GB)
            model.embed_audio(tmp.wav) -> features -> RNN-T greedy decode
            (PyTorch GPU when available, PyTorch CPU otherwise)
                  v
            Segment (text + start_time + end_time + confidence?)
                  v
            TranscriptBuffer (asyncio.Lock)
                  v
            Textual TUI (RichLog + status bar)
                  v
            [User] -> Ctrl+C (clipboard) | Ctrl+S (save)

The ASR worker runs on its own thread to keep the TUI's event loop responsive. All worker-to-UI handoffs go through app.call_from_thread to maintain thread safety.

License

MIT (matches GigaAM's license).

Acknowledgments

  • GigaAM by SberDevices — the state-of-the-art Russian ASR model. The ai-sage/GigaAM-v3 Hugging Face Hub repo is the v3 distribution.
  • Textual — modern async TUI framework for Python.
  • Hugging Face Transformers — the model loading and inference stack.

v1.1 follow-ups (tracked but not implemented)

  • F1 — Word-level confidence (RNN-T token probs)
  • F2 — Real-time streaming word-by-word UI
  • F3 — INT8 quantization for faster CPU inference
  • F4 — Multi-language support (Russian only in v1)
  • F5 — Auto-save on quit
  • F6 — CI smoke matrix (Linux + macOS)
  • F7 — ONNX + CUDAExecutionProvider for low-VRAM GPUs
  • F8 — Long-form audio (>60s) via chunked decoding
  • F9 — Graceful PortAudio-missing handling (no crash on startup; TUI shows "no devices" fallback)

About

AI real-time voice assistant supporting local edge devices

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages