Traduzione automatica · Originale inglese

Diarizzazione dei parlanti

Identificare chi ha parlato quando in una registrazione multi-altoparlante. Quattro motori sono disponibili: leggero Pyannote (il CLI predefinito), full-pipeline Community-1 (CoreML + nativo PLDA/VBx), streaming Sortformer (CoreML, Neural Engine), e Nemotron 3 (CoreML INT8 o MLX INT8).

Motori

Selezionare il motore con --engine pyannote (default), --engine community1, --engine sortformer, or --engine nemotron3

Pyannote (default)

Condotto a due stadi: Pyannote processi di segmentazione sovrapposizione di finestre con catena di altoparlanti basata su attività (raffronto tra le zone sovrapposte) per assegnare etichette di altoparlante globali. WeSpeaker l'estrazione di embedding consente l'identificazione dell'altoparlante di destinazione tramite l'audio di registrazione.

Community-1 ( CoreML + VBx nativo)

Il pieno Pyannote Community-1 fascio CoreML: 10-secondo PyanNet segmentazione finestre avanzare ogni secondo, mascherato WeSpeaker embeddings feed centroid AHC e un 256→128 Trasformazione PLDA, poi nativo Swift VBx e l'assegnazione limitata producono cluster globali. 256centroide dimensionale per diffusore rilevato e supporta i limiti esatti, minimi o massimi del conteggio dell'altoparlante.

Ordinatore ( CoreML)

NVIDIA modello di diarizzazione neurale end-to-end. Predice direttamente l'attività di diffusore per frame per un massimo di 4 altoparlanti senza fasi di inserimento o clustering separate. Corre su Neural Engine tramite CoreML con buffer di stato in streaming (FIFO + buffer di altoparlante).

Per audio dal vivo, SortformerStreamingSession corre .streaming Sortformer modello incrementale con 16 kHz mono PCM buffer di qualsiasi dimensione. Una volta il suo 560 ms lookahead è disponibile, avanza in 480 ms passi audio; una serie M di cinque file Neural Engine pilota misurato 12.4 latenza mediana per 500 Le etichette di altoparlante seguono la Cache di Speaker dell'Ordine di arrivo invece di ri-cluster ogni finestra, e ogni spinta restituisce un'istantanea a flusso intero. finish() Nella prova di equivalenza con il modello, i segmenti finali corrispondono a tutto il buffer .streaming diarizzazione all'interno di circa un telaio 80 ms.

Nemotron 3 ( CoreML o MLX)

NVIDIA Nemotron 3 predizioni 10 ms attività di oratore fino a otto altoparlanti anonimi. INT8 esportazione download automaticamente da CoreML o MLX. Il backend CLI predefinito è CoreML; scegliere MLX con --nemotron3-backend mlx. Entrambi supportano un fascio locale attraverso --nemotron3-directory.

Su un interno 132-registrare set diarizzazione (12.82 ore, 0.25 s collar), il spedito Nemotron 3 MLX e CoreML runtime segnati 10.98% e 11.20% in piscina DER, rispettivamente, senza guasti. Su 48 Incontri inglesi, hanno segnato 10.31% e 10.24%. Vedi il comparazione e limiti di valutazione per lingua.

Nota

Il --target-speaker e --embedding-engine le bandiere sono disponibili solo con il default Pyannote motore. Community-1 restituisce cluster centroids attraverso il suo Swift API; Sortformer e Nemotron 3 non producono embeddings di diffusori.

Per i risultati misurati attraverso i sistemi di diarizzazione e otto lingue, segnati con un righello, vedere i benchmark di diarization speaker

Pubblicato CALLHOME

Di seguito è la linea di base anonime grezzo pubblicata da NVIDIA per il diar_streaming_sortformer_4spk-v2Si tratta di un riferimento esterno, non di una misura locale della conversione speech-swift di CoreML e non di un risultato di attribuzione denominato-speaker.

DatasetCondizioneDER
CALLHOME Parte 22 relatori di riferimento6.57%
CALLHOME Parte 23 altoparlanti di riferimento10.05%
CALLHOME Parte 24 relatori di riferimento12.44%

Tutte le righe utilizzano latenza input-buffer 1.04 s, sovrapposizione inclusa, un colletto di 0.25 s e post-elaborazione sintonizzata su disgiunta CALLHOME Parte 1. CALLHOM è concesso in licenza e non è in bundle. Local diarization-bench report comparabili risultati separatamente dal conteggio di riferimento nella console e in JSON sotto byReferenceSpeakerCount

