whisper-gpu-kit
Installed as whisper-gpu-kit, imported as whisper_gpu.
GPU transcription plumbing for faster-whisper, extracted from two repos that had
the same code byte-for-byte (tiktok-lazy-follower/src/tlf/transcribe.py,
get_cool_event/src/gce/transcribe.py) plus the companion caption parser
(tlf/subtitles.py).
Python ≥3.12. faster_whisper is imported lazily inside the functions, so the
package imports fine on a machine with no GPU deps; whisper_gpu.subtitles needs
only webvtt-py.
uv add whisper-gpu-kit # + `[gpu]` extra for the CUDA runtimes
Why it exists
- cuDNN/cuBLAS preload. CTranslate2 4.x
dlopens cuDNN 9 at model-load time but does not search thenvidia-*-cu12pip packages' lib dirs — withoutpreload_cuda_libs()the GPU model load hangs silently. local_files_only=Truefirst. The per-load HF Hub check can stall for minutes on a slow network.- Cache-miss vs CUDA-error disambiguation.
"cudnn ... is not found"contains"not found"; treating it as a cache miss triggers a pointless 3 GB re-download that then fails anyway.is_cache_miss()rules CUDA out first. - GPU-OOM → CPU fallback. A CUDA OOM (usually another process holding VRAM)
corrupts the device context; every later call dies with "invalid device ordinal".
Detect it, release our model, redo on CPU (
int8) instead of mislabeling good audio as undecodable.
Usage
Captions first (free, no GPU), whisper second:
from pathlib import Path
from whisper_gpu import (find_subtitle, parse_subtitle, lang_from_subtitle_name,
transcribe_with_fallback, warn_if_low_vram)
audio = Path("data/audio/someone/7123456789.m4a")
sub = find_subtitle(audio) # sibling <id>.<lang>.vtt/.srt
if sub is not None:
text, lang, source = parse_subtitle(sub), lang_from_subtitle_name(sub), "native_sub"
else:
warn_if_low_vram() # logs if another process holds the GPU
text, lang, device = transcribe_with_fallback(audio) # cuda → cpu on GPU failure
Lower-level pieces, if you drive the loop yourself:
from whisper_gpu import whisper_transcribe, is_gpu_error, free_gpu_model
try:
text, lang = whisper_transcribe(audio, device="cuda", beam_size=5)
except Exception as exc:
if is_gpu_error(exc): # transient: VRAM contention → retry later
free_gpu_model()
text, lang = whisper_transcribe(audio, device="cpu")
else:
raise # permanent: undecodable audio → skip-list it
Models are cached per device in a module-level dict, so repeated calls reuse the
loaded model; free_gpu_model() drops the CUDA one and GCs to release its ~3 GB.
API
preload_cuda_libs() |
RTLD_GLOBAL-load pip cuBLAS then cuDNN; no-op without them |
is_gpu_error(exc) -> bool |
CUDA/cuDNN/VRAM failure (transient) vs bad input |
is_cache_miss(exc) -> bool |
model not (fully) downloaded — the only case a download fixes |
gpu_free_mib() -> int | None |
free VRAM via nvidia-smi |
warn_if_low_vram(model, min_free_mib) -> int | None |
preflight warning, never blocks |
free_gpu_model() |
drop the cached CUDA model + GC |
get_whisper(device, model, compute_type) |
lazy, cached WhisperModel (CPU forced to int8) |
whisper_transcribe(audio_path, device, model, beam_size, compute_type) -> (text, lang) |
one transcribe call |
transcribe_with_fallback(..., cpu_fallback=True) -> (text, lang, device_used) |
cuda → cpu on GPU error |
find_subtitle / parse_subtitle / lang_from_subtitle_name |
VTT/SRT → deduped plain text |
Constants: DEFAULT_MODEL="large-v3", DEFAULT_COMPUTE_TYPE="float16",
WHISPER_MIN_FREE_MIB=3500, GPU_ERR_MARKERS, CACHE_MISS_MARKERS.
The old underscore names from the source modules (_whisper_transcribe,
_is_gpu_error, _get_whisper, …) remain as aliases in whisper_gpu.transcribe
so migrating the two consumers is an import swap.
Tests
uv run --package whisper-gpu --extra dev pytest whisper-gpu/tests -q
No GPU and no model download: the classifiers are pure string logic, and the model layer is monkeypatched.
Metadata
Release files for whisper-gpu-kit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| whisper_gpu_kit-0.1.1.tar.gz | 11.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| whisper_gpu_kit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.3 kB
Release files / whisper_gpu_kit-0.1.1.tar.gz
| Download URL | whisper_gpu_kit-0.1.1.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4511f72aa4dac4113b65dee24acaa2cb201bebe4832438ccd2ca1d25bc0c02b7
|
|
BLAKE2b-256 checksum How to use checksums |
8c35c12223c3a62e0c6e6a1a6b8c2ce96dd15c3c6c95b2c253db9b53dc2d7722
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / whisper_gpu_kit-0.1.1-py3-none-any.whl
| Download URL | whisper_gpu_kit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
003cfd4aa459e6cb9141420a203d941da01f93c827842c420c70c2084ab4679f
|
|
BLAKE2b-256 checksum How to use checksums |
e7c908c2f39da8cc5ab6519fcd18a9391f46c9a1153e82434f6c4aa64bf676e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log