Skip to main content

transcribe-cpp

Python bindings for transcribe.cpp, a C/C++ speech-to-text library built on ggml.

Status: in development. Until wheels are published, use a locally built libtranscribe through repo auto-discovery or TRANSCRIBE_LIBRARY.

Upgrading from 0.1? See the 0.2 migration guide, including the replacement of gpu_device= with exact device objects.

import transcribe_cpp

with transcribe_cpp.Model("model.gguf") as model:
    with model.session() as session:
        result = session.run(pcm_float32_16k_mono)
        print(result.text)

run() takes mono 16 kHz float32 PCM (buffer-protocol object or sequence). It does not decode containers or resample; convert audio before calling it.

import numpy as np

pcm = np.asarray(audio, dtype=np.float32)   # 1-D, 16 kHz mono
# Downmix stereo first; 2-D input is rejected:
# pcm = audio.mean(axis=1).astype(np.float32)
result = session.run(pcm)

Punctuation, capitalization, and text normalization

Generic run controls use "default" to preserve each model family's shipped behavior. Models advertising model.supports("pnc") accept pnc="off" or pnc="on"; models advertising model.supports("itn") accept the equivalent itn values. The options are available on run(), run_batch(), stream(), and the one-shot transcribe() helper.

result = session.run(pcm, pnc="off", itn="on")

Prompting

vocabulary (custom terms), prompt (context, or the instruction under task="instruct") and prefix (text the model continues from) take effect where model.supports() reports "vocabulary", "context_prompt", "instruct" or "transcript_prefix".

result = session.run(pcm, vocabulary=["Kubernetes", "gRPC"])

Streaming models expose incremental transcription with committed/tentative text views — see examples/stream_wav.py:

with model.session() as session, session.stream() as stream:
    for chunk in pcm_chunks:
        stream.feed(chunk)
        text = stream.text()        # .committed (stable) + .tentative
    stream.finalize()
    result = stream.snapshot()      # language, segments, words, tokens, timings

Long transcriptions can be cancelled from another thread with session.cancel() — the run raises Aborted with the partial transcript on exc.partial_result (same for OutputTruncated).

Diarization

Models whose model.roles include Role.DIARIZE (Sortformer) answer "who spoke when" through a diarize session. run() returns SpeakerSegment rows (speaker_id in 1..model.diarize_info.max_speakers), grouped by speaker. Locking, Busy, cancel() and close() work as on Session. A model without the role raises UnsupportedRole, as model.session() and model.capabilities do on a model without Role.ASR (Sortformer serves only Role.DIARIZE).

with model.diarize_session() as diarizer:
    turns = diarizer.run(pcm, family=transcribe_cpp.SortformerDiarizeOptions(
        preset="very_high_latency"))
    for turn in turns:
        print(turn.speaker_id, turn.t0_ms, turn.t1_ms)

Language ID

Models whose model.roles include Role.LANGID (VoxLingua107 ECAPA-TDNN) identify the spoken language through a langid session. run() returns a LangIdResult with candidates ranked by p. Codes are the model's own labels ("iw", "jw"; model.langid_label_index("he") resolves aliases), so match result.code against the ASR model's capabilities.languages yourself. allowed=None scores every label; allowed_mass is the unrestricted probability the allowed set captured. An empty allowed list raises InvalidArgument; clips under model.langid_info.min_audio_ms raise InputTooShort, and longer ones than max_audio_ms are scored on their first max_audio_ms. Every allowed label comes back as a candidate. Locking, Busy, cancel() and close() work as on Session.

with model.langid_session() as lid:
    result = lid.run(pcm, allowed=["en", "de", "fr"])
    print(result.code, result.candidates[0].p, result.allowed_mass)

Voice activity detection

