Phase 06: Speech & Audio

Reconnaissance et vérification des haut-parleurs

L'ASR demande "qu'ont-ils dit?" La reconnaissance du haut-parleur demande "qui l'a dit?" Les mathématiques sont les mêmes embeddings plus cosine mais chaque décision de production dépend d'un seul numéro EER.

Type: Build

Languages: Python

Prerequisites: Phase 6 · 02 (Spectrograms & Mel), Phase 5 · 22 (Embedding Models)

Time: ~45 minutes

Le problème

Un utilisateur dit un mot de passe. Vous voulez savoir: est-ce la personne qu'il prétend être ( vérification, 1:1), ou est-ce la première personne dans votre banque d'inscription ( identification, 1: N)?

Avant 2018: GMM-UBM + i-vecteurs. EER raisonnable mais fragile pour le changement de canal (phone contre ordinateur portable) et l'émotion. 20182022: x-vecteurs (réteau TDNN entraîné avec marge angulaire). 2022+: ECAPA-TDNN et WavLM-grandes emblèmes.

La métrique est EER Taux d'erreur égal. Définissez votre seuil de décision de sorte que le taux de faux acceptation = taux de faux rejet. Le crossover est EER. Utilisé dans chaque document, chaque tableau de classement, chaque appel d'achat.

Le concept

!Enrollment + verification pipeline with embedding + cosine + EER

The pipeline.Enregistrement: enregistrer 530 secondes de l'enceinte cible; calculer une intégration en dimension fixe (192-d pour ECAPA-TDNN, 256-d pour WavLM-large).

ECAPA-TDNN (2020, still dominant 2026).Accentué l'attention, la propagation et l'agrégation du canal - Réseau neuronal retardé dans le temps. Blocs de convection 1D avec excitation de compresser, pooling d'attention multi-têtes, suivis d'une couche linéaire à 192-d. Formé sur VoxCeleb 1+2 (2 700 haut-parleurs, 1,1M déclarations) avec perte de marge angulaire additive (AAM-softmax).

WavLM-SV (2022+).Télécharger une mémoire de base SSL de taille WavLM pré-entrainée avec perte AAM.

x-vector (baseline).La mise en commun des statistiques TDNN +. classique; toujours utile sur le bord du processeur.

AAM-softmax.Softmax standard avec marge ajoutée mdans l'espace angulaire: cos(θ + m)Pour la classe correcte, la séparation angulaire entre les classes.m=0.2, l' échelle s=30- Je suis désolé .

Score

  • CosineLes résultats de l'enquête ont été évalués en fonction des résultats obtenus.
  • PLDA (Probabilistic LDA).Embedding de projet dans un espace latent où le même haut-parleur vs un haut-parleur différent a un rapport de probabilité de forme fermée. Ajouté en haut du cosine pour une réduction de +1020% de la REE.
  • Score normalization. S-normou AS-normLes résultats obtenus par les chercheurs sont essentiels pour une évaluation interdomaine.

Numéros que vous devriez connaître (2026)

ModelVoxCeleb1-O EERParamsThroughput (A100)
x-vector (classic)3.10%5 M400× RT
ECAPA-TDNN0.87%15 M200× RT
WavLM-SV large0.42%316 M20× RT
Pyannote 3.1 segmentation + embedding0.65%6 M100× RT
ReDimNet (2024)0.39%24 M100× RT

Diarrhée

" Qui a parlé quand " dans un clip multi- haut-parleurs. Pipeline: VAD → segment → intégrer chaque segment → cluster (agglomératif ou spectrale) → limites lisses.pyannote.audio3.1, qui regroupe la segmentation des haut-parleurs + l'intégration + le regroupement derrière un appel.

Faites-le

Étape 1: intégration de jouets à partir des statistiques de la CFPM

pythondef embed_mfcc_stats(signal, sr):
    frames = featurize_mfcc(signal, sr, n_mfcc=13)
    mean = [sum(f[i] for f in frames) / len(frames) for i in range(13)]
    std = [
        math.sqrt(sum((f[i] - mean[i]) ** 2 for f in frames) / len(frames))
        for i in range(13)
    ]
    return mean + std  # 26-d

