Docker¶
docker run --rm -v "$PWD:/data" ghcr.io/mskazemi/yazses \
transcribe /data/meeting.m4a --diarize -f md
That transcribes meeting.m4a and writes meeting.md beside it, with who said what, entirely on your machine. No account, no API key, and after the models are cached, no network at all.
What this image is not¶
It does not do hold-to-talk dictation. That is the main thing YazSes does, and it is deliberately absent here.
Dictation needs a microphone, access to /dev/input to see the hotkey, and the ability to inject keystrokes into your desktop session. A container is the wrong shape for all three, and an image that pretended otherwise would waste your evening. For dictation, install natively — it takes about as long as reading this page.
What the image is good for: transcribing recordings on a machine you would rather not install Python on, on a server, or in a pipeline.
Models and caching¶
Nothing is baked in. Mount a volume so the models download once instead of on every run:
docker volume create yazses-models
docker run --rm \
-v "$PWD:/data" \
-v yazses-models:/home/yazses/.cache \
ghcr.io/mskazemi/yazses transcribe /data/talk.wav --model small.en
| What | Size | When |
|---|---|---|
Whisper tiny.en | 78 MB | --model tiny.en |
Whisper base.en | 148 MB | the default |
Whisper small.en | 486 MB | --model small.en |
| Diarization models | ~45 MB | only with --diarize |
Speaker labels need the diarization models, fetched once:
docker run --rm -v yazses-models:/home/yazses/.cache \
-v yazses-data:/home/yazses/.local/share \
ghcr.io/mskazemi/yazses transcribe --download-models
Keep -v yazses-data:/home/yazses/.local/share on your --diarize runs too, or they will be downloaded again each time.
Air-gapped use¶
Pull the image and populate both volumes on a connected machine, export them, and the container never needs the network again — the whole point of the project is that none of your audio leaves the machine, and nothing here changes that.
Common flags¶
# subtitles with timestamps
docker run --rm -v "$PWD:/data" ghcr.io/mskazemi/yazses \
transcribe /data/talk.mp4 -f srt
# a different output path
docker run --rm -v "$PWD:/data" ghcr.io/mskazemi/yazses \
transcribe /data/talk.wav -o /data/transcripts/talk.txt
# every option
docker run --rm ghcr.io/mskazemi/yazses transcribe --help
See the CLI reference for the full set.
Notes on the image¶
- Non-root. It runs as uid 1000 (
yazses). If your own uid is not 1000, add--user "$(id -u):$(id -g)"— otherwise the container cannot write the transcript back into your mounted directory and the run fails with a permission error. With a matching uid it works without the flag, which is exactly why this is easy to miss; it is how our own CI first broke. The cache and data directories are world-writable so the flag is all you need — no extra setup.
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/data" \
ghcr.io/mskazemi/yazses transcribe /data/talk.wav
/data is the convention, not a requirement — mount wherever you like and give the container that path. - Size: ~1.5 GB. Most of it is PyTorch-free but still substantial ML wheels (ctranslate2, onnxruntime, numpy). It is a fair bit of disk for a transcription tool and we would rather say so than let you find out. - linux/amd64 and linux/arm64. - Built by .github/workflows/docker.yml from packaging/docker/Dockerfile, published on tags only, with build provenance attested.