Automatische vertaling · Engels origineel

Sprekerdiarisatie

Identificeer wie er sprak in een multi-luidspreker opname. Vier motoren zijn beschikbaar: lichtgewicht Pyannote (de CLI standaard), volledige pipeline Community-1 (CoreML + native PLDA/VBx), streaming Sortvormer (CoreML, Neural Engine), en Nemotron 3 (CoreML INT8 of MLX INT8).

Motoren

Selecteer de motor met --engine pyannote (standaard), --engine community1, --engine sortformer, of --engine nemotron3.

Pyannote (standaard)

Tweetrapspijplijn: Pyannote segmentatieprocessen overlappen vensters met activiteitsgebaseerde speakerketen (Pearson-correlatie in overlappende zones) om globale luidsprekerlabels toe te wijzen. Post-hoc WeSpeaker inbeddingsextractie maakt de identificatie van doelluidsprekers via inschrijfaudio mogelijk.

Community-1 (CoreML + native VBx)

De volledige Pyannote Community-1 CoreML bundel: 10-seconde PyanNet segmentatievensters gaan elke seconde vooruit, gemaskerd WeSpeaker inbeddingen voeden centroïde AHC en een 256→128 PLDA transformatie, dan native Swift VBx en beperkte toewijzing produceren globale clusters. Het geeft een 256-dimensionale centroïde per gedetecteerde speaker terug en ondersteunt exacte, minimale of maximale speaker-count grenzen.

Sortvormer (CoreML)

NVIDIA's end-to-end neurale diarisatiemodel. Voorspelt direct per frame speakeractiviteit voor maximaal 4 speakers zonder aparte inbed- of clusterstadia. Runs op Neural Engine via CoreML met streaming state buffers (FIFO + speaker cache).

Voor live audio, SortformerStreamingSession draait de .streaming Sortformer model incrementeel met 16 kHz mono PCM buffers van elke grootte. Zodra de 560 ms lookahead beschikbaar is, gaat het verder in 480 ms audiostappen; een vijf-file M-serie Neural Engine pilot gemeten 12,4 ms mediane latency per 500 ms push. Speaker labels volgen de Aankomst-Order Speaker Cache in plaats van her-clusteren elk venster, en elke push geeft een hele stream snapshot terug. finish() flusht de gebufferde staart. In de model-gated equivalentietest, eindigende segmenten met hele-buffer .streaming diarization binnen ongeveer één 80 ms frame.

Nemotron 3 (CoreML of MLX)

NVIDIA Nemotron 3 voorspelt 10 ms speakeractiviteit voor maximaal acht anonieme speakers. De definitieve INT8 export download automatisch van CoreML of MLX. De standaard CLI backend is CoreML; kies MLX met --nemotron3-backend mlx. Beide ondersteunen een lokale bundel door --nemotron3-directory.

Op een interne 132-recording diarization set (12,82 uur, 0,25 s kraag), scoorde de verzonden Nemotron 3 MLX en CoreML runtimes respectievelijk 10,98% en 11,20% samengevoegd DER, zonder storingen. Op 48 vergaderingen in het Engels scoorde ze 10,31% en 10,24%. Zie de per taalvergelijking en evaluatielimieten.

Opmerking

De --target-speaker en --embedding-engine vlaggen zijn alleen beschikbaar met de standaard Pyannote-engy. Community-1 geeft clustercentroïden terug via Swift API; Sortformer en Nemotron 3 produceren geen speakerbeddingen.

Voor gemeten resultaten over de diarization systemen en acht talen, gescoord met één liniaal, zie de speaker diarization benchmarks.

Gepubliceerde CALLHOME Baseline

Het volgende is NVIDIA's gepubliceerde ruwe anonieme speaker baseline voor diar_streaming_sortformer_4spk-v2. Het is een externe referentie, geen lokale meting van speech-swift's CoreML conversie en geen naam-speaker attribution resultaat.

Dataset VoorwaardeDER
CALLHOME Deel 22 referentiesprekers6.57%
CALLHOME Deel 23 referentiesprekers10.05%
CALLHOME Deel 24 referentiesprekers12.44%

Alle rijen gebruiken 1,04 s invoerbufferlatentie, overlap inbegrepen, een 0.25 s kraag, en post-verwerking afgestemd op dissociated CALLHOME deel 1. CALLHOME is gelicentieerd en is niet gebundeld. Lokale diarization-bench rapporteert vergelijkbare resultaten afzonderlijk door referentiespreker tellen in de console en in JSON onder byReferenceSpeakerCount.

Community-1 Pijpleiding

Community-1 draait beide neurale stadia met CoreML en alle hostverwerkingen in Swift, zodat het MLX niet laadt of een Metal shaderbibliotheek vereist. De gepubliceerde standaardwaarden worden bewaard: harde en/of harde decodering, schone enkelluidende maskers met de upstream fallback van de shorttrack, 0,6 centroïde-linkagedrempel, Fa=0.07, Fb=0.8 en hoogstens 20 VBx-iteraties.

Op de vaste vijf-file VoxConverse release subset (1.057.49 seconden, 0,25-seconde kraag, overlap inbegrepen), Swift output gerecord met pyannote.metrics gemeten 4,66% DER / 21,43% JER; de gepubliceerde CoreML referentie gemeten 4,65% / 21,42%. Dit is een kleine pariteitscontrole, niet een dataset-brede kwaliteit claim.

