Streaming speaker diarization: per-frame sigmoid activity for up to 8 speakers. The graph exports one streaming step (Sortformer cache + FIFO + chunk forward). Mel extraction and segment post-processing (median filter, hysteresis) are outside the ONNX file.
1conda activate onnx # NeMo + torch + onnx + onnxruntime
2pip install "nemo_toolkit[asr]" onnx onnxruntime
3
4python parakeet-rs/scripts/export_ultra_diar_8spk.py \
5 ultra_diar_streaming_sortformer_8spk_v1/ultra_diar_streaming_sortformer_8spk_v1.nemo \
6 out_diar_8spk/ultra_diar_streaming_sortformer_8spk_v1.onnx
The export script runs an ONNX Runtime smoke test after writing the file. Override streaming params with --chunk-len, --right-context, --fifo-len, --spkcache-len if needed; re-export for a different latency trade-off.
1import numpy as np
2import onnxruntime as ort
3
4CHUNK_LEN = 340
5RIGHT_CONTEXT = 40
6FIFO_LEN = 40
7SPKCACHE_LEN = 376
8SUBSAMPLING = 8
9MEL_FRAMES = (CHUNK_LEN + RIGHT_CONTEXT) * SUBSAMPLING # 3040
10
11session = ort.InferenceSession(
12 "ultra_diar_streaming_sortformer_8spk_v1.onnx",
13 providers=["CPUExecutionProvider"],
14)
15
16chunk = np.zeros((1, MEL_FRAMES, 128), dtype=np.float32)
17chunk_lengths = np.array([MEL_FRAMES], dtype=np.int64)
18spkcache = np.zeros((1, 0, 512), dtype=np.float32)
19spkcache_lengths = np.array([0], dtype=np.int64)
20fifo = np.zeros((1, 0, 512), dtype=np.float32)
21fifo_lengths = np.array([0], dtype=np.int64)
22
23preds, embs, emb_lens = session.run(
24 None,
25 {
26 "chunk": chunk,
27 "chunk_lengths": chunk_lengths,
28 "spkcache": spkcache,
29 "spkcache_lengths": spkcache_lengths,
30 "fifo": fifo,
31 "fifo_lengths": fifo_lengths,
32 },
33)
34
35# preds: [1, time_out, 8] — slice chunk predictions from cache/fifo region
36print(preds.shape)
A full streaming loop must maintain FIFO, speaker cache, and smart cache compression between steps (see NVIDIA NeMo Sortformer streaming or parakeet-rs sortformer.rs).
1use parakeet_rs::sortformer::{Sortformer, DiarizationConfig};
2
3let mut sortformer = Sortformer::with_config(
4 "ultra_diar_streaming_sortformer_8spk_v1.onnx",
5 None,
6 DiarizationConfig::callhome(),
7)?;
8
9println!("speakers={}", sortformer.num_speakers()); // 8
10println!("latency={:.1}s", sortformer.latency()); // ~30.4s
11
12// Buffered streaming (recommended for 8spk latency)
13for chunk in audio.chunks(320) {
14 for seg in sortformer.feed(chunk)? {
15 println!("Speaker {} [{:.2}s - {:.2}s]", seg.speaker_id, ...);
16 }
17}
18sortformer.flush()?;
1cd parakeet-rs
2cargo run --release --example streaming-diarization --features sortformer -- \
3 audio.wav ../out_diar_8spk/ultra_diar_streaming_sortformer_8spk_v1.onnx