Skip to content
Danube Labs

Local Whisper Transcription on Your Own PC, Step by Step

Local Whisper transcription keeps your audio on your own computer. Convert to 16 kHz mono with FFmpeg, run faster-whisper on a GPU or CPU, and export TXT, SRT or VTT, with speaker labels from pyannote.

By Alexandru Secureanu7 min read
An audio waveform turning into timed transcript lines with two labelled speakers, all inside one laptop

Local Whisper transcription means running an open speech-to-text model on your own computer, so the recording never leaves it. The quickest route is faster-whisper: convert the audio to 16 kHz mono with FFmpeg, load a model such as large-v3 on a GPU in float16 or a smaller one on a CPU in int8, and write TXT, SRT or VTT. Add pyannote or WhisperX when you need to know who spoke.

Why transcribe audio locally?

Interviews, meetings, lectures and client calls often contain personal or confidential material. A local pipeline has no upload step. The model downloads once, and after it is cached the transcription itself needs no network. There is no per-minute fee either, because you pay in hardware and setup time. Whisper's code and model weights are released under the MIT licence, which allows this. Cloud services can still suit audio that is not sensitive. If you use one, read its data-use terms before you upload anything.

Whisper, faster-whisper or WhisperX: which one should you use?

ToolWhat it isPick it when
openai/whisperThe reference PyTorch implementation, MIT licensed. It needs the ffmpeg command-line tool installed.You want the original behaviour and its command line, for example whisper audio.mp3 --model turbo.
faster-whisperA reimplementation on CTranslate2 with float16, int8_float16 and int8 compute types. It decodes audio with PyAV.You want lower memory use and a clean Python API. This is the default choice below.
WhisperXAdds word-level timestamps through wav2vec2 forced alignment, and speaker diarization through pyannote.You need tight word timing and speaker labels from one command.

Speed and accuracy depend on your audio and your hardware. The faster-whisper README publishes benchmark tables, and the sensible move is to time a two-minute sample of your own recordings on your own machine.

What hardware do you need?

The Whisper README lists approximate VRAM for the original implementation. Treat these as a sizing guide, since quantised faster-whisper models need less.

ModelParametersVRAM in the READMEEnglish-only variant
tiny39Mabout 1 GBtiny.en
base74Mabout 1 GBbase.en
small244Mabout 2 GBsmall.en
medium769Mabout 5 GBmedium.en
large1550Mabout 10 GBnone
turbo809Mabout 6 GBnone

GPU or CPU?

An NVIDIA GPU is the fast route. faster-whisper needs cuBLAS and cuDNN 9 for CUDA 12 on the GPU. A CPU also works. Pick small or medium, use compute_type="int8", and set the thread count with OMP_NUM_THREADS. Expect a CPU to take much longer than a GPU, so measure before you queue a folder.

What does quantisation change?

faster-whisper accepts float16, int8_float16 and int8. Use float16 on a GPU by default, int8_float16 when GPU memory is tight, and int8 on a CPU. Lower precision uses less memory and can change a few words, so compare the output with your own audio before you commit to a setting.

How do you prepare audio with FFmpeg?

Whisper works on 16 kHz mono audio in 30-second windows. Its own loader calls ffmpeg with -ac 1 -ar 16000. Converting the file yourself gives you a predictable input, drops any video track and lets you check the result.

ffmpeg -i interview.m4a -vn -ac 1 -ar 16000 interview.wav

-vn drops video, -ac 1 mixes down to mono and -ar 16000 resamples to 16 kHz. For noisy recordings, DeepFilterNet is an open-source speech enhancement framework for 48 kHz audio, with a deep-filter command. Run it before you downsample, then compare the transcript with and without it, because aggressive denoising can swallow quiet speech.

How do you transcribe with faster-whisper, step by step?

  1. Create a virtual environment and install the package.
    python -m venv .venv
    .venv\Scripts\activate
    pip install faster-whisper
  2. On a GPU, install cuBLAS and cuDNN 9 for CUDA 12. The faster-whisper README links ready-made libraries for Windows and Linux.
  3. Convert the audio with the FFmpeg command above.
  4. Save this script as transcribe.py and run python transcribe.py interview.wav. It writes TXT, SRT, VTT and JSON next to the audio.
