Strojový překlad · Anglický originál

Diarizace mluvčích

Identifikujte, kdo mluvil, když v multireproduktoru záznam. Čtyři motory jsou k dispozici: lehký Pyannote (výchozí hodnota CLI), plnopotrubí Community-1 (CoreML + native PLDA / VBx), streaming Sortformer (CoreML, Neural Engine) a Nemotron 3 (CoreML INT8 nebo MLX INT8).

Motory

Vyberte motor s --engine pyannote (přednastaveno), --engine community1, --engine sortformernebo --engine nemotron3.

Pyannote (přednastaveno)

Plynovod Two- stage: Segmentace Pyannote proces překrývání oken s řetězem reproduktorů na bázi aktivity (Pearsonova korelace v překrývacích zónách) pro přiřazení globálních reproduktorů štítky. Post- hoc extrakce pomocí WeSpeaker umožňuje cílovou identifikaci reproduktorů přes záznam audio.

Community-1 (CoreML + native VBx)

Plný Pyannote Community-1 CoreML svazek: 10-druhé PyanNet segmentace okna postupují každou sekundu, maskovaný WeSpeaker Vznik těžiště AHC a 256→128 PLDA transformace, pak nativní Swift VBx a omezený úkol produkují globální clustery. Vrací jeden 256-dimenzionální těžiště na detekovaný reproduktor a podporuje přesné, minimální nebo maximální hlasitost.

Sortformer (CoreML)

Model end- to- end neurální diarizace NVIDIA. Přímo předpovídá per- framerovou aktivitu reproduktoru pro 4 reproduktory bez samostatného vkládání nebo seskupování. Běží na Neural Engine přes CoreML s streamingovým stavovým pufrem (FIFO + reproduktor cache).

Pro živý zvuk, SortformerStreamingSession běží .streaming Sortformer model incrementally with 16 kHz mono PCM buffers of any size. Jakmile je k dispozici jeho 560 ms look forward, postupuje v 480 MS audio kroky; 5-soubor M- series Neural Engine pilot měřil 12.4 s mediánem latence na 500 ms push. Řečnické štítky sledovat Arrival- Order Speaker Cache místo reclustering každé okno, a každý push vrací celou stream snapsshot. finish() proplachuje buffered ocas. V modelově-routed rovnocennosti test, finální segmenty odpovídají whole-buffer .streaming diarizace v rámci jednoho 80 ms rámce.

Nemotron 3 (CoreML nebo MLX)

NVIDIA Nemotron 3 předpovídá aktivitu reproduktoru 10 pro až osm anonymních reproduktorů. Konečný export INT8 automaticky stahuje z CoreML nebo MLX. Výchozí CLI backend je CoreML; zvolte MLX s --nemotron3-backend mlx. Oba podporují místní svazek přes --nemotron3-directory.

Na vnitřní 132-nahrávací diarizační set (12.82 hodiny, 0.25 límec), odeslaný Nemotron 3 MLX a CoreML skórované runtimes 10.98% a 11.20% sdružené DER, resp., bez selhání. Na 48 Anglická setkání, oni skórovali 10.31% a 10.24%Podívej se na to. pro srovnání a hodnocení jazyků.

Poznámka

V --target-speaker a --embedding-engine Vlajky jsou k dispozici pouze s výchozí Pyannote Motor. Community-1 vrací shluky centroidů přes jeho Swift API; Sortformer a Nemotron 3 neprodukujte reproduktory.

Pro naměřené výsledky napříč diarizačními systémy a osmi jazyky, zaznamenané s jedním pravítkem, viz referenční hodnoty pro diarizaci reproduktoru.

Zveřejněná základní hodnota CALLHOME

Níže je uveden NVIDIA je zveřejněna syrová anonymní- reproduktor základní pro diar_streaming_sortformer_4spk-v2. Jedná se o externí referenci, nikoli lokální měření speech-swift konverze CoreML a ne jmenovaný-reproduktor přiřazení výsledku.

DatasetStavDER
CALLHOME část 22 referenční reproduktory6.57%
CALLHOME část 23 referenční reproduktory10.05%
CALLHOME část 24 referenční reproduktory12.44%

Všechny řádky používají 1.04 's input- buffer latency, překrývání součástí, a 0.25 límec, a post- zpracování laděno na disjungle CALLHOME část 1. CALLDOME je licencován a není sdružen. diarization-bench uvádí srovnatelné výsledky samostatně podle počtu respondentů v konzoli a v JSON byReferenceSpeakerCount.

Pipeline Community-1

Community-1 běží obě neurální fáze s CoreML a veškeré zpracování hostitelů v Swift, takže se nenačítá MLX nebo požadovat Metal Knihovna shader. Zveřejněné vady jsou zachovány: tvrdé dekódování powerset, čisté jednoreproduktorové masky s předními zkratky, 0.6 prahová hodnota centroid- linkage, Fa=0.07, Fb=0.8, a nanejvýš 20 VBx iterace.

Na fixní 5ve- soubor VoxConverse verze podmnožina (1,057.49 sekund, 0.25-second obojek, překrývání součástí), výstup Swift obnoven s pyannote.metrics měřeno 4.66% DER / 21.43% JER; zveřejněný naměřený odkaz na CoreML 4.65% / 21.42%Toto je malá kontrola parity, ne celé prohlášení o kvalitě.