Models whose model.roles include Role.VAD (Silero VAD, GGUF or the whisper.cpp .bin) score speech probability per frame of model.vad_info.frame_samples samples through a VAD session. run() scores one clip and returns a VadResult with probs and speech segments (start_sample/end_sample; options default to Silero's get_speech_timestamps). stream_feed() streams audio of any chunk size and returns the probabilities of the frames each call completed (first_frame is the position of the first); stream_flush() scores the zero-padded remainder and ends the stream, stream_reset() drops it. The VAD stream does not take the model's ASR stream lease. Locking, Busy, cancel() and close() work as on Session.

with model.vad_session() as vad:
    for seg in vad.run(pcm, min_silence_ms=300).segments:
        print(seg.start_sample, seg.end_sample)

    frame = model.vad_info.frame_samples
    probs = []
    for chunk in chunks:
        r = vad.stream_feed(chunk)
        print(f"{len(r.probs)} frames from sample {r.first_frame * frame}")
        probs.extend(r.probs)
    probs.extend(vad.stream_flush().probs)

Backends

Model(backend=...) applies a backend policy ("auto" uses the best available). transcribe_cpp.backends() returns process-local device objects; pass one as Model(device=device) for exact selection with no fallback. Persist a device's device_id, not its runtime handle or index. backend_available(kind) checks whether a backend policy can currently be satisfied.

device = next(d for d in transcribe_cpp.backends() if d.device_type == "cpu")
with transcribe_cpp.Model("model.gguf", device=device) as model:
    print(model.device)

Weights are memory-mapped from the model file where the device can use host memory (CPU, Metal on Apple silicon), so they live in reclaimable page cache rather than process memory. Don't truncate or rewrite a model file in place while it is loaded; write a new file and rename it over the old one. Model(no_mmap=True) copies the weights instead.

Variable Effect
TRANSCRIBE_BACKEND overrides the "auto" default; explicit backend= still wins
TRANSCRIBE_NO_MMAP 1 copies weights instead of memory-mapping them, like no_mmap=True
TRANSCRIBE_NATIVE_PROVIDER forces an installed native provider package, for example cu12
TRANSCRIBE_LIBRARY loads exactly this shared library

Planned wheels will bundle CPU plus platform accelerators; transcribe-cpp[cu12] will add the CUDA 12 provider.

Running from a working tree

The binding loads the native library at import and verifies its ABI layout and version before use. Build a shared library, then run from the repo or point TRANSCRIBE_LIBRARY at it:

cmake -B build-shared -DTRANSCRIBE_BUILD_SHARED=ON
cmake --build build-shared --target transcribe

cd bindings/python
PYTHONPATH=src uv run --no-project python examples/transcribe_wav.py \
    ../../models/whisper-tiny.en/whisper-tiny.en-Q5_K_M.gguf ../../samples/jfk.wav

No-model tests always run; model tests skip unless smoke assets are present. Override paths with TRANSCRIBE_SMOKE_MODEL, TRANSCRIBE_SMOKE_AUDIO, and TRANSCRIBE_SMOKE_STREAMING_MODEL.

cd bindings/python
TRANSCRIBE_LIBRARY=../../build-shared/src/libtranscribe.dylib \
    uv run --extra test pytest

Notes

  • One compute call at a time per Model: the binding serializes calls across all sessions of a model with a model-wide lock (load one model per worker for parallelism). While a stream is active, other runs and stream begins on that model raise transcribe_cpp.Busy. See the Model docstring.
  • Import package: transcribe_cpp
  • Distribution: transcribe-cpp
  • License: MIT

Metadata

Release files for transcribe-cpp 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for transcribe-cpp 0.4.1
File Size Uploaded Provenance Actions
transcribe_cpp-0.4.1.tar.gz 118.5 kB With provenance Details for transcribe_cpp-0.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for transcribe-cpp 0.4.1
File Interpreter ABI Platform Actions
transcribe_cpp-0.4.1-py3-none-any.whl Python 3 none any Details for transcribe_cpp-0.4.1-py3-none-any.whl

Total release size: 166.1 kB

Release files / transcribe_cpp-0.4.1.tar.gz

Download URL transcribe_cpp-0.4.1.tar.gz
Size 118.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4ffc427f559d5271b91e43f02bc73d392541719a8f605348a7f6a434bc33ba5a
BLAKE2b-256 checksum
How to use checksums
86e79edc70afb5068db1222453cce6e95e9fb6e871e6e34fbd535a6cebeee379
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 22, 2026.

Transparency log

Release files / transcribe_cpp-0.4.1-py3-none-any.whl

Download URL transcribe_cpp-0.4.1-py3-none-any.whl
Size 47.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4bb6ffb8eac16875daec12a8b3b9598024a34d1c10507cff51f0c42400eab5d
BLAKE2b-256 checksum
How to use checksums
60df55b97bec42c43f44a3d1bf1d4bbaf32b8bb1f99f444f4d49bfe6ca4224f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 22, 2026.

Transparency log

Security for transcribe-cpp 0.4.1

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for transcribe_cpp-0.4.1.tar.gz

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 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page