Community-1 Pipeline

Community-1 corre entrambe le fasi neurali con CoreML e tutti i processi di elaborazione degli host Swift, così non si carica MLX o richiedere Metal libreria shader. I default pubblicati sono conservati: decodifica hard powerset, maschere a singolo diffusore pulite con il ritorno a monte a corto raggio, 0.6 soglia centroid-linkage, Fa=0.07, Fb=0.8, e alla maggior parte 20 VBx iterations.

Sul subset a cinque file fisso VoxConverse release (setti 1,057.49, colletto 0.25-secondo, sovrapposizione inclusa), uscita Swift riscossa con pyannote.metrics misurato 4.66% DER / 21.43% JER; il riferimento CoreML pubblicato misurato 4.65% / 21.42%. Questo è un piccolo controllo di parità, non una richiesta di qualità dataset-wide.

Con il segnapunti frame-grid di speech-swift sullo stesso sottoinsieme, Community-1 misurato 9.31% DER / 16.20% JER, 25.5× in tempo reale, e 1.54 GB picco RSS. Il motore predefinito Pyannote misurato 5.03% / 9.28%, 105.7× in tempo reale, e 393 MB. Community-1 è quindi un opzionale pipeline upstream-parity con i limiti del contatore e centroids restituiti, non un'accuratezza universale o un aggiornamento della velocità.

Pyannote Pipeline

La pipeline di default viene eseguita in due fasi:

Fase 1: Segmentazione + Catena di altoparlanti

Pyannote segmentation-3.0 elabora finestre scorrevoli 10-secondo con sovrapposizione 50%. A decoder powerset converte il 7-class output in probabilità di per-speaker (fino a 3 diffusori locali per finestra). 5-secondo sovrapposizione — l'identità dell'altoparlante viene propagata attraverso le finestre mediante l'elaborazione Correlazione di Pearson tra tracce di probabilità nella zona sovrapposta, con avidità esclusiva per gli ID di altoparlante globali coerenti.

Fase 2: Embedding post-hoc

Dopo la diarizzazione, WeSpeaker ResNet34-LM estrae un centroide dimensionale 256 incorporato per diffusore, che consente l'estrazione dell'altoparlante target (--target-speaker) ma non guidare l'assegnazione dell'altoparlante stesso.

Migrazione da pyannote.audio

Se vieni da Python pyannote.audio biblioteca — sostituzione di una Pipeline sottoclasse che imposta pipeline.segmentation = ..., o allontanarsi da un hosting server pyannote/speaker-diarization-3.1 — Soniqo avvolge lo stesso modello Pyannote-Segmentation-3.0 e lo esegue interamente on-device su Apple Silicon. No Python runtime, no CUDA, no Hugging Face token a inference time.

pyannote.audio ( Python)Soniqo (Swift)
Pipeline.from_pretrained("pyannote/speaker-diarization-3.1") DiarizationPipeline.fromPretrained()
pipeline(audio_file) pipeline.diarize(audio: samples, sampleRate: 16000)
pipeline.segmentation = ... (sottoclasse doganale) Corretto: Pyannote-Segmentation-3.0 ( MLX o CoreML, auto-selezionato)
diarization.itertracks(yield_label=True) for seg in result.segments { ... }
diarization.write_rttm(file) CLI: --rttm
pyannote.metrics.diarization.DiarizationErrorRate CLI: --score-against reference.rttm