Se snímkem speech-swift na stejné podskupině, měřeno Community-1 9.31% DER / 16.20% JER, 25.5 × real-time, a 1.54 GB peak RSS. Výchozí měřený motor Pyannote 5.03% / 9.28%, 105.7 × reálný čas a 393 MB. Community-1 je proto volitelný plynovod pro zvýšení parity s hlasitými hranicemi a vrácenými centroidy, nikoliv univerzální přesnost nebo upgrade rychlosti. Výsledky obou bodovacích metod nejsou přímo srovnatelné.

Pipeline Pyannote

Výchozí potrubí probíhá ve dvou etapách:

Fáze 1: Segmentace + Řetězy reproduktorů

Pyannote segmentation-3.0 procesy 10- druhá posuvná okna s překrytím 50%. dekodér Powerset převádí výstup třídy 7- na per- reproduktory pravděpodobnosti (až na 3 lokální reproduktory na okno). Přilehlá okna sdílejí překrývání 5-second - identity reproduktoru se šíří přes okna výpočtem Pearsonova korelace mezi pravděpodobnostními trasami v překrývací zóně s chamtivým exkluzivním srovnáváním pro konzistentní globální ID reproduktorů.

Fáze 2: Post- hoc vkládání

Po diarizaci, WeSpeaker ResNet34-LM extrahuje a 256- dimenzionální těžiště vyzařování na reproduktor. Tyto vložení umožňují cílový reproduktor extrakce (--target-speaker), ale neřiďte řečník zadání sám.

Migrace z pyannote.audio

Pokud přicházíte z Python pyannote.audio knihovna - nahrazení Pipeline podtřída, která se nastavuje pipeline.segmentation = ..., nebo se odstěhovat od hostingu serveru pyannote/speaker-diarization-3.1 - Soniqo obchází stejný model Pyannote-Segmentation-3.0 a běží zcela on- zařízení na Apple Silicon. No Python runtime, no CUDA, no Hugging Face token at 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 = ... (vlastní podtřída) Opraveno: Pyannote-Segmentation-3.0 (MLX nebo CoreML, automaticky vybrané)
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

Váhy Pyannote-Segmentation-3.0 se převádějí z předního kontrolního bodu HuggingFace, takže segradační logity jsou číselně rovnocenné v rámci tolerance přesnosti float-. Post- segmentace řetězy (Pearsonova korelace přes překrývající se okna + chamtivé exkluzivní shodování) a post- hoc fáze vkládání WeSpeaker jsou reimplementovány v Swift ale produkují srovnatelný RTTM výstup na referenční potrubí Python.

Dosud podporované

Není tu žádný proud. OnlineSpeakerDiarization ekvivalentní pro motor Pyannote. K použití v reálném čase --engine sortformer místo toho, který běží Sortformer model s FIFO a mluvčí stavových bufferů.

Použití 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

Extrakce cílového reproduktoru

Poskytněte audio zápisu známého reproduktoru, který bude extrahovat pouze jejich segmenty z záznamu. Plynovod počítá zapsání reproduktoru do záznamu a najde cluster s nejvyšší kosinovou podobností.

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

DER Scoring

Hodnotit kvalitu digitalizace bodováním proti referenčnímu RTTM souboru. Plynovod počítá Diarizační chybovost rate (DER), který měří podíl času, který je nesprávně přiřazen.

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

RTTM výstup

V --rttm flag produkuje Rich Transcription Time Marked výstup, standardní formát používaný pro hodnocení diarizace. Každý řádek následuje formát:

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

Možnosti

MožnostPopis
--target-speakerZapisovací zvuk pro extrakci cílového reproduktoru (pouze pyannote)
--embedding-engineReproduktor vkládací motor: mlx nebo coreml (pouze pyannote)
--vad-filterPre- filtr se Silero VAD (pouze pyannote)
--community1-compute-unitsane (přednastaveno), cpu, gpunebo all
--num-speakersPřesný počet reproduktorů (pouze Community-1)
--min-speakersMinimální počet reproduktorů (Community-1, výchozí 1)
--max-speakersMaximální počet reproduktorů (Community-1)
--rttmVýstup ve formátu RTTM
--jsonVýstupní formát JSON
--score-againstReferenční soubor RTTM pro hodnocení DER
Důležité

Diarizace funguje nejlépe s nahrávkami, které mají jasné otáčky reproduktoru. Vysoce překrývající se řeč může snížit přesnost. Počet reproduktorů se určuje automaticky.

Stáhnout model

Modely se stahují automaticky při prvním použití:

SoučástVzorVelikostHuggingFace
SegmentacePyannote-Segmentation-3.0~ 5,7 MBaufklarer / Pyannote- Segmentation- MLX
Reproduktor EmbeddingWeSpeaker-ResNet34-LM (MLX)~ 25 MBaufklarer / WeSpeaker-ResNet34-LM-MLX
Reproduktor EmbeddingWeSpeaker-ResNet34-LM (CoreML)~ 25 MBaufklarer / WeSpeaker-ResNet34-LM-CoreML
Plynovod Community-1PyanNet + maskovaný WeSpeaker + PLDA / VBx~ 32 MBaufklarer / Pyannote-Community-1-CoreML
SortformerDiarizace Sortformer (CoreML)~ 240 MBaufklarer / Sortformer- Diarization- CoreML
Nemotron 3Diarizace INT8 (CoreML nebo MLX)~ 100 MB každýCoreML · 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)
)