Skip to main content

sprezzature-audio

Local-first speech processing for the sprezzature stack.

Point it at a recording (a meeting, an interview, a lecture) and it hands back a transcript that says not just what was said, but who said it and in which language. Everything runs on your own machine: no audio leaves it, and no API key is needed. If you instead need to cut, resample, or clean up the audio signal itself (trim silence, separate a voice from background music), that is a different job, handled by a sibling package, audio-helper; this package starts once the audio is already usable and asks what was said in it.

What it does

Six scripts, each one stage of the pipeline. A few terms recur throughout the table below, so here they are once, up front, rather than repeated at every mention:

  • ASR (automatic speech recognition) is the technical name for speech-to-text: turning a sound wave into written words.
  • WebVTT and SRT are two competing plain-text file formats for storing subtitles: a list of [start time, end time, text] triples. WebVTT is the web-standard one (what a <video> tag expects); SRT is older and more universally supported by video players.
  • RTTM is a plain-text format from the speech-research world for recording who spoke when: one line per speaker turn, with a start time, a duration, and a speaker label.
  • NeMo is NVIDIA's open-source toolkit for speech models; Sortformer and TitaNet are two specific NeMo models used here (diarization and speaker fingerprinting, explained below).
Script What it produces
captions_from_whisper.py WebVTT, SRT, or a plain transcript, via a local Whisper model (through vocal-helper)
diarize_from_nemo.py An RTTM file plus a JSON turn list, via NeMo's Sortformer model (up to 4 speakers)
identify_from_titanet.py A speaker's identity, matched against a reference voice sample, via NeMo's TitaNet model
caption_diarize.py The combined pipeline: transcript and speaker turns merged in one pass
name_from_transcript.py A guess at each speaker's real name, read off the diarized transcript (pattern matching, with an optional LLM assist)
translate_captions.py A translated copy of a VTT/SRT file, via a local LLM
audit_captions.py What is wrong with a caption track: reading speed, overlaps, line width, duration

And the other direction — text back into sound, because that is the same modality read backwards. A narration lands as a WAV plus a WebVTT, exactly like a transcript does, so a page can follow the reading sentence by sentence.

Script What it produces
narrate_kokoro.py A narrated WAV and its cues, from 54 built-in voices in nine languages. The default.
narrate_openvoice.py The same, in a voice cloned from a 6–30 s sample
narrate_chatterbox.py The same, with emotion and intensity hints the model can act on
pick_voice.py A one-line demo clip per voice, so a narrator is chosen by listening
install_narrate.py The checkpoints each engine needs

Nobody passes a language. narrate_kokoro.py reads the text, detects the language, and picks the voice that speaks it — which matters more than it sounds: the detected language is what the phonemiser works from, so French read as English is not French in an American accent, it is an American spelling the words out.

Install

# Base (no ML dependencies)
pip install sprezzature-audio

# Add captioning (Whisper via vocal-helper)
pip install "sprezzature-audio[captions]"

# Add diarization and speaker ID (NeMo; install torch first, since the right
# build depends on your hardware: CUDA, Apple-silicon MPS, or plain CPU)
pip install torch
pip install "sprezzature-audio[diarize]"

# Add LLM translation (best-engine-ai-helper + a local Ollama server)
pip install "sprezzature-audio[translate]"

# Add narration. No torch: Kokoro is 82 M parameters through ONNX Runtime,
# Apache-2.0 in code and weights. espeak-ng is the one half pip cannot
# supply — `brew install espeak-ng`, or `apt install espeak-ng`.
pip install "sprezzature-audio[narrate]"
sprezzature-audio-install-voice --engine kokoro

# The cloning engines, if you want to sound like a particular person rather
# than to have a page read aloud. These are the ones that pull torch.
pip install "sprezzature-audio[narrate-openvoice]"
pip install "sprezzature-audio[narrate-chatterbox]"

# Everything
pip install "sprezzature-audio[all]"

Quick start

Fifteen tools ship here, each with its own command — which is what a script should call. The two front doors are how you find them:

make-audio --help          # argparse: the catalogue, with a line per tool
sprezzature-audio --help   # click: the same fifteen, the other parser

make-audio audit subtitles.vtt
make-audio narrate post.md --out post.mp3

Every argument after the tool name belongs to that tool, so make-audio captions --help shows the transcription flags, not these.

# Transcribe a video to WebVTT
sprezzature-audio-captions talk.mp4

# Same, as a plain-text transcript
sprezzature-audio-captions podcast.mp3 --format text