import json
import sys
from pathlib import Path

from faster_whisper import WhisperModel

audio = Path(sys.argv[1])
# GPU: large-v3 in float16. CPU: try "small" or "medium" with compute_type="int8".
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, info = model.transcribe(
    str(audio), language="en", beam_size=5, vad_filter=True, word_timestamps=True
)

def stamp(t, sep):
    ms = round(t * 1000)
    h, ms = divmod(ms, 3_600_000)
    m, ms = divmod(ms, 60_000)
    s, ms = divmod(ms, 1000)
    return f"{h:02}:{m:02}:{s:02}{sep}{ms:03}"

rows = [
    {"start": s.start, "end": s.end, "text": s.text.strip(),
     "words": [{"w": w.word, "start": w.start, "end": w.end} for w in (s.words or [])]}
    for s in segments            # the generator runs here
]

out = audio.with_suffix("")
out.with_suffix(".txt").write_text("\n".join(r["text"] for r in rows), encoding="utf-8")
out.with_suffix(".srt").write_text(
    "\n".join(f"{i}\n{stamp(r['start'], ',')} --> {stamp(r['end'], ',')}\n{r['text']}\n"
              for i, r in enumerate(rows, 1)), encoding="utf-8")
out.with_suffix(".vtt").write_text(
    "WEBVTT\n\n" + "\n".join(f"{stamp(r['start'], '.')} --> {stamp(r['end'], '.')}\n{r['text']}\n"
                            for r in rows), encoding="utf-8")
out.with_suffix(".json").write_text(json.dumps(rows, ensure_ascii=False, indent=2), encoding="utf-8")

Two details matter. segments is a generator, so transcription only starts when you iterate over it. And vad_filter=True removes silence before decoding. Change language to the code of your audio, for example ro for Romanian.

What if you get a metadata_errors TypeError?

At the time of writing, in October 2026, faster-whisper 1.2.1 fails with TypeError: open() got an unexpected keyword argument 'metadata_errors' when PyAV 19 is installed, because PyAV 19 removed an argument that faster-whisper still passes. This is tracked in faster-whisper issue 1589. Pinning an older PyAV fixed it in our test with version 18.1.0.

pip install "av<19"

Which output format should you export?

FormatUse it forDetail
TXTReading, quoting, pasting into documentsPlain text, one segment per line in the script above
SRTSubtitles in most video editorsNumbered cues, comma before milliseconds: 00:00:05,340
VTTSubtitles on web videoFile starts with WEBVTT, period before milliseconds, UTF-8
JSONSearch, analysis, your own toolsSegments with word timings, plus a speaker field if you add one

The W3C WebVTT specification defines the WEBVTT signature, the 00:00:01.000 --> 00:00:04.000 cue timing and the text/vtt type.

How do you get speaker labels with diarization?

Whisper transcribes words and does not say who spoke. Speaker diarization is a separate model. pyannote.audio is an MIT-licensed Python toolkit for it. Its pipeline takes an audio file and returns timed turns labelled SPEAKER_00, SPEAKER_01 and so on. You need a Hugging Face access token and you must accept the model's conditions on Hugging Face first. The README quickstart looks like this.

import torch
from pyannote.audio import Pipeline

pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-community-1",
    token="HUGGINGFACE_ACCESS_TOKEN")
pipeline.to(torch.device("cuda"))
output = pipeline("audio.wav")

To combine the two outputs, give each Whisper segment the speaker whose turns overlap it the most. WhisperX does the alignment and the diarization for you.

whisperx path/to/audio.wav --model large-v2 --diarize --hf_token YOUR_TOKEN

Set expectations honestly. The WhisperX README says overlapping speech is not handled particularly well and that diarization is far from perfect. Listen to a sample, then rename the generic labels yourself. If GPU memory is tight, free the Whisper model before you load the diarization pipeline.

