Nemotron 3 Diarization is an open-weight speaker diarization model designed to determine "who spoke when" in real-world audio. It supports both streaming and offline inference and handles up to eight speakers. Following Sortformer [\[1\]](#ref-1), the model resolves speaker permutation by ordering its output channels according to each speaker's first arrival in the input audio.
For streaming inference, the model adopts the Arrival-Order Speaker Cache (AOSC) and FIFO queue introduced in Streaming Sortformer [\[2\]](#ref-2). The AOSC retains speaker information from earlier chunks to preserve speaker identities over time, while the FIFO queue provides recent frame context for each processing step.
A single checkpoint supports input buffer latency as low as 80 ms for latency-critical applications, although the lowest recommended configuration is 0.32 s; the offline-style configuration uses a 30.4 s input buffer. The output frame resolution is configurable in multiples of 10 ms. With chunked inference, the maximum audio duration is not limited.
This model is ready for commercial or non-commercial use.
To train, fine-tune or perform inference with this model, install NVIDIA NeMo Speech after installing Python 3.12 or later, Cython, and a recent PyTorch version.
from nemo.collections.asr.models import SortformerEncLabelModel
# load model from Hugging Face model card directly (You need a Hugging Face token)
diar_model = SortformerEncLabelModel.from_pretrained("nvidia/Nemotron-3-Diarization")
# If you have a downloaded model in "/path/to/Nemotron-3-Diarization.nemo", load model from a downloaded file
diar_model = SortformerEncLabelModel.restore_from(restore_path="/path/to/Nemotron-3-Diarization.nemo", map_location='cuda', strict=False)
# switch to inference mode
diar_model.eval()
import numpy as np
audio_input = np.random.randn(16000 * 10).astype(np.float32) # 10 sec at 16kHz
# or a list of arrays
audio_input = [audio_array1, audio_array2]
diar_model.diarize(audio=audio_input, batch_size=2, sample_rate=16000)
Note: When using numpy arrays, you MUST specify a correct sample_rate in diar_model.diarize() function. Default sample_rate is 16000.
or a line-delimited JSON manifest file:
audio_input="/path/to/multispeaker_manifest.json"
where each line is a JSON object containing the following fields:
Streaming configuration is defined by the following parameters, all measured in 80 ms frames:
SPKCACHE_LEN: Total number of frames in the speaker cache.
FIFO_LEN: Number of previous frames attached before the current chunk from the FIFO queue.
CHUNK_LEN: Number of frames in a processing chunk.
RIGHT_CONTEXT: Number of future frames attached after the chunk.
UPDATE_PERIOD: Number of frames extracted from the FIFO queue to update the speaker cache.
Here are recommended configurations for different scenarios:
Configuration
Latency
SPKCACHE_LEN
FIFO_LEN
CHUNK_LEN
RIGHT_CONTEXT
UPDATE_PERIOD
Very high latency (offline)
30.4 s
264
40
340
40
300
Low latency
1.04 s
264
264
9
4
222
Very low latency
0.64 s
264
264
6
2
222
Ultra-low latency
0.32 s
264
264
3
1
222
Note.Latency refers to Input Buffer Latency, calculated as (CHUNK_LEN + RIGHT_CONTEXT) Γ 80 ms. This value does not include computational processing time.
If you need to perform a comprehensive evaluation and calculate the accuracy and speed metrics across different parameter settings, use the NeMo example script e2e_diarize_speech.py. This script allows you to test the streaming behavior of the model by adjusting key parameters like chunk_len, fifo_len, chunk_right_context and spkcache_update_period.
import torch
from transformers import AutoModelForAudioFrameClassification, AutoProcessor
from transformers.audio_utils import load_audio
model_id = "nvidia/Nemotron-3-Diarization"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForAudioFrameClassification.from_pretrained(model_id, device_map="auto")
sampling_rate = processor.feature_extractor.sampling_rate
audio = load_audio(
"https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/diarization_example.mp3",
sampling_rate=sampling_rate,
)
inputs = processor(audio, sampling_rate=sampling_rate).to(model.device, dtype=model.dtype)
with torch.inference_mode():
logits = model(**inputs).logits # (1, num_frames, 8), one frame every 10 ms
segments = processor.extract_speaker_dict(logits, inputs.attention_mask)[0]
for segment in segments:
print(f"speaker_{segment['Speaker']}: {segment['Start']:.2f}s - {segment['End']:.2f}s")
β‘οΈ Streaming diarization
Audio arrives chunk by chunk, and each forward takes one chunk: the processor cuts it for its streaming_mode and adds num_lookahead_frames, the number of trailing look-ahead frames the model attends to but does not score, since they open the next chunk. The forward returns the speaker_cache to pass to the next call. The last chunk of a session is extracted with is_last_audio_chunk=True: it has no look-ahead, so every remaining frame is scored.
streaming_mode
LatencyΒΉ
"low_latency" (default)
1.04 s
"very_low_latency"
0.64 s
"ultra_low_latency"
0.32 s
ΒΉ Audio to wait for before the model runs on a chunk: the chunk plus its look-ahead, excluding compute time.
import torch
from transformers import AutoModelForAudioFrameClassification, AutoProcessor
from transformers.audio_utils import load_audio
model_id = "nvidia/Nemotron-3-Diarization"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForAudioFrameClassification.from_pretrained(model_id, device_map="auto")
processor.set_streaming_mode("low_latency") # the default, can also be "very_low_latency" and "ultra_low_latency"
print(f"Streaming latency: {processor.streaming_latency_ms} ms")
sampling_rate = processor.feature_extractor.sampling_rate
audio = load_audio(
"https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/diarization_example.mp3",
sampling_rate=sampling_rate,
)
def inputs_generator():
"""Yields the processor outputs of each chunk."""
yield processor(
audio[: processor.num_samples_first_audio_chunk],
sampling_rate=sampling_rate,
is_streaming=True,
is_first_audio_chunk=True,
)
mel_frame_idx = processor.num_mel_frames_per_step
start_idx = processor.audio_chunk_start(mel_frame_idx)
while (end_idx := start_idx + processor.num_samples_per_audio_chunk) <= audio.shape[0]:
yield processor(
audio[start_idx:end_idx],
sampling_rate=sampling_rate,
is_streaming=True,
is_first_audio_chunk=False,
)
mel_frame_idx += processor.num_mel_frames_per_step
start_idx = processor.audio_chunk_start(mel_frame_idx)
# the audio ended: the frames left in the buffer are the last ones of the session
yield processor(
audio[start_idx:],
sampling_rate=sampling_rate,
is_streaming=True,
is_first_audio_chunk=False,
is_last_audio_chunk=True,
)
speaker_cache, logits = None, []
with torch.inference_mode():
for inputs in inputs_generator():
inputs = inputs.to(model.device, dtype=model.dtype)
# `inputs` carries `num_lookahead_frames` for every chunk but the last, `speaker_cache` links the chunks
outputs = model(**inputs, speaker_cache=speaker_cache)
logits.append(outputs.logits) # the chunk's frames, without its look-ahead
speaker_cache = outputs.speaker_cache
logits = torch.cat(logits, dim=1) # (1, num_frames, 8), one frame every 10 ms
segments = processor.extract_speaker_dict(logits)[0] # [{"Start": 0.0, "End": 15.43, "Speaker": 0}, ...]
Maximum Duration: Not limited when chunked inference is used.
Other Properties Related to Input: Input audio must be sampled at 16 kHz and is converted into 10 ms Mel-spectrogram features. Chunked inference supports recordings without a fixed maximum duration.
Output Parameters: A two-dimensional tensor with shape [T, 8], where T is the number of output frames and each value is a per-speaker activity probability in the range [0, 1].
Output Frame Resolution: The default frame stride is 10 ms and can be configured to any multiple of 10 ms, such as 30 ms, 80 ms, or 240 ms.
Speaker Ordering: The eight speaker channels are ordered by the speakers' arrival time in the input audio.
Derived Output: Speaker activity probabilities can be converted into start time, end time, and a generic speaker label, for example ["speaker1", 0.51, 12.62].
Other Properties Related to Output: The output frame resolution is configurable in multiples of 10 ms. Speaker channels are ordered by first arrival, and probabilities can be postprocessed into generic speaker labels with start and end timestamps.
RTX PRO 6000 Blackwell Workstation Edition, RTX PRO 6000 Blackwell Max-Q Workstation Edition, RTX PRO 5000 Blackwell, RTX PRO 4500 Blackwell Workstation Edition, RTX PRO 4000 Blackwell, RTX PRO 4000 Blackwell SFF Edition, and RTX PRO 2000 Blackwell.
RTX PRO 6000 Blackwell Server Edition and RTX PRO 4500 Blackwell Server Edition.
NVIDIA B200, B300, GB200, and GB300.
Blackwell NVIDIA Workstations: NVIDIA DGX Spark and NVIDIA DGX Station.
The integration of foundation and fine-tuned models into AI systems requires additional testing using use-case-specific data to ensure safe and effective deployment. Following the V-model methodology, iterative testing and validation at both unit and system levels are essential to mitigate risks, meet technical and functional requirements, and ensure compliance with safety and ethical standards before deployment.
The model can be integrated into conversational AI systems through NeMo Framework inference pipelines to produce per-speaker activity probabilities or postprocessed generic speaker labels and timestamps.
The model was trained on a combination of real conversations and multi-talker audio mixtures with 1-8 speakers simulated using the FastMSS toolkit [\[3\]](#ref-3).
Real conversations: Total duration is around 10,000 hours.
Dataset
Language
Split or description
Fisher English
English
Training Part 1 and Part 2
AMI Meeting Corpus
English
Train and development; force-aligned [\[4\]](#ref-4)
ICSI
English
Full
VoxConverse v0.3
Multilingual
Development and test
AISHELL-4
Mandarin
Train
Third DIHARD Challenge
Multilingual
Development
2000 NIST Speaker Recognition Evaluation
Multilingual
CALLHOME Part 1
AliMeeting Mandarin Corpus
Mandarin
Train; force-aligned [\[4\]](#ref-4)
DiPCo β Dinner Party Corpus
English
Development
NOTSOFAR1
English
Train and development; force-aligned [\[3\]](#ref-3)
DISPLACE 2024
English, Hindi, Kannada, Telugu, Bengali
Development and evaluation
DISPLACE-M 2026
Hindi, Kannada
Development 1, 2, and 3
David AI β [D2] Multispeaker
English
Licensed under agreement; 3-4 speakers 1,000 hours
YODAS-v2
Multilingual
Pseudo-labeled 5,000-hour subset
Data used to simulate multi-talker audio mixtures: Total duration of single-speaker audio recordings is around 28,000 hours.
Dataset
Language
Split or description
LibriSpeech
English
Train-960h
AMI Meeting Corpus (individual headsets)
English
Train and development
AliMeeting Mandarin Corpus (individual headsets)
Mandarin
Train
Fisher English
English
Training Part 1 and Part 2
David AI β [D1] Chit Chat
English
Licensed under agreement
David AI β [D2] Multispeaker
English
Licensed under agreement
David AI β [D6a] Podcast
English
Licensed under agreement
David AI β [D6b] Advice
English
Licensed under agreement
David AI β [D7] Expert Assistant
English
Licensed under agreement
David AI β [D12] Human Transcripts
21 languages
Licensed under agreement
MUSAN noises
Not applicable
Noises for augmentation
Multi-talker audio mixtures used in training:
Librispeech: 6,694 hours
AMI: 6,743 hours
AliMeeting: 6,745 hours
Fisher English: 6,755 hours
David AI English: 36,458 hours
David AI Multilingual: 19,216 hours
Properties: Approximately 10,000 hours of real conversations plus 82,611 hours of simulated multi-talker audio mixtures. The data modality is audio and includes conversational speech, telephone calls, meetings, podcasts, noise augmentation, and synthetic mixtures. Languages include English, Mandarin, Hindi, Kannada, Telugu, Bengali, and other languages represented in the multilingual sources. Voice recordings may constitute personal data.
Properties: 901 condition-specific audio recordings comprising real-world multilingual conversational speech captured under telephone, meeting, near-field, far-field, and multi-microphone conditions. The data may contain personal data in the form of voice recordings. Languages include English, Mandarin, and other languages represented in the multilingual benchmarks.
The model training was initialized with a Transformer-based NEST [\[5\]](#ref-5) SSL checkpoint. Training was performed on 8 nodes of 8ΓNVIDIA A100-SXM4-80GB GPUs in two stages.
Use the published reference labels to reproduce these results!#
The DER scores reported in this model card were computed using the exact reference annotations identified in the Labels column above. Reference RTTMs are part of the evaluation protocol: changing the reference labels changes the measured result.
We use forced-alignment based reference labels for AMI, AliMeeting and NOTSOFAR1 because the original segment-level annotations were created primarily for transcription rather than frame-accurate diarization evaluation. These annotations may label substantial within-segment silence as speech, thereby overestimating reference speaker activity. When used for DER scoring, they can inflate missed-speech error by penalizing a diarization system for correctly predicting non-speech during those intervals. Forced alignment provides more precise speech boundaries and therefore a more appropriate and interpretable reference for frame-level diarization evaluation. Please refer to [\[4\]](#ref-4) for a detailed discussion of this annotation issue and the forced-alignment methodology.
The Forced alignment links above point to the public repositories containing the reference RTTM files used for evaluation.
Results obtained using different reference labels constitute a different evaluation protocol and are not directly comparable with the numbers reported here. Before reporting a reproduction discrepancy, score the same model outputs using the linked reference RTTMs, the listed dataset split, and the collar and overlap settings specified in the Metrics section.
Diarization Error Rate (DER): The primary metric for diarization performance, consisting of false alarm (FA), missed speech (Miss), and speaker confusion (Conf).
All evaluations include overlapping speech.
Collar tolerance is 0 s for DIHARD III Eval, AliMeeting Test, AMI Test and NOTSOFAR1 Eval.
Collar tolerance is 0.25 s for CALLHOME-part2.
Speaker Counting Accuracy (SCA):1 when the predicted and ground-truth speaker counts are equal; otherwise 0. This metric does not capture the magnitude of a counting error.
Speaker Counting Mean Absolute Error (MAE):|predicted speaker count - ground-truth speaker count|. This metric is more informative than SCA because it reflects magnitude of speaker counting error.
Real-Time Factor Speedup (RTFx):total audio duration / total processing time.
Nemotron 3 Diarization is intended for speaker diarization in live or recorded conversational audio, including meetings, calls, podcasts, and speech-recognition pipelines that need generic speaker labels and speaker timestamps.
If you use this model in your research, please cite:
@misc{medennikov2026nemotron3diarization,
title={Nemotron 3 Diarization: Advancing the Accuracy-Efficiency Frontier in Streaming Speaker Diarization},
author={Ivan Medennikov and Taejin Park and Tatiana Timofeeva and He Huang and Alexander Polok and Sofia Kostandian and Weiqing Wang and Dongji Gao and Jagadeesh Balam and Boris Ginsburg},
year={2026},
eprint={2611.12246},
archivePrefix={arXiv},
primaryClass={eess.AS},
url={https://arxiv.org/abs/2611.12246}
}
NVIDIA believes Trustworthy AI is a shared responsibility and has established policies and practices to enable development for a wide array of AI applications. Developers should evaluate the model with use-case-specific data and ensure that the complete system meets the requirements of the relevant industry and deployment context.