Skip to main content

qal-scribe

On-device push-to-talk dictation for Amharic. Hold a key, speak, let go: the text appears wherever your cursor is. A second key turns Amharic speech into English text. Everything runs on your computer; after the models are downloaded nothing leaves it.

  • macOS on Apple Silicon is the main platform (Intel Macs are not supported: PyTorch no longer builds for them). Linux works and is in beta.
  • Speech model: snapwre/hohe-asr-amharic (wav2vec2-BERT 600M, CC-BY-4.0), decoded with its KenLM language model. On an Apple GPU a 10 s clip takes about 0.15 s.
  • Translation: facebook/nllb-200-distilled-600M (CC-BY-NC-4.0: non-commercial use only).

Install

You need uv.

uv tool install --python 3.12 qal-scribe
qal-scribe doctor      # checks permissions, microphone and models, and says how to fix what is missing
qal-scribe             # hold Right Option, speak, release

The first start downloads the speech model and its language model (about 3 GB), then the translation model (2.5 GB); later starts work offline. Ctrl+C cancels a download (the next start begins it again). To skip the translation model, set translate_key = "" in the config before the first start. qal-scribe models download [--translation] fetches the models without starting.

On Linux without an NVIDIA GPU, install the CPU build of PyTorch instead of the multi-GB CUDA one:

uv tool install --python 3.12 qal-scribe --torch-backend cpu

uv does not remember --torch-backend, so upgrade with the same line plus --upgrade rather than with uv tool upgrade, which may fetch the multi-GB CUDA build.

--python 3.12 matters: the language-model decoder has no builds for newer Pythons, and without it qal-scribe falls back to slightly less accurate greedy decoding (qal-scribe doctor warns about it). uv downloads Python 3.12 if you do not have it.

macOS permissions

Give the terminal app you run qal-scribe from (Terminal, iTerm2, Ghostty, ...) these three permissions in System Settings > Privacy & Security, then quit and reopen the terminal:

  • Microphone, to hear you (macOS asks the first time you record).
  • Input Monitoring, so the hotkeys work while another app is in front.
  • Accessibility, to paste into that app.

qal-scribe doctor shows which ones are missing.

Use

Key What it does
Hold Right Option, speak, release Amharic text is pasted at your cursor
Hold Right Control, speak, release The English translation is pasted

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.

Pasting goes through the clipboard: qal-scribe saves what you had copied and puts it back half a second later. While you speak, a live draft appears in the window (turn it off with preview = false).

The terminal window shows the state (ready, recording, transcribing), a mic level meter and a history of what you said. Its keys: c copies the last text, Enter copies the highlighted history row, l switches language, t changes the theme, m toggles a compact 3-5 line layout for a small always-visible window, q quits. qal-scribe --plain prints one line per event instead, for logs or terminals without a full UI.

Linux (beta)

Text is typed with wtype (Wayland: sway, Hyprland, ...), xdotool (X11) or, on GNOME and KDE Wayland, pasted with wl-copy + ydotool (needs ydotoold running; terminals want Ctrl+Shift+V, so pasting into a terminal does not work there). Without any of them the text goes to the clipboard and the window says so. qal-scribe doctor tells you what to install.

Before uv tool install, install PortAudio and the tools to build evdev (a keyboard library that has no ready-made build for Linux):

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

Wayland does not let programs read global hotkeys, so bind two keys in your compositor or desktop settings to:

qal-scribe toggle              # first press starts recording, second press pastes Amharic
qal-scribe toggle --translate  # the same, pasting English

Linux has only been tested in CI and with simulated tools so far. Please report what works and what does not.

Settings

qal-scribe config --init writes a fully commented ~/.config/qal-scribe/config.toml (or under $XDG_CONFIG_HOME) listing every setting with its default; qal-scribe config prints its path. The ones you are most likely to change:

