pyannote segmentation 3.0 — static-shape ONNX for pure-Rust inference

pyannote/segmentation-3.0 re-exported so that it can be loaded by tract, the pure-Rust ONNX runtime. Functionally identical to the upstream export; only the graph's shape handling differs.

Used by CallMind to measure how many speakers a recording holds instead of assuming two.

Why a re-export was needed

The published ONNX export cannot be loaded by tract. It contains an If node guarding a branch on the input's shape, plus symbolic dimension arithmetic that tract declines to prove equal (-24 + T/10 against -25 + (T+9)/10). Both disappear once the input is fixed to a single 10-second chunk: the branch condition becomes a constant and ordinary constant folding removes the node.

Verified against the source export:

check result
output change from folding exactly 0.0
tract against onnxruntime 6.7e-4 max, 3.0e-4 mean (f32 accumulation)
per-frame decision agreement 589 / 589 frames

Operators after folding are all standard ai.onnx: InstanceNormalization, Conv, MaxPool, LeakyRelu, Transpose, LSTM, Reshape, Gemm, LogSoftmax, Abs.

The int8 variant is deliberately not provided: it folds to a graph containing DynamicQuantizeLSTM from the com.microsoft domain, which tract does not implement.

Interface

input x [1, 1, 160000] — one 10-second chunk, 16 kHz mono, float32
output y [1, 589, 7] — per-frame log-probabilities over a speaker powerset

The seven classes are ∅, {1}, {2}, {3}, {1,2}, {1,3}, {2,3} — up to three speakers with the two-at-once combinations, which is how overlapping speech is represented. Frame duration is 10000 / 589 ≈ 16.98 ms.

Longer audio is processed one chunk at a time; the final chunk is zero-padded.

Measured behaviour

Against labelled recordings — four single-speaker recordings confirmed by their owner and thirty two-party phone calls — taking the median number of distinct speakers seen per chunk:

statistic single speaker two-party
maximum per chunk 4/4 20/30
median per chunk 4/4 26/30

The maximum is the wrong statistic despite looking natural: it is the maximum of a noisy quantity, so it grows with recording length and long calls reliably report one speaker too many.

Reproducing this file

python3 -m venv .venv && .venv/bin/pip install onnx onnxruntime numpy
.venv/bin/python scripts/export_pyannote_segmentation.py \
    --out models/diarization/segmentation.onnx

The script re-downloads the source, applies the transformation and refuses to write a result whose output drifted, whose If node survived, or which contains non-standard operator domains.

License and attribution

MIT, inherited unchanged from upstream.

If you use pyannote in research, cite the upstream work:

@inproceedings{Plaquet23,
  author={Alexis Plaquet and Hervé Bredin},
  title={{Powerset multi-class cross entropy loss for neural speaker diarization}},
  year=2023,
  booktitle={Proc. INTERSPEECH 2023},
}
@inproceedings{Bredin23,
  author={Hervé Bredin},
  title={{pyannote.audio 2.1 speaker diarization pipeline: principle, benchmark, and recipe}},
  year=2023,
  booktitle={Proc. INTERSPEECH 2023},
}
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for shareed2k/callmind-pyannote-segmentation

Quantized
(7)
this model