qal-scribe (ቃል, qal, means "word") is push-to-talk dictation for Amharic that runs entirely on your computer. Hold a key, speak, let go: the text appears wherever your cursor is, in any app. A second key turns Amharic speech into English text.
Install
You need uv and a Mac with Apple Silicon (Linux works too, in beta).
uv tool install --python 3.12 qal-scribe
qal-scribe
The first start opens a setup screen that walks you through the permissions and downloads the models (about 3 GB, plus 2.5 GB if you want translation). After that it works offline. The full guide, including Linux, is in docs/install.md.
What it does
- Dictate Amharic. Hold Right Option, speak, release. The Amharic text is pasted where you are typing.
- Translate to English. Hold Right Command (Linux: Right Control) instead, and the English translation is pasted. Translation is optional: turn it off and the translation model is never downloaded.
- See it as you speak. The window shows a live draft while you talk, a microphone level meter, and a history of everything you said, ready to copy again.
- Five more languages, experimental. Tigrinya, Afaan Oromo, Somali, Sidaama and Wolaytta run on the same engine as rough drafts (docs/languages.md).
- Private. Your voice never leaves your computer. The only network use is downloading the models.
First run
- Run
qal-scribe. The setup screen opens. - macOS: turn on three permissions for the terminal app you started it from (Terminal, iTerm2, Ghostty, ...): Microphone, Input Monitoring (so the keys work while another app is in front) and Accessibility (so it can paste). Each row has an Open Settings button. Then quit the terminal with ⌘Q and open it again. Linux: the screen shows the exact install command for anything missing.
- Choose whether you want translation to English, and which model.
- Press Download. Each model gets its own progress bar.
- Press Continue, click into any app, hold Right Option and speak.
Something not working? qal-scribe doctor checks everything and prints the fix for each problem.
docs/permissions.md explains each permission.
Keys
| Key | What it does |
|---|---|
| Hold Right Option, speak, release | paste the Amharic text at your cursor |
| Hold Right Command (Linux: Right Control) | paste the English translation |
c |
copy the last text |
a |
copy the Amharic behind a translation |
Enter |
copy the highlighted history row (Esc jumps back to the latest) |
s |
settings |
d |
setup: permissions and downloads |
l |
switch language (when you have downloaded more than one) |
t / m |
next colour theme / compact layout for a small window |
v |
mute or unmute the sounds (saved to your config) |
? |
every key, as you configured them |
q |
quit |
Both hotkeys can be changed in the settings (s). The other keys work in the qal-scribe window.
Settings
Press s in the window to change the common settings; each one saves at once. Everything else lives in
config.toml: qal-scribe config --init writes a commented copy and qal-scribe config prints where it is.
| Setting | Default | What it does |
|---|---|---|
translation |
true |
false: no translate key, and the translation model is never downloaded or loaded |
dictate_key, translate_key |
"alt_r", "cmd_r" (Linux "ctrl_r") |
the push-to-talk keys |
mic |
system default | part of a microphone's name, or its number |
numbers_to_digits |
false |
write spoken numbers as digits: ሁለት ሺህ አስራ ሰባት → 2017 |
merge_homophones |
false |
spell sound-alike letters one way (ሐ ኀ → ሀ, ሠ → ሰ, ዐ ዓ → አ, ፀ → ጸ) |
punctuation |
false |
add ። ? and ፣ by rule (experimental) |
preview |
true |
a live draft while you speak |
indicator |
true |
macOS: a small floating pill, "Listening" while you hold the key and "Transcribing…" after, even when the terminal is hidden; ignored on Linux |
Every setting, with its default, is in docs/settings.md,
including your own word corrections (words.txt) and how the experimental punctuation behaves.
Translation models
Translation goes sentence by sentence, and the speech model writes no punctuation, so qal-scribe takes a pause of half a second as the end of a sentence: pause briefly between sentences when you translate.
Pick the model on the setup screen, in the settings, or with translation_model in config.toml:
translation_model |
Download | Licence |
|---|---|---|
nllb-600m (default) |
2.5 GB | CC-BY-NC-4.0, non-commercial use only |
nllb-1.3b |
5.5 GB | CC-BY-NC-4.0, non-commercial use only |
Bigger models are slower and need more memory. On a machine with little memory, turn translation off: the translation model is then never loaded.
Linux (beta)
Before installing, get PortAudio and the tools to build evdev (a keyboard library with no ready-made build):
sudo apt install libportaudio2 build-essential python3-dev # Debian, Ubuntu
sudo dnf install portaudio gcc python3-devel kernel-headers # Fedora
sudo pacman -S portaudio base-devel # Arch
Without an NVIDIA GPU, install the CPU build of PyTorch instead of the multi-GB CUDA one, and upgrade with the
same line plus --upgrade (uv does not remember --torch-backend):
uv tool install --python 3.12 qal-scribe --torch-backend cpu
Text is typed with wtype (sway, Hyprland), xdotool (X11), or on GNOME and KDE Wayland pasted with wl-copy
plus ydotool (needs ydotoold running). Without any of them the text goes to the clipboard and the window
says so. Wayland gives programs no global hotkeys, so bind two keys in your desktop settings to
qal-scribe toggle and qal-scribe toggle --translate.
Linux has only been tested in CI and with simulated tools so far. Please report what works and what does not.
Troubleshooting
Start with qal-scribe doctor: it checks the permissions, microphone, compute device, config and models,
and prints the fix next to each problem.
- The keys do nothing while another app is in front. Turn on Input Monitoring for your terminal, then quit it with ⌘Q and reopen it.
- The text is not pasted. Turn on Accessibility for your terminal. The text is also on the history list:
select it and press
Enterto copy it. - It pastes what you had copied before. Some apps paste slowly; raise
restore_delay(default0.5seconds). - The language model is off.
qal-scribe doctorwarns when Python is not 3.12: reinstall withuv tool install --python 3.12 --reinstall qal-scribe. - A download stopped. Ctrl+C cancels a download; the next start,
qal-scribe setuporqal-scribe models download --translationbegins it again.
More answers in docs/faq.md.
Privacy
Recording, transcription and translation all happen on your computer. qal-scribe sends no audio, no text and no usage data anywhere. It goes online only to fetch the models from Hugging Face (and to look up their download sizes on the setup screen), the first time or when you choose a new one. Pasting uses the clipboard: qal-scribe saves what you had copied and puts it back half a second later.
Accuracy
Measured on the 516 clips of the FLEURS Amharic test split with eval/evaluate.py (lower is better; scoring
folds homophone letters and drops punctuation):
| Decoding | CER | WER |
|---|---|---|
| greedy (the model alone) | 6.5 % | 17.2 % |
| with the language model (default) | 6.0 % | 14.4 % |
language model and numbers_to_digits = true |
4.5 % | 13.1 % |
These are for read speech; expect more errors with background noise, fast speech, names and English words (add those to your words file). On an Apple GPU a 10 s clip takes about 0.15 s.
Commands
qal-scribe start dictating (terminal UI)
qal-scribe --plain the same, one line per event
qal-scribe --no-translate start without the translation model, for this run
qal-scribe setup permissions, translation choice and model downloads
qal-scribe doctor check permissions, microphone, device, config and models
qal-scribe models list languages and whether each model is downloaded
qal-scribe models download [LANG] [--translation]
qal-scribe transcribe FILE [--translate] an audio file (wav, flac, ogg, mp3; convert m4a first) to text
qal-scribe config [--init] show (or create) the config file
qal-scribe toggle [--translate] start/stop recording in the running instance
qal-scribe about licences and model attribution
Licences
The code is MIT licensed. The models are downloaded at run time and keep their own licences: the Amharic
speech model, snapwre/hohe-asr-amharic, is CC-BY-4.0; the
NLLB translation models are CC-BY-NC-4.0, which allows non-commercial use only.
qal-scribe about lists them all. The ቃል in the logo is drawn from Noto Sans Ethiopic (SIL Open Font
License 1.1).
Development
uv sync
uv run ruff check
uv run pytest # no model weights are loaded
uv run python scripts/gpu_lock.py -- uv run pytest -m model # tests with the real models
uv run python scripts/screenshots.py # redraw docs/assets/screens and demo.svg
uv run python eval/fetch_fleurs.py && \
uv run python scripts/gpu_lock.py -- uv run python eval/evaluate.py eval/data/fleurs-am-test --compare
Metadata
Release files for qal-scribe 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| qal_scribe-1.0.1.tar.gz | 367.7 kB | With provenance | Details for qal_scribe-1.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qal_scribe-1.0.1-py3-none-any.whl | Python 3 | none | any | Details for qal_scribe-1.0.1-py3-none-any.whl |
Total release size: 455.3 kB
Release files / qal_scribe-1.0.1.tar.gz
| Download URL | qal_scribe-1.0.1.tar.gz |
|---|---|
| Size | 367.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
073dc5553a9bebf680decd0dc648787ccbfa19995c1303174e2bb2360a17df98
|
|
BLAKE2b-256 checksum How to use checksums |
a29b2f3b1f1aaaa1c0e67216743b696b00876199dbdf68fa5077376d1fe7c9cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 30, 2026.
Transparency logRelease files / qal_scribe-1.0.1-py3-none-any.whl
| Download URL | qal_scribe-1.0.1-py3-none-any.whl |
|---|---|
| Size | 87.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6cd1057062569ef6a2e779296e6ffb20dc69feec3d7e2e6a45234c545d643d7c
|
|
BLAKE2b-256 checksum How to use checksums |
d868ef00ca921f8a0bdd06b624441bade743f522cadfe43da733e746b961f515
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 30, 2026.
Transparency logSecurity for qal-scribe 1.0.1
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for qal_scribe-1.0.1.tar.gz
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 Oct 30, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.