Il Pyannote-Segmentation-3.0 i pesi vengono convertiti dall'a monte HuggingFace checkpoint, quindi i logits di segmentazione sono numericamente equivalenti all'interno della tolleranza di precisione del galleggiante. La catena di post-segmentazione (la correlazione tra le finestre sovrapposte + l'avidità esclusiva corrispondenza) e post-hoc WeSpeaker Le fasi di embedding sono reimplementate Swift ma produrre un output RTTM comparabile al riferimento Python Conduttura.

Non ancora supportato

Non c'è streaming OnlineSpeakerDiarization equivalente per il motore Pyannote. Per l'uso in tempo reale di diarizzazione --engine sortformer invece, che gestisce il modello Sortformer con buffer di stato FIFO e altoparlante-cache.

Uso CLI

# Basic diarization (pyannote, default)
.build/release/speech diarize meeting.wav

# Community-1 (CoreML + native PLDA/VBx)
.build/release/speech diarize meeting.wav --engine community1
.build/release/speech diarize meeting.wav --engine community1 --num-speakers 2

# End-to-end Sortformer (CoreML)
.build/release/speech diarize meeting.wav --engine sortformer

# Nemotron 3 (CoreML default; MLX optional)
.build/release/speech diarize meeting.wav --engine nemotron3
.build/release/speech diarize meeting.wav --engine nemotron3 --nemotron3-backend mlx

# RTTM output format (for evaluation)
.build/release/speech diarize meeting.wav --rttm

# JSON output
.build/release/speech diarize meeting.wav --json

Estrazione di altoparlante target

Fornisce audio di registrazione di un diffusore noto per estrarre solo i loro segmenti da una registrazione. Il gasdotto calcola l'integrazione dell'audio di registrazione e trova il cluster con la più alta somiglianza di cosene.

# Extract segments for a specific speaker
.build/release/speech diarize meeting.wav --target-speaker enrollment.wav

DER Scommesse

Valutare la qualità della diarizzazione segnando contro un file RTTM di riferimento. Il gasdotto calcola il tasso di errore di diarizzazione (DER), che misura la percentuale di tempo che viene attribuita in modo errato.

# Score against reference RTTM
.build/release/speech diarize meeting.wav --score-against reference.rttm

RT RT RT RT produzione di energia elettrica

La bandiera --rttm produce l'uscita Rich Transcription Time Marked, un formato standard utilizzato per la valutazione della diarizzazione.

SPEAKER filename 1 start_time duration <NA> <NA> speaker_id <NA> <NA>

Opzioni

OpzioneDesignazione
--target-speakerIscrizioni audio per l'estrazione di altoparlante target (solo piannota)
--embedding-engineMotore di embedding del diffusore: mlx o coreml (solo in piannota)
--vad-filterPrefiltro con Silero VAD (solo per piannota)
--community1-compute-unitsane (default) cpu, gpu, o all
--num-speakersConto preciso dell'altoparlante ( Community-1)
--min-speakersConto minimo dell'altoparlante ( Community-1, default 1)
--max-speakersConto massimo del diffusore ( Community-1
--rttmUscita in formato RTTM
--jsonFormato di uscita JSON
--score-againstReferenza RTTM file per la valutazione DER
Importante

La diarizzazione funziona meglio con le registrazioni che hanno un chiaro girante di altoparlante. Il discorso altamente sovrapposto può ridurre l'accuratezza.

Download del modello

I modelli vengono scaricati automaticamente sul primo utilizzo:

ComponentiModelloDimensioneHuggingFace
SegmentazionePyannote-Segmentation-3.05,7 MBaufklarer/Pyannote-Segmentation-MLX
Altoparlante EmbeddingWeSpeaker-ResNet34-LM (MLX)~ 25 MBaufklarer/WeSpeaker-ResNet34-LM-MLX
Altoparlante EmbeddingWeSpeaker-ResNet34-LM (CoreML)~ 25 MBaufklarer/WeSpeaker-ResNet34-LM-CoreML
pipeline Community-1PyanNet + mascherato WeSpeaker + PLDA/VBx~ 32 MBaufklarer/Pyannote-Community-1-CoreML
SortformerDiarizzazione di Sortformer ( CoreML)~240 MBaufklarer/Sortformer-Diarization-CoreML
Nemotron 3Diarizzazione INT8 ( CoreML o MLX)~ 100 MB ciascunoCoreML · MLX

Swift API

import SpeechVAD

let pipeline = try await DiarizationPipeline.fromPretrained()
let result = pipeline.diarize(audio: samples, sampleRate: 16000)
for seg in result.segments {
    print("Speaker \(seg.speakerId): [\(seg.startTime)s - \(seg.endTime)s]")
}

// Target speaker extraction
let targetEmb = pipeline.embeddingModel.embed(audio: enrollmentAudio, sampleRate: 16000)
let segments = pipeline.extractSpeaker(
    audio: meetingAudio, sampleRate: 16000,
    targetEmbedding: targetEmb
)

// Full Community-1 pipeline with bounded speaker counts
let community1 = try await Community1DiarizationPipeline.fromPretrained()
try community1.prewarm()
let attributed = try community1.diarize(
    audio: meetingAudio,
    sampleRate: 16000,
    speakerBounds: Community1SpeakerBounds(minimum: 2, maximum: 6)
)