Pas de SOTA par un mile pour l'enseignement seulement. code/main.pyutilise cette méthode comme preuve de concept sur les données des haut-parleurs synthétiques.

Étape 2: similitude cosine + seuil

pythondef cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    na = math.sqrt(sum(x * x for x in a))
    nb = math.sqrt(sum(x * x for x in b))
    return dot / (na * nb) if na and nb else 0.0

def verify(enroll, test, threshold=0.75):
    return cosine(enroll, test) >= threshold

Étape 3: EER à partir de paires de similitudes

pythondef eer(same_scores, diff_scores):
    thresholds = sorted(set(same_scores + diff_scores))
    best = (1.0, 1.0, 0.0)  # (fa, fr, threshold)
    for t in thresholds:
        fr = sum(1 for s in same_scores if s < t) / len(same_scores)
        fa = sum(1 for s in diff_scores if s >= t) / len(diff_scores)
        if abs(fa - fr) < abs(best[0] - best[1]):
            best = (fa, fr, t)
    return (best[0] + best[1]) / 2, best[2]

Retour (eer, threshold_at_eer).

Étape 4: production avec SpeechBrain

pythonfrom speechbrain.pretrained import EncoderClassifier

clf = EncoderClassifier.from_hparams(source="speechbrain/spkrec-ecapa-voxceleb")

# enroll: average the embeddings of 3-5 clean samples
enroll = torch.stack([clf.encode_batch(load(x)) for x in enrollment_clips]).mean(0)
# verify
score = clf.similarity(enroll, clf.encode_batch(load("test.wav"))).item()
verdict = score > 0.25   # ECAPA typical threshold; tune on your data

Étape 5: Diary avec note de piane

pythonfrom pyannote.audio import Pipeline

pipe = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1")
diarization = pipe("meeting.wav", num_speakers=None)
for turn, _, speaker in diarization.itertracks(yield_label=True):
    print(f"{turn.start:.1f}–{turn.end:.1f}  {speaker}")

Utilisez-le

La pile de 2026:

SituationPick
Closed-set 1:1 verification, edgeECAPA-TDNN + cosine threshold
Open-set verification, cloudWavLM-SV + AS-norm
Diarization (meetings, podcasts)pyannote/speaker-diarization-3.1
Anti-spoofing (replay / deepfake detection)AASIST or RawNet2
Tiny embedded (KWS + enrollment)Titanet-Small (NeMo)

Les pièges

  • Channel mismatch.Modèle formé sur VoxCeleb (vidéo web) ≠ audio d'appel téléphonique.
  • Short utterances.L'EER se dégrade nettement en dessous de 3 secondes d'audio de test.
  • Enrollment with noise.Une inscription bruyante empoisonne l'ancre.
  • Fixed threshold across conditions.Toujours régler le seuil sur un ensemble de développement détenu depuis le domaine cible.
  • Cosine on non-normalized embeddings.L2 normaliser d'abord; sinon la magnitude domine.

La faire partir

  • Je ne sais pas .outputs/skill-speaker-verifier.md- Le modèle de sélection, le protocole d'inscription, le plan de réglage des seuils et les garanties contre la fraude.

Exercices

  1. Easy.On court .code/main.py- Construit des " haut-parleurs " synthétiques (profiles de tonalité différents), inscrit, calcula EER sur une liste d'essai de 100 paires.
  2. Medium.Utilisez SpeechBrain ECAPA sur 30 déclarations VoxCeleb1 (5 haut-parleurs × 6 chacun).
  3. Hard.Construire l' inscription complète → diary → vérifier le pipeline avec pyannote.audio- Évaluer le DER sur le set de développement AMI.

Les termes clés

TermWhat people sayWhat it actually means
EERThe headline metricThreshold where False Accept = False Reject.
Verification1:1"Is this Alice?"
Identification1:N"Who is speaking?"
Open-setUnknown possibleTest set can contain unenrolled speakers.
EnrollmentRegisteringComputing a speaker's reference embedding.
AAM-softmaxThe lossSoftmax with additive angular margin; forces cluster separation.
PLDAClassic scoringProbabilistic LDA; likelihood-ratio scoring on top of embeddings.
DERDiarization metricDiarization Error Rate — miss + false alarm + confusion.

Pour en savoir plus

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.