Run Whisper Locally on a Mac with whisper.cpp (Step by Step)
Run Whisper locally on a Mac with whisper.cpp: install, model download, ffmpeg conversion to 16 kHz WAV, output formats, Apple Silicon notes and common errors.
This is the complete Terminal walkthrough for running OpenAI's Whisper speech model on your own Mac with whisper.cpp: install, model download, audio conversion, transcription, output formats, and the errors you are most likely to hit. When you are done you will have a command you can reuse on any audio file, and a batch loop for folders. Nothing is uploaded; the only network traffic is the one-time model download.
What whisper.cpp is
whisper.cpp is a C/C++ port of Whisper with no Python dependency. On Apple Silicon it runs the model on the GPU through Metal out of the box, and it can optionally run the encoder on the Neural Engine through Core ML. It reads WAV files, writes text, subtitles or JSON, and handles roughly a hundred languages with the multilingual models. It is free and actively maintained.
There is a second Mac-native option, WhisperKit, covered near the end. Both give you Whisper; they differ in how they use the hardware and how much you set up yourself.
Step 1: install Homebrew
Homebrew is the package manager most Mac developers use. If brew --version in Terminal returns an error, install it from brew.sh:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
On Apple Silicon the installer finishes by printing two lines that add Homebrew to your shell path. Run them, then open a new Terminal window.
Step 2: install whisper.cpp and ffmpeg
brew install whisper-cpp ffmpeg
ffmpeg is needed because whisper.cpp only reads WAV. After installing, find out what the binary is called on your system. Current formula versions install whisper-cli; older ones installed whisper-cpp, and the project has also shipped main in source builds.
ls "$(brew --prefix)/bin" | grep -i whisper
The rest of this guide uses whisper-cli. Substitute the name you see.
Step 3: choose and download a model
Whisper ships in several sizes. Each is a single .bin file in ggml format, published on the project's Hugging Face page and listed in the README.
| Model | Best for |
|---|---|
tiny, base |
Quick drafts, clean audio, testing the setup |
small |
Everyday use when speed matters |
medium |
Better accuracy on accents and noise, slower |
large-v3 |
Best accuracy, largest download, slowest |
large-v3-turbo |
Most of large's accuracy with a much faster decoder |
Models with a .en suffix are English-only and slightly more accurate for English at the same size. Quantized variants (file names ending in something like -q5_0) are smaller and faster with a small accuracy cost; useful on a Mac with 8 GB of memory.
Download into a folder you will remember:
mkdir -p ~/whisper-models
curl -L -o ~/whisper-models/ggml-small.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin
Repeat with a different file name for other sizes. If a URL changes, take the current one from the README's model table rather than guessing.
Step 4: convert audio to 16 kHz mono WAV
whisper.cpp expects 16-bit PCM WAV at 16 kHz, one channel. Anything else fails with a read error, so make this a habit:
ffmpeg -i input.m4a -ar 16000 -ac 1 -c:a pcm_s16le input.wav
The input can be MP3, M4A, FLAC, OGG, MP4, MOV or anything else ffmpeg understands. To convert every audio file in a folder:
for f in *.mp3 *.m4a; do
[ -e "$f" ] || continue
ffmpeg -i "$f" -ar 16000 -ac 1 -c:a pcm_s16le "${f%.*}.wav"
done
Step 5: transcribe
The minimum command is the model, the file, and an output flag:
whisper-cli -m ~/whisper-models/ggml-small.bin -f input.wav -otxt
Timestamped segments print to the terminal as they are decoded and input.wav.txt appears next to the audio. The flags you will actually use:
-l desets the language (any ISO code);-l autodetects it. Omit it and the default is English.-otxt,-osrt,-ovtt,-ocsv,-ojwrite text, SRT, WebVTT, CSV or JSON. Combine several.-of transcriptsets the output base name, so you gettranscript.txtinstead ofinput.wav.txt.-ntdrops timestamps from the terminal output.-t 8sets the thread count; the default is usually fine.-ppprints progress, handy for long files.--prompt "Names, jargon, product terms"nudges spelling toward words in the prompt.
Run whisper-cli --help for the full list; flags occasionally change between versions.
A reusable one-liner that converts and transcribes in one go:
ffmpeg -i talk.mp3 -ar 16000 -ac 1 -c:a pcm_s16le talk.wav && \
whisper-cli -m ~/whisper-models/ggml-small.bin -f talk.wav -l auto -otxt -osrt -of talk
Output formats explained
- TXT is the transcript as paragraphs of segments, one per line. Fine for reading and pasting.
- SRT and VTT are subtitle formats with start and end times per segment. Whisper's segment boundaries are approximate, so expect to adjust a few in an editor; the SRT guide shows how.
- JSON includes segments, timings and token probabilities, useful if you are building something on top.
- CSV is timings plus text, handy for spreadsheets.
Word-level timestamps are possible with -ml 1 (max segment length of one token) but they are rough; Whisper was not trained to place words precisely. If you need accurate word timing, a transducer model such as Parakeet does better, which the Whisper vs Parakeet comparison explains.
Apple Silicon notes
Metal is on by default. The Homebrew build runs matrix work on the GPU. You do not need to pass any flag to get it.
Core ML for the encoder. whisper.cpp can run the encoder on the Neural Engine, which noticeably speeds up the large models. It requires building from source with the Core ML option and generating a Core ML version of the model with the Python script in the repo. The first run then compiles the model for your chip, which takes minutes and happens once per model. The README has the exact steps; they change occasionally, so follow the current version rather than an old blog post.
Memory. The model has to fit in memory alongside the encoder's working set. On an 8 GB Mac, stick to small or a quantized medium. On 16 GB and above, large-v3 runs comfortably.
Speed expectations. With small, an M-series Mac transcribes an hour of audio in a few minutes. large-v3 can approach real time on base M1 models and is several times faster on Pro and Max chips. large-v3-turbo is the usual compromise when you want large's accuracy.
Intel Macs work but run on the CPU only. Use base or small and be patient.
Batch transcribing a folder
Once the single-file command works, wrap it:
MODEL=~/whisper-models/ggml-small.bin
for f in *.wav; do
[ -e "$f" ] || continue
whisper-cli -m "$MODEL" -f "$f" -l auto -otxt -of "${f%.*}"
done
Pair it with the conversion loop from Step 4 and you have a two-command pipeline for any drop folder.
Common errors and fixes
command not found: whisper-cli. Either Homebrew is not on your path (open a new Terminal after installing) or your version installed the binary under another name. Run the ls command from Step 2.
failed to read WAV file or unsupported sample rate. The file is not 16 kHz mono 16-bit PCM. Re-run the ffmpeg conversion exactly as in Step 4; a WAV saved by another app is usually 44.1 kHz stereo.
failed to load model or no such file. The path after -m is wrong or the download did not finish. ls -lh ~/whisper-models should show a file of sensible size; a tiny file usually means the download returned an error page instead of the model.
Repeated sentences or a phrase that loops. Whisper's decoder occasionally gets stuck. Try a larger model, add -l with the correct language instead of auto, or split the file at the point where it derails. Silence and music at the start are common triggers, so trim them with ffmpeg first. The behaviour has a specific cause, and why Whisper repeats itself and how to stop it goes through the decoder settings that help.
Invented text where nobody spoke. Same cause. Whisper is a language model as well as a speech model and will sometimes write plausible sentences over silence. Skim the output around long pauses. Speech-activity detection flags in newer versions help; check --help for a VAD option.
Very slow. You are probably running a large model on an Intel Mac, or a quantization mismatch is forcing CPU fallback. Try small to confirm the setup is fine, then step up.
Wrong language. Set -l explicitly. Auto-detection looks only at the first seconds of audio, so a file that opens with music or a different language gets misdetected.
The WhisperKit CLI alternative
WhisperKit by Argmax runs Whisper on Core ML and uses the Neural Engine without any source build. As of writing, the README documents a Homebrew install and a transcribe subcommand that takes the original audio file directly, so no ffmpeg step, and models download on first use. The trade-off is a first-run compile per model that takes a few minutes, and a smaller set of output flags than whisper.cpp. For a Mac-only workflow that should use the Neural Engine, it is the simpler tool. Check the README for the current commands.
The same binaries can drive live dictation rather than file transcription. To build a whisper.cpp dictation hotkey that types into any app, the recording side is a short script on top of what you installed above.
If you'd rather not maintain this
Frequently asked questions
Is whisper.cpp free to use?
Yes. whisper.cpp is open source under the MIT license and the Whisper model weights are released by OpenAI under a permissive license as well. You can use it for personal and commercial transcription without fees. Check the repository for the current license text if that matters for your organisation.
Does Whisper run offline on a Mac?
Yes. After the model file is downloaded, whisper.cpp needs no network connection at all. Audio and transcripts stay on the Mac. That makes it a good fit for confidential recordings, and the same holds for any app that bundles Whisper for on-device use.
Which Whisper model should I use on a Mac?
Start with small for a fast, decent result, and move to large-v3-turbo when accuracy matters or the audio is noisy. Use the .en variants for English-only material. On an 8 GB Mac, stay with small or a quantized model. Bigger is more accurate but slower, and the jump from medium to large is smaller than the jump from base to small.
Does whisper.cpp use the Neural Engine?
Only if you build it with the Core ML option and generate a Core ML encoder for your model. The default Homebrew build uses the GPU through Metal, which is already fast on Apple Silicon. WhisperKit uses the Neural Engine by default, and so do apps built on Core ML, which is the main reason they can be faster than a stock whisper.cpp install.