TNT 🧨
🌐 appautomaton.com/tnt-asr — the project landing page.
Terminal voice-to-text. Tap Space, speak, tap Space — your words land in the transcript and on the clipboard.
Qwen3-ASR-1.7B runs in-process on the Apple GPU via mlx-speech as an 8-bit (int8) quantized checkpoint — ~2.5 GB resident: the model loads once, stays resident, and transcribes a short take in a fraction of a second. Fully local — no cloud, no runtime network calls. The microphone is captured natively through AVFoundation by a small Swift helper process, so a misbehaving audio stack can never trap the mic: TNT just kills the helper and macOS releases it.
Features
- In-process GPU inference — pure MLX, no PyTorch
- 8-bit quantized — int8 weights (~2.5 GB), about half the memory of BF16 with a faster decode
- Resident model — loads once in the background at startup; every take is warm
- Native mic capture — AVFoundation via an isolated Swift helper process; the mic can always be reclaimed
- English, Chinese, and mixed speech — language auto-detected, or forced via env var
- Live braille oscilloscope — real audio levels while you record
- Clipboard-first — new transcriptions auto-copy; click any past entry to copy it again
- Responsive TUI — side-rail layout on wide terminals, stacked on narrow ones
Setup
git clone https://github.com/appautomaton/tnt-asr.git
cd tnt-asr
uv sync
./bootstrap-mlx-asr.sh # downloads + links the int8 checkpoint (~2.5 GB, cached by Hugging Face)
uv run tnt
Or install from PyPI (automaton-tnt):
uv tool install automaton-tnt
TNT_MLX_MODEL=/path/to/qwen3-asr-1.7b-int8-mlx tnt
(Instead of exporting TNT_MLX_MODEL, you can symlink the checkpoint at
~/.local/share/tnt/qwen3-asr-mlx.)
Model checkpoint
TNT expects a converted Qwen3-ASR-1.7B MLX checkpoint. A ready-to-use int8 build (~2.5 GB) is published at appautomaton/qwen3-asr-1.7b-int8-mlx. The bootstrap script takes three forms:
./bootstrap-mlx-asr.sh # download the int8 build from Hugging Face, then link it
./bootstrap-mlx-asr.sh <hf-repo-id> # download a specific Hugging Face repo
./bootstrap-mlx-asr.sh /path/to/checkpoint # link a checkpoint you already have (no download)
Downloads use huggingface_hub (already installed via mlx-speech) and land in
the shared Hugging Face cache (~/.cache/huggingface); the script symlinks
bin/qwen3-asr-mlx to the cached snapshot. It is idempotent — if the model is
already cached, or you pass a local path, nothing is re-downloaded, so you
never keep two copies of the 2.5 GB weights. BF16 and mxfp8 builds work too —
mlx-speech reads the quantization from the checkpoint's config.json, so
switching is just a relink. Alternatively, convert the upstream
Qwen/Qwen3-ASR-1.7B weights
yourself with mlx-speech's
scripts/convert/qwen3_asr.py.
Configuration
| Environment variable | Default | Description |
|---|---|---|
TNT_MLX_MODEL |
bin/qwen3-asr-mlx, else ~/.local/share/tnt/qwen3-asr-mlx |
Path to the converted MLX checkpoint |
TNT_R2T2_MODEL |
bin/r2t2-mlx, else ~/.local/share/tnt/r2t2-mlx |
Confucius4-R2T2 MLX checkpoint; when present, m switches to it |
TNT_MLX_LANGUAGE |
auto |
Chinese, English, or auto. Use Chinese to keep mixed Chinese/English speech from being translated to English |
TNT_INPUT_DEVICE |
system default | Microphone, by index or name |
TNT_CAPTURE_BACKEND |
auto |
macOS always uses native AVFoundation (needs the Xcode command line tools: xcode-select --install); other platforms use PortAudio. portaudio is rejected on macOS |
Keybindings
| Key | Action |
|---|---|
| Space | Start / stop recording, or hold to record until release; cancels during transcription |
| c | Copy the last transcript entry |
| mouse click | Copy the clicked transcript entry |
| x | Clear the transcript |
| q | Quit |
Project structure
src/tnt/
├── app.py # Textual TUI, state machine, keybindings
├── audio.py # Recorder protocol, backend selection, PortAudio (non-macOS)
├── avf_audio.py # Native AVFoundation capture via helper process (macOS)
├── mic_helper.swift # AVFoundation helper source, compiled on demand
├── async_threads.py # Daemon-thread helpers for blocking work
├── transcriber.py # In-process MLX Qwen3-ASR transcription
└── widgets/
├── transcript.py # Scrollable transcript log
└── status.py # Braille oscilloscope + state rail
bin/
└── qwen3-asr-mlx # Symlink to converted MLX checkpoint (gitignored)
Related projects
- mlx-speech — our MLX-native speech runtime that powers TNT (PyPI)
- qwen3-asr-1.7b-int8-mlx — our int8 MLX checkpoint that TNT runs (converted from Qwen3-ASR-1.7B)
More from appautomaton
- 🌐 appautomaton.com — our site
- 🤗 huggingface.co/appautomaton — our models and checkpoints on Hugging Face
- 🐙 github.com/appautomaton — our open-source projects
License
MIT. See LICENSE.
Release files for automaton-tnt 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| automaton_tnt-0.1.3.tar.gz | 61.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| automaton_tnt-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.1 kB
Release files / automaton_tnt-0.1.3.tar.gz
| Download URL | automaton_tnt-0.1.3.tar.gz |
|---|---|
| Size | 61.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc0e9fc14c165fa7d8dd93d8828939728bf1f5944e8436f340de6b0aeb6faceb
|
|
BLAKE2b-256 checksum How to use checksums |
ab84ad7c04f03feb4499e7574604018851f8971f8fc0f7b365244733e38cf47a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logRelease files / automaton_tnt-0.1.3-py3-none-any.whl
| Download URL | automaton_tnt-0.1.3-py3-none-any.whl |
|---|---|
| Size | 33.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3e39b370513df63a94e4c7469880e40a99f0e2077acf47b80bfe0428fb85b972
|
|
BLAKE2b-256 checksum How to use checksums |
bffa3d1ed5ccc718ada550e82c468c186d95bf481b61705e3c2a9c6c4be5b01c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency log