Building a Practical ASR Pipeline with whisper.cpp
Step-by-step guide to picking a model, converting audio, and wiring whisper.cpp into a repeatable transcription pipeline.
3 min read
- asr
- whisper.cpp
- guide
Overview
A real ASR pipeline is more than one command. It needs: a known-good audio format, a model chosen for your accuracy/speed tradeoff, and a place to put the output.
Step 1 — Normalize the audio
Whisper.cpp expects 16kHz mono WAV. Most source audio isn't in that format, so convert it first with ffmpeg:
ffmpeg -i input.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio.wavStep 2 — Pick a model
| Model | Size | Relative speed | Use case |
|---|---|---|---|
tiny.en | ~75 MB | Fastest | Quick drafts, live captions |
base.en | ~140 MB | Fast | Good default for English |
small.en | ~460 MB | Moderate | Better accuracy, still light |
medium.en | ~1.5 GB | Slow | High accuracy, needs more RAM |
large-v3 | ~3 GB | Slowest | Best accuracy, multilingual |
bash ./models/download-ggml-model.sh base.enStep 3 — Transcribe with structured output
./whisper-cli \
-m models/ggml-base.en.bin \
-f audio.wav \
-osrt -otxt -oj \
--output-file out/audioThis produces out/audio.txt, out/audio.srt, and out/audio.json in one pass.
Step 4 — Wrap it in a script
#!/usr/bin/env bash
set -euo pipefail
SRC="$1"
MODEL="${2:-models/ggml-base.en.bin}"
OUT_DIR="out"
if [ -z "$SRC" ]; then
echo "Usage: $0 <input-file> [model-path]" >&2
exit 1
fi
if ! command -v ffmpeg >/dev/null 2>&1; then
echo "Error: ffmpeg is required but not found on PATH" >&2
exit 1
fi
mkdir -p "$OUT_DIR"
base_name="$(basename "${SRC%.*}")"
wav_path="$OUT_DIR/${base_name}.wav"
ffmpeg -y -loglevel error -i "$SRC" -ar 16000 -ac 1 -c:a pcm_s16le "$wav_path" || {
echo "Error: ffmpeg failed to convert $SRC" >&2
exit 1
}
./whisper-cli -m "$MODEL" -f "$wav_path" -osrt -otxt --output-file "$OUT_DIR/$base_name" || {
echo "Error: whisper-cli failed to transcribe $wav_path" >&2
exit 1
}
echo "Done: $OUT_DIR/${base_name}.txt"Common pitfalls
- Wrong sample rate: skipping the
ffmpegconversion step gives garbled or empty transcripts. - Model/language mismatch: using an
.en-only model on non-English audio produces nonsense text. - Missing disk space check:
large-v3models need several GB free; check before downloading in automated pipelines.
Up next
The final article in this series digs into what happens inside whisper.cpp — the decoder strategies, beam search, and tuning options that affect both speed and accuracy.