How do you get better results with Whisper in Romanian and with noisy audio?

  • Set the language. With no language given, Whisper detects it from up to the first 30 seconds, and a noisy intro can mislead that guess. Pass language="ro".
  • Use the biggest model that fits. Romanian is in Whisper's language list. The model card says accuracy varies by language and drops for languages with less training data, so test on your own recordings.
  • Prompt with vocabulary. initial_prompt accepts custom vocabulary and proper nouns, and faster-whisper also offers hotwords. List names, places and technical terms from the recording.
  • Cut silence. The model card warns that Whisper can output text that was never spoken, and can repeat itself. vad_filter=True helps with the silent stretches.
  • Break repetition loops. Set condition_on_previous_text=False. Whisper's own docs say this makes the model less prone to getting stuck, at the cost of some consistency across windows.
  • Try a fine-tune. Community Whisper models fine-tuned for Romanian exist on Hugging Face. Check each licence and training data, and compare it with the stock model on your own audio.

Check diacritics at the end. A short pass makes the text use comma-below ș and ț consistently.

fix = str.maketrans({"\u015f": "\u0219", "\u0163": "\u021b", "\u015e": "\u0218", "\u0162": "\u021a"})
text = text.translate(fix)  # cedilla s and t become comma-below ș and ț

Always proofread names, numbers and dates, and run a two-minute clip before you start a long batch.

What does AI Transcription Studio add on top?

AI Transcription Studio is a Danube Labs desktop app that is in development. It is closed source and not released, so this describes what it is built to do. It wraps the steps above in one interface. You pick an engine from Faster-Whisper for speed, WhisperX for precise word timing and OpenAI Whisper as a fallback. Pyannote diarization sits in the same place, and FFmpeg conversion of audio and video is automatic, with optional DeepFilterNet noise reduction. A job queue takes whole folders, pauses and resumes, skips files that are already done and keeps going when one file fails. Results export to TXT, JSON, SRT and VTT, and everything runs locally on a GPU or CPU, with GPU memory released between transcription and diarization. We do not publish accuracy figures yet.

Need a private transcription workflow built for you?

If you want a private transcription workflow built around your own recordings, see AI systems or book a free intro call. Once you have a transcript, translating it is a separate task, covered in our guide to translating documents with AI.

Frequently asked questions

Can Whisper run offline?
Yes. Download the model weights once, and transcription then runs on your own machine without sending audio anywhere. Whisper's code and weights are MIT licensed. You need Python, enough RAM or VRAM for the model you choose, and either FFmpeg or, with faster-whisper, its bundled PyAV decoder for reading audio files.
Do I need a GPU for local Whisper transcription?
No. faster-whisper runs on a CPU with compute_type int8 and a smaller model such as small or medium. An NVIDIA GPU with cuBLAS and cuDNN 9 for CUDA 12 makes it much faster. Test a two-minute sample on your hardware to see how long a full recording will take.
How do I add speaker labels to a Whisper transcript?
Whisper does not identify speakers. Run a diarization model such as pyannote.audio, which needs a Hugging Face token, or use WhisperX with the diarize flag. Then give each transcript segment the speaker whose turns overlap it most. Expect mistakes where people talk over each other.
What audio format does Whisper need?
Whisper processes 16 kHz mono audio in 30-second windows, and its loader converts common formats through ffmpeg. For a predictable input, convert first with ffmpeg -i in.m4a -vn -ac 1 -ar 16000 out.wav. That drops video, mixes down to mono and resamples to 16 kHz.
Does Whisper work well in Romanian?
Romanian is in Whisper's language list, but accuracy varies by language and audio quality, and the model card notes lower accuracy where training data is thinner. Set language to ro, use the largest model you can run, prompt with names, and test on your own recordings.
What is the difference between SRT and VTT subtitles?
Both are plain-text subtitle formats. SRT numbers each cue and writes milliseconds after a comma, as in 00:00:05,340. WebVTT starts with the line WEBVTT, uses a period before milliseconds, is UTF-8 and has the text/vtt type, which suits video on the web.
Share

Related articles