Skip to content

Transcribe on the GPU when there is one, fall back to the CPU - #19

Open
simplaerai-sv wants to merge 1 commit into
HelpFreedom:mainfrom
simplaerai-sv:whisper-gpu
Open

Transcribe on the GPU when there is one, fall back to the CPU#19
simplaerai-sv wants to merge 1 commit into
HelpFreedom:mainfrom
simplaerai-sv:whisper-gpu

Conversation

@simplaerai-sv

Copy link
Copy Markdown

What

scripts/transcribe.py runs faster-whisper on the GPU when one is
visible, and keeps today's CPU path as the fallback. One file changed.

Why

The runner hard-codes device="cpu", compute_type="int8". On a machine
with an NVIDIA card that leaves most of the box idle. Measured on the same
60-second Ukrainian clip, RTX 4060 (8 GB), 12-core CPU:

model CPU int8 GPU float16
small 15.5 s 6.9 s
large-v3 8.8 s (incl. model load)

A 50-minute lecture on large-v3 goes from "leave it running" to about
seven minutes.

How

  • pick_device()cuda when ctranslate2 reports a CUDA device, else
    cpu. KADR_WHISPER_DEVICE=cpu|cuda|auto overrides (default auto),
    so a user can pin the CPU without touching code.
  • load_model()cuda/float16, falling back to cpu/int8 if the load
    itself fails (driver too old, no VRAM).
  • The transcribe loop moved into run(). If the GPU fails during
    inference — the common Windows case is a missing cublas64_12.dll,
    the model loads fine and the first kernel dies — the job is redone on
    the CPU. Only while nothing has been streamed yet: a CPU rerun after
    partial GPU output would hand the editor every segment twice.
  • _register_nvidia_dlls() (Windows only) — the pip wheels
    nvidia-cublas-cu12 / nvidia-cudnn-cu12 drop their DLLs under
    site-packages/nvidia/<lib>/bin, which is not on the search path;
    registering those folders is what makes CUDA actually work from a plain
    pip install. No-op on Linux/macOS.
  • The chosen device is logged to stderr; stdout stays NDJSON-only, so
    electron/transcribe.ts needs no change.

Behaviour on a machine without a GPU is byte-for-byte what it was.

Tested

Windows 11, Python 3.12, faster-whisper 1.2.1, ctranslate2 4.8.2:

  • GPU path: small and large-v3, timings above, Ukrainian recognised
  • inference-level fallback: with the CUDA wheels absent, cuda load →
    cublas64_12.dll error → CPU rerun → exit 0, all segments present
  • KADR_WHISPER_DEVICE=cpu → CPU path, unchanged output
  • device-less path not testable here; it is the untouched original code

Users on Windows who want the GPU need
pip install nvidia-cublas-cu12 nvidia-cudnn-cu12 on top of
faster-whisper — happy to add a line to the README if you would like it
in this PR.

🤖 Generated with Claude Code

scripts/transcribe.py hard-coded device=cpu/int8. Pick cuda/float16 when
ctranslate2 sees a CUDA device (KADR_WHISPER_DEVICE=cpu|cuda|auto to
override), keep cpu/int8 as the fallback — at model load AND during
inference: on Windows the model loads fine and the first kernel dies with
'cublas64_12.dll not found', so the transcribe loop is retried on the CPU,
but only while no segment has reached the editor yet (a rerun after partial
output would stream everything twice).

Windows also needs the DLLs from the nvidia-cublas-cu12 / nvidia-cudnn-cu12
wheels, which pip puts in site-packages/nvidia/<lib>/bin, off the search
path; register those folders with os.add_dll_directory before loading.

RTX 4060, 60 s Ukrainian clip: small 15.5 s -> 6.9 s; large-v3 8.8 s
including model load, i.e. a 50-minute lecture in about seven minutes.
stdout stays NDJSON-only; electron/transcribe.ts is unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant