Распознавание говорящего и диаризация

Учим систему отвечать на вопросы «чей это голос» и «кто когда говорил».

Эмбеддинг говорящего — компактный вектор, кодирующий уникальные особенности голоса человека; близкие векторы означают похожие голоса.

Голос так же уникален, как отпечаток пальца: его задают анатомия речевого тракта и манера речи. Аудио-AI умеет использовать это, чтобы узнавать людей по голосу и разбирать, кто что сказал в разговоре. Это отдельное семейство задач, не связанное с тем, что сказано.

Эмбеддинги: голос как вектор

Нейросеть обучают так, чтобы для каждого голоса она выдавала вектор (например, 192 числа), причём у одного человека векторы близки, а у разных — далеки. Такой вектор называют x-vector или d-vector. Сравнение голосов сводится к измерению расстояния между векторами.

Верификация и идентификация

Это две разные задачи, которые легко спутать.

ЗадачаВопросПример
Верификацияэто точно тот, кем представился?вход по голосу 1:1
Идентификациякто из известных это говорит?поиск 1:N
Диаризациякто и когда говорил?разметка диалога

Диаризация: «кто когда»

Диаризация не знает имён — она лишь различает голоса и размечает запись: «спикер A: 0–5 с, спикер B: 5–9 с...». Алгоритм нарезает речь на сегменты, считает эмбеддинг каждого и кластеризует похожие в «спикеров». Вместе с ASR это даёт протокол совещания с репликами по говорящим.

запись:  [A....][B..][A...][C....][B..]
            |
            v кластеризация эмбеддингов
спикеры: A = {сегм1, сегм3}
         B = {сегм2, сегм5}
         C = {сегм4}

Сравнение голосов кодом

Покажем суть: голоса как векторы, близость — косинусное сходство. Совпадение голоса — высокое сходство.

import math

def 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(y * y for y in b))
    return round(dot / (na * nb), 3)

anna = [0.9, 0.1, 0.4]
anna2 = [0.85, 0.15, 0.42]   # та же Анна, другая фраза
boris = [0.1, 0.9, 0.2]

print("Анна vs Анна:", cosine(anna, anna2))
print("Анна vs Борис:", cosine(anna, boris))
print("Один человек:", cosine(anna, anna2) > 0.9)

Вывод:

Анна vs Анна: 0.998
Анна vs Борис: 0.283
Один человек: True

Векторы одного голоса почти совпали (0.997), разных — далеки (0.358). По порогу сходства система решает, тот же это человек или нет.

Разделение источников

Сложный случай — когда говорят одновременно (наложение голосов). Здесь нужна сепарация источников: модели вроде Conv-TasNet разделяют смешанный звук на отдельные дорожки голосов. Это решает «коктейльную проблему» — то, что человек делает легко, а машина — с трудом.

Главная практическая магия эмбеддингов говорящего — в том, что обученная сеть работает для людей, которых она никогда не видела при обучении. Её учили не «узнавать Анну или Бориса», а более общему навыку: располагать записи одного человека рядом в пространстве векторов, а разных — далеко друг от друга. Поэтому добавить нового сотрудника в голосовую биометрию можно за секунды — достаточно один раз посчитать его эмбеддинг и сохранить, без всякого переобучения модели. Это та же идея, что у систем распознавания лиц, и именно она делает голосовую верификацию пригодной для реальных продуктов.

Классический случай, где интуиция подсказывает неверное, — «коктейльная вечеринка». Человек в шумном зале без труда выхватывает голос собеседника из десятка одновременных разговоров, а для машины наложенная речь долго оставалась почти неразрешимой задачей. Обычная диаризация тут пасует: она хорошо размечает, кто говорит по очереди, но на перекрывающихся репликах путается. Поэтому в сложных сценах сначала запускают сепарацию источников (модели вроде Conv-TasNet), которая расщепляет смешанный звук на отдельные дорожки голосов, и лишь затем размечают каждую. Это наглядное напоминание, что лёгкое для уха бывает крайне тяжёлым для алгоритма.

Важно держать в голове, что распознавание говорящего отвечает на вопрос «кто говорит», а вовсе не «что сказано» — это ортогональная к ASR задача. Можно точно знать, что в записи звучит голос Анны, не разобрав ни единого слова, и наоборот — идеально расшифровать реплику, не зная её автора. В реальных конвейерах эти задачи соединяют: диаризация режет запись на сегменты по говорящим, а ASR расшифровывает содержание каждого, и только их союз превращает сырой диалог в аккуратный протокол с подписанными репликами «Спикер 1», «Спикер 2».

Как работает под капотом

Сеть для эмбеддингов обучают так, чтобы записи одного человека притягивались, а разных — отталкивались (контрастные/triplet-функции потерь). После обучения эмбеддинги работают даже для людей, которых не было в обучении — нужно лишь сравнить векторы. Поэтому голосовую биометрию можно добавлять новым пользователям без переобучения модели.

Частые ошибки

  • Путать верификацию (1:1) и идентификацию (1:N). Это разные задачи с разными метриками.
  • Полагаться на голос как на надёжную биометрию. Голос подделывают клонированием — нужна защита от спуфинга.
  • Ждать идеальной диаризации на наложении. Одновременная речь требует ещё и сепарации источников.

Итоги

  • Голос кодируют эмбеддингом; сравнение голосов = расстояние между векторами.
  • Верификация — «тот ли это человек» (1:1), идентификация — «кто из многих» (1:N).
  • Диаризация размечает «кто когда говорил» через кластеризацию эмбеддингов.
  • Наложение голосов решается разделением источников («коктейльная проблема»).
Проверьте себя
1. Что такое эмбеддинг говорящего?
AТекст реплики
BВектор, кодирующий особенности голоса; у одного человека векторы близки
CГромкость записи
DЧастота сэмплирования
2. Чем диаризация отличается от идентификации?
AНичем
BДиаризация размечает «кто когда» без имён, идентификация ищет конкретного человека среди известных
CДиаризация синтезирует речь
DИдентификация работает только с музыкой
3. Что нужно, когда несколько человек говорят одновременно?
AТолько громче записать
BРазделение источников (сепарация) — «коктейльная проблема»
CПеревести на английский
DНичего, диаризация справится сама