← Neill's Vibe
Field GuideWhisper Writer

Stop typing at your AI. Just talk to it.

Hold a key, say what you want, let go — the words type themselves into whatever window your cursor is in. Chat box, code editor, email, anywhere. It runs entirely on your own machine: no API key, no subscription, no audio ever leaving your laptop. $0, forever. The catch is that on Windows it usually refuses to start, and the error it gives you is a lie. This guide is the fix — and the working repo.

01 · the scene

Hold. Talk. Release. Done.

you: [hold Pause] "rewrite this function so it handles the empty array case and add a test" [release]
↓ ~1 second later ↓
⌨️ typed straight into your cursor
rewrite this function so it handles the empty array case and add a test

No window to open. No "upload your audio." No button to click when you're done. You hold a key you never use anyway — Pause/Break, sitting there unloved since 1995 — and the text lands wherever you were already typing.

Here's the part people underestimate: you talk about three times faster than you type, and you think out loud better than you write. Long, rambling, context-rich prompts stop being a chore. That changes what you bother to ask an AI, which is the actual win.

02 · why local wins

Nothing leaves the machine, and nothing gets billed

Whisper is OpenAI's speech model, but you do not have to call OpenAI to use it. The weights are public. One config line decides everything:

# src/config.yaml
model_options:
  use_api: false        # ← the whole value proposition

false means the model runs on your own hardware. Three consequences, all good:

One naming trap worth flagging: there is a paid product literally called WhisperKey. Different thing, costs money. What you want is whisper-writer — open source, MIT, free.

03 · the wall

The error that stops almost everyone

You install it. You run it. You get this:

Could not load library cudnn_ops64_9.dll. Error code 126
Please make sure cudnn_ops64_9.dll is in your library path!

So you go install the NVIDIA CUDA Toolkit. Doesn't help. You download cuDNN, make an account, unzip it into your CUDA folder. Doesn't help. You add things to PATH, reboot, try a different Python. Doesn't help. Somewhere around hour three you conclude your machine is cursed.

Your machine is fine. The DLL is already on your disk. It shipped inside your virtual environment as a pip wheel — it's sitting in venv\Lib\site-packages\nvidia\cudnn\bin right now. Windows just isn't looking there.

And it gets one turn worse. PyQt5 and pynput — the window toolkit and the keyboard hook — mutate the DLL search path when they import. So even registering the right directory doesn't stick if you do it too late.

The fix is nine lines, and the order is the whole thing

# src/main.py — this must run BEFORE PyQt5/pynput are imported
if sys.platform == 'win32':
    for _pkg in ('cublas', 'cudnn', 'cuda_nvrtc'):
        _dll_dir = os.path.join(sys.prefix, 'Lib', 'site-packages', 'nvidia', _pkg, 'bin')
        if os.path.isdir(_dll_dir):
            os.add_dll_directory(_dll_dir)

import ctranslate2      # initialize CUDA before PyQt/pynput poison the loader
import faster_whisper

Point Windows at the wheel directories, then load the CUDA library first, before anything else gets a chance to rearrange the furniture. That's it. That's the three hours.

The transferable lesson: when a library says a file is missing, check whether it's actually missing before you start installing things. "Not found" and "not found yet, from here, in this order" are different bugs, and only one of them is fixed by downloading more software.

04 · the deadlock

Put the model in its own process

Second scar. Even with the DLLs loading, running a GPU model in the same process as a desktop window toolkit can hang the whole app — Qt's event loop and CUDA's streams deadlock, and you get a frozen tray icon and no error at all.

The fix is architectural and it's a pattern worth having in your pocket: when two libraries can't share a process, stop making them. The model lives in a subprocess that never imports Qt. The app talks to it over plain stdin/stdout:

→ request
[4-byte length][JSON header][4-byte length][raw float32 audio]
← response
[4-byte length][JSON body] — the transcript, or an error + traceback

Length-prefixed framing, so you always know where a message ends. JSON for structure, raw bytes for the audio — no pickle, no deserializing anything you wouldn't want to execute. And because the worker stays alive between requests, the model loads exactly once, at startup. Every transcription after that is pure inference, which is why it feels instant.

The side effect that looks like a bug

One running instance shows up as about six pythonw.exe processes in Task Manager. Everyone's first instinct is to kill five of them. Don't — you'll tear down your own app.

The venv's launchers are redirector stubs: each logical process (run.py, main.py, the worker) appears as a stub plus the real interpreter it delegates to. Three processes × two = six. Check worker.log for a single model ready line and you'll see the model loaded once, exactly as intended.

05 · no GPU?

It still works — and it's still free

No NVIDIA card? Work laptop, ThinkPad, MacBook-shaped life? You lose the "blazing" and keep the "useful." Swap two lines and install the CPU requirements, which drop about a gigabyte of CUDA wheels you'd never load:

# src/config.cpu.yaml — copy over src/config.yaml
    model: base.en          # tiny.en if your machine is slow, small.en for accuracy
    device: cpu
    compute_type: int8      # float16 is GPU-only

Measured on a normal laptop: roughly 8× faster than real time, near-perfect on clean speech. It will fumble a proper noun now and then.

Which does not matter — and this is the reframe that makes the CPU path genuinely good rather than a consolation prize. An LLM is reading this, not your boss. Claude does not care that "Postgres" came out "post grass." It has the context to fix it silently. You are not writing; you are steering. Optimize for speed, not for perfection you don't need.

pathmodelspeedgood for
NVIDIA GPUlarge-v3-turbonear-instanteverything, including punctuation you'd publish
CPU onlybase.en~8× real timetalking to an AI, notes, prompts, search

Why the GPU model is quick despite being called "large": large-v3-turbo is large-v3 with the decoder pruned from 32 layers down to 4 — about 8× faster to decode, with accuracy essentially intact. And there's no PyTorch anywhere in this install. It runs on CTranslate2 directly: 80 packages, no multi-gigabyte download.

06 · build your own

Or just hand this to your AI

You don't have to read a line of Python to get this running. Below is the brief — paste it into Claude Code (or whatever you drive) and let it do the install, including the two traps that cost me the evening. It's written so the assistant explains as it goes.


    
  
07 · clone it

The fixed version is yours

All the real speech-to-text work is savbell/whisper-writer — excellent, MIT, credit where it's due. My fork adds the four things that make it actually start and stay running on Windows:

the DLL fix
Nine lines that end the cuDNN error. The reason this repo exists.
out-of-process worker
Model in its own subprocess — no Qt/CUDA deadlock, loads once.
history.log
Every transcription saved. A paste that lands in the wrong window is no longer gone.
verified locks
Two pinned freezes (GPU + CPU). Upstream's requirements.txt is the trap itself.

That last one is worth a sentence, because it's the meta-lesson: upstream pins ctranslate2 4.2.1, which needs cuDNN 8, against wheels that ship cuDNN 9. That mismatch is the DLL error. A lockfile that isn't verified is just a rumor. Both of mine were installed from scratch and run before this page went up.

Below is the loader fix in full — the highest-value 20 lines in the repo, and the piece you'd want even if you never use this app.


    ★ whisper-writer-gpu on GitHub (MIT)
    
    

Clone → py -3.11 -m venv venvpip install -r requirements.txtpython run.py. Needs Python 3.11 specifically. First run downloads the model. Then hold Pause and talk.