diart: Real-Time Speaker Diarization as a Streaming Python Pipeline
A python package to build AI-powered real-time audio applications
At a glance
- What is it?
- diart wraps pyannote segmentation and embedding models in an incremental clustering pipeline that emits speaker turns while audio is still playing. It is a good fit for live transcription and meeting capture, and a poor fit if you cannot accept the pyannote model licence terms or need a stable API.
- Who is it for?
- Adopt diart if you are building a live meeting, call centre or captioning tool in Python and can accept the pyannote model gating on Hugging Face. Do not adopt it if you need offline batch diarization with a frozen API, or if your system cannot meet the ffmpeg < 4.4, portaudio 19.6.X and libsndfile >= 1.2.2 requirements.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 88 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem diart addresses: speaker turns before the file ends
Most diarization tooling is batch oriented. You hand it a complete recording, it returns an RTTM file, and the speaker labels are only meaningful once the whole file has been processed. That is fine for archives and post-meeting analysis. It is useless for a live caption that needs to say who is talking now.
diart targets that second case. The README describes it as a python framework to build AI-powered real-time audio applications, with speaker diarization as the key feature. The intended users are engineers writing live transcription, meeting capture or voice analytics tools in Python, not researchers running offline benchmarks. The package is published on PyPI, targets Python 3.10, 3.11 and 3.12, and is MIT licensed.
How the SpeakerDiarization pipeline actually works
The README states that the diart.SpeakerDiarization pipeline combines a speaker segmentation model and a speaker embedding model to drive an incremental clustering algorithm that gets more accurate as the conversation progresses. That sentence is the whole architecture in miniature.
Segmentation runs over a sliding window of audio and produces per-frame speaker activity. The embedding model turns short speech regions into fixed-length vectors. The clustering layer compares each new embedding against the speakers discovered so far, assigning the region to an existing speaker or starting a new one. Because the clustering state persists across windows, earlier mistakes can be corrected by later evidence, which is why accuracy improves over the course of a conversation rather than being fixed at the first window.
The same machinery is exposed as building blocks. diart.models provides SegmentationModel.from_pretrained and EmbeddingModel.from_pretrained, so you can swap the segmentation or embedding backend through the --segmentation and --embedding arguments on the CLI or the equivalent Python calls. The README also advertises pre-trained pipelines for Speaker Diarization, Voice Activity Detection, and two transcription variants marked as coming soon, so the transcription path should not be treated as available today.
Getting audio through the system: CLI, Python and sources
The fastest path is the command line. For a recorded file: diart.stream /path/to/audio.wav. For a live input: diart.stream microphone, and the README notes you can select a non-default device with microphone:ID, listing devices via python -m sounddevice. The default pipeline is SpeakerDiarization, equivalent to passing --pipeline SpeakerDiarization, and --pipeline VoiceActivityDetection switches to the lighter task. diart.stream -h lists the remaining options.
In Python the shape is explicit. You construct a pipeline, wrap an audio source, attach one or more observers, then call the inference object:
from diart import SpeakerDiarization from diart.sources import MicrophoneAudioSource from diart.inference import StreamingInference from diart.sinks import RTTMWriter
pipeline = SpeakerDiarization() mic = MicrophoneAudioSource() inference = StreamingInference(pipeline, mic, do_plot=True) inference.attach_observers(RTTMWriter(mic.uri, "/output/file.rttm")) prediction = inference()
The observer pattern is the extension point. RTTMWriter writes speaker turns to disk in RTTM format, and the README points to Benchmark for dataset-level inference and evaluation. The do_plot flag enables a live view, which the demo GIF illustrates.
Model dependencies, Hugging Face gating and the latency table
diart does not ship its own acoustic models. By default it uses pyannote.audio models from the Hugging Face hub, and the README requires you to accept user conditions for pyannote/segmentation, pyannote/segmentation-3.0 and pyannote/embedding, install huggingface-cli and log in with an access token, or pass the token manually through the CLI or API. That is a hard dependency on an external account and on terms you do not control. It also means an air-gapped deployment needs a mirror or local copies, which the README does not describe.
The README includes a timing table for supported models, measured in milliseconds on CPU and GPU. The default pyannote/segmentation is listed at 12ms CPU and 8ms GPU, and the default pyannote/embedding at 26ms CPU and 12ms GPU. Alternatives include pyannote/segmentation-3.0 at 11ms CPU, hbredin/wespeaker-voxceleb-resnet34-LM in ONNX form at 48ms CPU and 15ms GPU, pyannote/wespeaker-voxceleb-resnet34-LM in PyTorch form at 150ms CPU and 29ms GPU, and speechbrain/spkrec-xvect-voxceleb at 41ms CPU and 15ms GPU. The README does not state the hardware used for those numbers, so treat them as relative rather than absolute. The spread matters more than the values: the PyTorch wespeaker embedding is roughly six times slower on CPU than the default embedding, which is a real constraint if you are running without a GPU.
Where diart is the wrong tool
The incremental clustering design has a cost. Speaker identities are decided online and revised as audio arrives, so the labels you emit at second ten are not guaranteed to match the labels at second sixty. If your downstream consumer needs stable identifiers, you have to buffer and reconcile, and diart does not do that for you.
Installation is another friction point. The README lists ffmpeg < 4.4, portaudio == 19.6.X and libsndfile >= 1.2.2 as system dependencies. The ffmpeg upper bound is unusual and will conflict with distributions that ship newer versions, so a conda environment built from the provided environment.yml is often the safer route. The README also recommends Benchmark for dataset inference and evaluation, with a note on reproducibility, but the material here does not describe what that reproducibility guarantee covers.
Finally, the release cadence is uneven. v0.9 landed in November 2023, v0.9.1 in May 2024 and v0.9.2 in February 2025. The project is not archived, but a sub-1.0 version number plus long gaps between releases means you should pin the version you deploy rather than tracking main.
The alternative: pyannote.audio in batch mode
The obvious comparison is pyannote.audio itself. diart is built on top of pyannote models, so the acoustic front end is largely the same. The difference is the inference model. pyannote.audio pipelines are typically run over a complete file and return a diarization for the whole recording at once, with clustering performed globally over all embeddings. diart runs the same models in a streaming loop with an incremental clustering state, trading global optimality for the ability to emit results while audio is still arriving.
That trade-off cuts both ways. Batch diarization can revisit every embedding when deciding speaker boundaries, which a streaming system cannot do without unbounded memory. diart gets lower latency and bounded state, at the cost of labels that can shift mid-stream. If your application can wait for the file to finish, the batch approach is simpler and avoids the Hugging Face CLI and token plumbing that diart requires for its default models. The README also points to Benchmark for evaluation, which suggests the project expects you to measure the streaming pipeline against a reference rather than assume parity.
Maintenance cost, licensing and what to check before committing
The diart code itself is MIT licensed, which is permissive and imposes no copyleft obligation on your application. The models are a separate matter. The pyannote models are gated on Hugging Face behind user conditions, and the README instructs you to accept those conditions before use. Whether those terms are compatible with your product is a question for your legal team, not something this review can settle.
Upgrade cost is dominated by two things: the pinned system dependencies and the model identifiers. Because the CLI and Python API accept model names as strings, a model rename or a new segmentation checkpoint is a config change rather than a code change, which is a genuine advantage. But the sub-1.0 versioning means breaking changes are possible between minor releases, and the README's own note that transcription pipelines are coming soon implies the API surface is still growing. Pin diart to a specific version, pin your model names explicitly rather than relying on defaults, and re-run your own evaluation set after any upgrade. The Benchmark class the README recommends is the tool for that, and it is the one piece of the workflow you should set up before you ship anything.
Editorial conclusion
Adopt diart if you are building a live meeting, call centre or captioning tool in Python and can accept the pyannote model gating on Hugging Face. Do not adopt it if you need offline batch diarization with a frozen API, or if your system cannot meet the ffmpeg < 4.4, portaudio 19.6.X and libsndfile >= 1.2.2 requirements. Verify first that your Hugging Face token has accepted the conditions for pyannote/segmentation, pyannote/segmentation-3.0 and pyannote/embedding, and that your segmentation and embedding latency budget leaves room for the clustering step.
Community notes