Met speech-swift's frame-grid scorer op dezelfde subset, Community-1 gemeten 9.31% DER / 16.20% JER, 25,5× real-time, en 1,54 GB piek RSS. De standaard Pyannote motor gemeten 5.03% / 9.28%, 105,7× real time, en 393 MB. Community-1 is daarom een optionele upstream-parity pijpleiding met speaker-count grenzen en geretourneerde centroïden, niet een universele nauwkeurigheid of snelheidsupgrade. Scores van de twee scoremethoden zijn niet direct vergelijkbaar.

Pyannote Pijpleiding

De standaard pijpleiding loopt in twee fasen:

Fase 1: Segmentatie + Straling van de spreker

Pyannote segmentation-3.0 verwerkt 10-seconde schuifvensters met 50% overlapping. Een powerset decoder zet de 7-klasse output om in per-luidbaarheid (tot 3 lokale luidsprekers per venster). Aangrenzende vensters delen een 5-seconde overlappende luidsprekeridentiteit wordt over de vensters uitgedeeld door Pearson correlatie tussen waarschijnlijkheidssporen in de overlappende zone, met hebzuchtige exclusieve matching voor consistente wereldwijde luidspreker-ID's.

Fase 2: Post-hoc-inbedding

Na diarisatie, WeSpeaker ResNet34-LM haalt een 256-dimensionale centroïde inbedding per speaker. Deze inbeddingen maken het extraheren van de doelluidspreker (--target-speaker) mogelijk, maar sturen de speakeropdracht niet zelf.

Migreren van pyannote.audio

Als je uit de Python pyannote.audio bibliotheek komt, dan moet je een Pipeline subklasse vervangen die pipeline.segmentation = ... instelt, of van een serverhosting pyannote/speaker-diarization-3.1 .. Soniqo hetzelfde Pyannote-Segmentation-3.0 model verwijdert en het volledig op het apparaat draait op Apple Silicon. No Python runtime, no CUDA, no Hugging Face token op interferentietijd.

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 = ... (custom subclass) Vast: Pyannote-Segmentation-3.0 (MLX of CoreML, automatisch geselecteerd)
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

De Pyannote-Segmentation-3.0 gewichten worden omgezet uit de upstream HuggingFace controlepunt, dus segmentatielogits zijn numeriek gelijkwaardig binnen de tolerantie voor floatprecisie. De postsegmentatieketen (Pearson correlatie tussen overlappende vensters + hebzuchtige exclusieve matching) en post-hoc WeSpeaker inbeddingsfasen worden in Swift opnieuw uitgevoerd, maar produceren vergelijkbare RTTM-uitvoer naar de referentie Python pijpleiding.

Nog niet ondersteund

Er is geen streaming OnlineSpeakerDiarization-equivalent voor de Pyannote-motor. Voor realtime diarizatie gebruik --engine sortformer in plaats daarvan, die het Sortformer-model draait met FIFO- en speakercache-statusbuffers.

CLI-gebruik

# 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

Uitpakken van doelluidspreker

Zorg voor inschrijfaudio van een bekende luidspreker om alleen hun segmenten uit een opname te halen. De pijplijn berekent de luidspreker inbedding van het inschrijfgeluid en vindt de cluster met de hoogste cosinus overeenkomst.

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

DER Score

Evalueer diarization kwaliteit door te scoren tegen een referentie RTTM bestand. De pijpleiding berekent de Diarization Error Rate (DER), die het percentage tijd meet dat verkeerd wordt toegeschreven.

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

RTTM-uitvoer

De --rttm vlag produceert Rich Transcription Time Gemarkeerde uitvoer, een standaardformaat dat gebruikt wordt voor diarization evaluatie. Elke regel volgt het formaat:

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

Opties

Optie Omschrijving
--target-speakerAudio inschrijven voor speakerextractie (alleen pyannote)
--embedding-engineSpeaker inbedding motor: mlx of coreml (alleen pyannote)
--vad-filter Voorfilter met Silero VAD (alleen pyannote)
--community1-compute-unitsane (standaard), cpu, gpu, of all
--num-speakersBekende exacte speakertelling (Community-1 alleen)
--min-speakersMinimum aantal sprekers (Community-1, standaard 1)
--max-speakersMaximum aantal sprekers (Community-1)
--rttm Uitvoer in RTTM-formaat
--jsonJSON-uitvoerformaat
--score-against Referentie RTTM-bestand voor DER-evaluatie
Belangrijk

Diarization werkt het best met opnames die duidelijke speakerdraaiingen hebben. Zeer overlappende spraak kan de nauwkeurigheid verminderen. Speakertelling wordt automatisch bepaald.

Modeldownloads

Modellen worden automatisch gedownload bij eerste gebruik:

OnderdeelModel GrootteHuggingFace
SegmentatiePyannote-Segmentation-3.0~5,7 MBaufklarer/Pyannote-Segmentation-MLX
Speaker inbeddingWeSpeaker-ResNet34-LM (MLX)25 MBaufklarer/WeSpeaker-ResNet34-LM-MLX
Speaker inbeddingWeSpeaker-ResNet34-LM (CoreML)25 MBaufklarer/WeSpeaker-ResNet34-LM-CoreML
Community-1 pijpleidingPyanNet + gemaskerd WeSpeaker + PLDA/VBx~32 MBaufklarer/Pyannote-Community-1-CoreML
SortvormerSortformer diarization (CoreML)~240 MBaufklarer/Sortformer-Diarization-CoreML
Nemotron 3Diarisatie INT8 (CoreML of MLX)100 MB elkCoreML · 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)
)