Setting Default
dictate_key, translate_key "alt_r", "ctrl_r" pynput key names such as cmd_r, shift_r, f13; translate_key = "" turns translation off
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, see below)
lm true decode with the language model; false is plain greedy decoding
sounds true short sound when recording starts and stops

Run qal-scribe doctor after editing to check the file.

Your own words

Put corrections in ~/.config/qal-scribe/words.txt, one per line: heard => wanted, for example ኤፒአይ => API. Lines starting with # are ignored. The wanted text still goes through merge_homophones and numbers_to_digits when those are on, so a wanted word containing ዓ or a number word can change; turn those settings off if that happens.

Punctuation (experimental)

Amharic speech models write no punctuation. With punctuation = true, qal-scribe adds it with simple rules: ? after a sentence with a question word (ምን, ማን, የት, መቼ, እንዴት, ስንት, ...), ። otherwise, and ፣ before ነገር ግን, ሆኖም and ምክንያቱም. The rules prefer a missing mark to a wrong one, but they do make mistakes: an exclamation such as እንዴት ደስ ይላል gets ?, and a yes/no question without a question word (ዛሬ ትመጣለህ) gets ።. Check the text before you send it.

Spoken numbers have known traps too: አንድ ("a", "one") becomes 1 in አንድ ቀን, and the city አርባ ምንጭ becomes 40 ምንጭ.

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 %

The language model removes about one word error in six and adds about 11 ms per clip. The FLEURS transcripts write numbers as digits, which is why numbers_to_digits scores better here; it stays off by default because of the traps described above. These numbers are for read speech; expect more errors with background noise, fast speech, names and English words (add those to your words file).

More languages (experimental)

Tigrinya (tir), Afaan Oromo (orm), Somali (som), Sidaama (sid) and Wolaytta (wal) run through the same engine with other open models. They are rough drafts at best: see docs/languages.md for their accuracy and licences (the Somali model is non-commercial). Download one with qal-scribe models download tir, then press l in the window or set language = "tir". Translation was only measured from Amharic (NLLB has no Sidaama or Wolaytta), and the text clean-up settings are made for Amharic.

Commands

qal-scribe                     start dictating (terminal UI)
qal-scribe --plain             the same, one line per event
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

Licence

The code is MIT licensed. The models are downloaded at run time and keep their own licences: the Amharic speech model is CC-BY-4.0 and the translation model is CC-BY-NC-4.0, which allows non-commercial use only. qal-scribe about lists them all.

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 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.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qal-scribe 1.0.0
File Size Uploaded Provenance Actions
qal_scribe-1.0.0.tar.gz 182.4 kB With provenance Details for qal_scribe-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for qal-scribe 1.0.0
File Interpreter ABI Platform Actions
qal_scribe-1.0.0-py3-none-any.whl Python 3 none any Details for qal_scribe-1.0.0-py3-none-any.whl

Total release size: 249.9 kB

Release files / qal_scribe-1.0.0.tar.gz

Download URL qal_scribe-1.0.0.tar.gz
Size 182.4 kB
Tags Source
SHA-256 checksum
How to use checksums
6d12026d7bfcd3856c03450cf6231ff4c235696cb4c1ebc9c3234f4419db8cc1
BLAKE2b-256 checksum
How to use checksums
4a7b934db11ef6864ecc9ea52cfc1774b13e3dfbaa977a2ba123aa16aacdcb80
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 29, 2026.

Transparency log

Release files / qal_scribe-1.0.0-py3-none-any.whl

Download URL qal_scribe-1.0.0-py3-none-any.whl
Size 67.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12a6b95ece10b248a26c9bbd27fce0109131a90c0b5dcccdf15ad203b16926b9
BLAKE2b-256 checksum
How to use checksums
3a9657fa50e99c1bc772c31ab36f4d009ffc2c740b624efc401a350b1176bde2
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 29, 2026.

Transparency log

Security for qal-scribe 1.0.0

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.

Select from 2 files

Attestation for qal_scribe-1.0.0.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 29, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page