# Diarize an audio file: who spoke when
sprezzature-audio-diarize interview.wav

# Full pipeline: caption_diarize.py merges caption + diarization files
# already produced by the two steps above (it takes no media file itself)
sprezzature-audio-captions meeting.mp4
sprezzature-audio-diarize meeting.mp4
sprezzature-audio-pipeline --captions meeting.vtt --diarization meeting.diarization.json

# Guess speaker names from the diarized transcript
sprezzature-audio-name meeting.speakers.vtt

# Translate captions to French
sprezzature-audio-translate talk.vtt --lang fr

As a library

import sprezzature_audio hands back the engine, not a version string. What is importable with no extras at all is everything that needs no model — the same set the HTTP API serves, and for the same reason: it is fast and pure.

import sprezzature_audio as audio

cues = audio.parse(open("talk.vtt").read())
for finding in audio.audit_cues(cues):      # too fast, too short, too wide
    print(finding)

print(audio.write_srt(cues))                # VTT -> SRT, same reader
print(audio.word_error_rate(reference, hypothesis)["wer"])
print(audio.describe_device())              # which accelerator this host uses

The model-backed half resolves on first use, so the import above costs nothing even on a machine with Whisper, NeMo and Kokoro installed:

audio.synthesise(...)      # [narrate]  — Kokoro
audio.transcribe(...)      # [captions] — Whisper
audio.diarize(...)         # [diarize]  — NeMo Sortformer
audio.translate_cues(...)  # [translate]

Ask for one without its extra and the error names the pip install that fixes that tool, not the package in general.

How this differs from audio-helper

audio-helper works at the signal level: converting formats, slicing a waveform, resampling, separating a voice from background music with Demucs. It has no notion of words; a silence and a sentence look the same to it.

sprezzature-audio works at the content level: it reads speech, attributes it to a speaker, and translates it. The two packages are meant to be used together, not as alternatives; captions_from_whisper.py in fact calls audio-helper internally, to extract a 16 kHz mono WAV file (the format Whisper expects) before it ever runs the speech model.

Models used

Task Model Backend
ASR (speech to text) large-v3-turbo by default, or any other GGML-format Whisper weights (the compact file format vocal-helper's underlying engine, whisper.cpp, expects) vocal-helper / pywhispercpp
Diarization (who spoke when) nvidia/diar_sortformer_4spk-v1 NeMo
Speaker ID (matching a voice to a reference sample) nvidia/speakerverification_en_titanet_large NeMo
Translation Configured through the SPREZZATURE_LLM_* environment variables best-engine-ai-helper

Environment variables

Variable Purpose
SPREZZATURE_WHISPER_MODEL Override the Whisper model path or alias
SPREZZATURE_CACHE_DIR Cache directory for Whisper weights and transcripts
SPREZZATURE_NO_CACHE Set to any value to disable the transcript cache
NEMO_DIAR_MODEL Override the NeMo diarization checkpoint
SPREZZATURE_LLM_* LLM backend configuration (see best-engine-ai-helper)

License

BSD 3-Clause. See LICENSE.

Author

Warith HARCHAOUI: deraison.ai

Metadata

Release files for sprezzature-audio 1.5.0

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

Source distribution (sdist)

Source distribution for sprezzature-audio 1.5.0
File Size Uploaded Provenance
sprezzature_audio-1.5.0.tar.gz 137.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sprezzature-audio 1.5.0
File Interpreter ABI Platform
sprezzature_audio-1.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 262.7 kB

Release files / sprezzature_audio-1.5.0.tar.gz

Download URL sprezzature_audio-1.5.0.tar.gz
Size 137.8 kB
Tags Source
SHA-256 checksum
How to use checksums
46f1b4c1d5a4c85c87397cb81de541e8cf80b2df2aeeb9bc45b3e63ac439d73b
BLAKE2b-256 checksum
How to use checksums
e7a45428c2956cd8ecf3d9ed206798377ae16624d03e45788df0ca7cb5e6bfa6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / sprezzature_audio-1.5.0-py3-none-any.whl

Download URL sprezzature_audio-1.5.0-py3-none-any.whl
Size 125.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b15795231037d8ab81dd960b325c50246affb4a6b1ac066d3ac020ebac14236c
BLAKE2b-256 checksum
How to use checksums
e98dc7a2faff5d9c7979a53170229bc5e996250363e9c7e9bf973d03018b627b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Security for sprezzature-audio 1.5.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

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