Diarizacao de falantes

Identifique quem falou quando em uma gravacao multi-locutor. Dois engines de diarizacao estao disponiveis: um pipeline de duas etapas Pyannote (segmentacao + encadeamento de locutores baseado em atividade, depois embedding post-hoc) e um modelo ponta-a-ponta Sortformer (CoreML, Neural Engine).

Engines

Selecione o engine com --engine pyannote (padrao) ou --engine sortformer.

Pyannote (padrao)

Pipeline de duas etapas: a segmentacao Pyannote processa janelas sobrepostas com encadeamento de locutores baseado em atividade (correlacao de Pearson nas zonas de sobreposicao) para atribuir rotulos globais de locutor. A extracao post-hoc de embedding WeSpeaker permite identificacao de locutor alvo via audio de enrolamento.

Sortformer (CoreML)

Modelo neural ponta-a-ponta de diarizacao da NVIDIA. Preve diretamente a atividade por frame de ate 4 falantes sem estagios separados de embedding ou clustering. Roda no Neural Engine via CoreML com buffers de estado de streaming (FIFO + speaker cache).

Nota

Sortformer nao produz embeddings de falante. As flags --target-speaker e --embedding-engine estao disponiveis apenas com o engine Pyannote.

Pipeline Pyannote

O pipeline padrao roda em duas etapas:

Etapa 1: Segmentacao + Encadeamento de falantes

Pyannote segmentation-3.0 processa janelas deslizantes de 10 segundos com sobreposicao de 50%. Um powerset decoder converte a saida de 7 classes em probabilidades por falante (ate 3 falantes locais por janela). Janelas adjacentes compartilham uma sobreposicao de 5 segundos — a identidade do falante e propagada entre janelas computando correlacao de Pearson entre as trilhas de probabilidade na zona de sobreposicao, com matching exclusivo greedy para IDs de falante globais consistentes.

Etapa 2: Embedding post-hoc

Apos a diarizacao, o WeSpeaker ResNet34-LM extrai um embedding centroide de 256 dimensoes por falante. Esses embeddings permitem extracao de falante alvo (--target-speaker) mas nao guiam a atribuicao de falante em si.

Uso do CLI

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

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

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

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

Extracao de falante alvo

Forneca audio de enrolamento de um locutor conhecido para extrair apenas seus segmentos de uma gravacao. O pipeline computa o embedding de falante do audio de enrolamento e encontra o cluster com a maior similaridade de cosseno.

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

Pontuacao DER

Avalie a qualidade da diarizacao pontuando contra um arquivo RTTM de referencia. O pipeline calcula a Diarization Error Rate (DER), que mede a proporcao de tempo atribuido incorretamente.

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

Saida RTTM

A flag --rttm produz saida Rich Transcription Time Marked, um formato padrao usado para avaliacao de diarizacao. Cada linha segue o formato:

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

Opcoes

OpcaoDescricao
--target-speakerAudio de enrolamento para extracao de falante alvo (somente pyannote)
--embedding-engineEngine de embedding de falante: mlx ou coreml (somente pyannote)
--vad-filterPre-filtrar com Silero VAD (somente pyannote)
--rttmSaida no formato RTTM
--jsonFormato de saida JSON
--score-againstArquivo RTTM de referencia para avaliacao DER
Importante

A diarizacao funciona melhor com gravacoes que tem turnos claros de falante. Fala altamente sobreposta pode reduzir a precisao. O numero de falantes e determinado automaticamente.

Downloads de modelos

Os modelos sao baixados automaticamente no primeiro uso:

ComponenteModeloTamanhoHuggingFace
SegmentacaoPyannote-Segmentation-3.0~5.7 MBaufklarer/Pyannote-Segmentation-MLX
Embedding de falanteWeSpeaker-ResNet34-LM (MLX)~25 MBaufklarer/WeSpeaker-ResNet34-LM-MLX
Embedding de falanteWeSpeaker-ResNet34-LM (CoreML)~25 MBaufklarer/WeSpeaker-ResNet34-LM-CoreML
SortformerSortformer Diarization (CoreML)~240 MBaufklarer/Sortformer-Diarization-CoreML

API Swift

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
)