Реалізація діаризації мовців (Speaker Diarization) під ключ
Уявіть: запис наради триває годину, у ній п'ять учасників, але після транскрибації отримуєте суцільний текст без атрибуції. Хто сказав бюджет? Хто запропонував терміни? Без діаризації розшифровка марна. Ми вирішуємо це завдання — розділяємо аудіодоріжку на сегменти за мовцями з точністю до 90–95%.
Діаризація мовців (speaker diarization) — це pipeline, що складається з детекції голосової активності (VAD), сегментації, вилучення ембеддингів і кластеризації. Сучасні нейромережеві підходи на базі speaker diarization та pyannote.audio 3.x дозволяють досягти DER 5–12% на чистих записах. Розберемо, як ми реалізуємо діаризацію під ключ, які проблеми виникають на реальних даних і як їх вирішуємо.
Чому проста кластеризація не працює?
Класичні методи (k-means, агломеративна кластеризація) дають DER 25–40% на реальних записах через перекриття мовлення, фоновий шум і різну гучність учасників. Нейромережеві ембеддинги, навчені на задачі розпізнавання мовців (наприклад, ECAPA-TDNN), дозволяють отримати компактне представлення голосу. Саме тому ми використовуємо готові моделі на кшталт pyannote/speaker-diarization-3.1, які вже передтреновані на тисячах годин. Pyannote 3.1 у 2 рази точніший за агломеративну кластеризацію на стандартних бенчмарках.
Сучасний стек
pyannote.audio 3.x — state-of-the-art open-source рішення з DER (Diarization Error Rate) 7–12% на стандартних датасетах:
from pyannote.audio import Pipeline
import torch
pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token="HF_TOKEN"
)
pipeline.to(torch.device("cuda"))
diarization = pipeline(
"meeting.wav",
min_speakers=2,
max_speakers=6
)
for segment, track, speaker in diarization.itertracks(yield_label=True):
print(f"[{segment.start:.2f}s → {segment.end:.2f}s] {speaker}")
Model card for pyannote/speaker-diarization-3.1 reports DER 5-12% on AMI and DIHARD datasets
Деталі налаштування VAD
Для детекції голосової активності ми використовуємо передтреновану модель VAD на основі MarbleNet. Пороги активації підбираються індивідуально: занадто низький поріг призводить до хибних спрацьовувань на шумі, занадто високий — до втрати тихих реплік. Оптимальне значення SNR для вашого сценарію визначається на етапі аналізу.
Як об'єднати діаризацію з ASR?
Злиття з транскрипцією — ключовий етап. Використовуємо Whisper large-v3 для розпізнавання та зіставляємо сегменти за часовими мітками:
from faster_whisper import WhisperModel
def transcribe_with_diarization(audio_path: str) -> list[dict]:
# 1. Транскрибуємо
whisper = WhisperModel("large-v3", device="cuda")
segments, _ = whisper.transcribe(audio_path, word_timestamps=True)
# 2. Діаризуємо
diarization = pipeline(audio_path)
# 3. Зіставляємо за часовими мітками
result = []
for seg in segments:
seg_midpoint = (seg.start + seg.end) / 2
speaker = "UNKNOWN"
for turn, _, spk in diarization.itertracks(yield_label=True):
if turn.start <= seg_midpoint <= turn.end:
speaker = spk
break
result.append({
"speaker": speaker,
"start": seg.start,
"end": seg.end,
"text": seg.text
})
return result
На практиці точність зіставлення залежить від синхронізації: розсинхрон навіть у 100 мс призводить до помилок атрибуції. Ми вирішуємо це калібруванням VAD та інтерполяцією.
Які проблеми вирішуємо в реальних проєктах?
- Перекриття мовлення: коли два спікери говорять одночасно — до 30% тривалості зустрічі. Використовуємо сегментацію з overlap-aware детекцією.
- Шум і різна якість мікрофонів: на зустрічах із віддаленими учасниками SNR падає до 5 дБ. Застосовуємо передобробку (Noise Suppression, VoiceFixer).
- Невідома кількість мовців: наша система автоматично визначає оптимальне число кластерів через Silhouette score.
- Довгі паузи: VAD склеює репліки одного мовця, розділені паузою до 2 секунд.
Якість за кількістю мовців
| Число мовців | DER (pyannote 3.1) |
|---|---|
| 2 | 5–8% |
| 4 | 8–12% |
| 6 | 12–18% |
| 8+ | 15–25% |
Порівняння з хмарними сервісами
| Параметр | pyannote + Whisper | AssemblyAI | Google STT |
|---|---|---|---|
| DER на російських даних | 8–14% | 11–17% | 13–19% |
| Контроль даних | Повний (on-prem) | Ні | Ні |
| Вартість за годину аудіо | Фіксована | За токенами | За хвилинами |
Порівняння з хмарними сервісами показує, що на російськомовних даних pyannote + Whisper дає DER на 3–5 п.п. нижче, ніж AssemblyAI чи Google STT, при повному контролі над даними. При переході на on-premise рішення ви економите до 40% бюджету на транскрибацію порівняно з хмарними сервісами.
Процес роботи
- Аналіз: приймаємо зразок аудіо (5–10 хвилин), оцінюємо якість, щільність мовлення, кількість мовців.
- Проєктування pipeline: обираємо модель (pyannote, ECAPA) та гіперпараметри під ваш сценарій (стенограми зустрічей, інтерв'ю, кол-центри).
- Реалізація: інтеграція з ASR-системою (Whisper, Vosk, хмарні API), зіставлення часових міток.
- Тестування: замір DER на вашому датасеті, ітеративне налаштування threshold та clustering.
- Деплой: on-premise або в хмарі, з моніторингом latency p99 < 2 сек на хвилину аудіо при batch-обробці.
Що входить в роботу
- Аналіз аудіозаписів та вибір оптимальної конфігурації
- Розробка та кастомізація pipeline під вашу предметну область
- Інтеграція з існуючою ASC/CRM через REST API або WebSocket
- Документація з налаштування та експлуатації
- Навчання вашої команди (2–3 години)
- Підтримка 2 тижні після деплою
Команда TrueTech має 5+ років досвіду в NLP та аудіоаналітиці, реалізовано 20+ проєктів із діаризації для клієнтів з finance, legal, media. Гарантуємо якість: приймання за DER не вище 15% на обумовленому датасеті. Скорочуємо витрати на транскрипцію до 30% за рахунок on-premise розгортання.
Терміни: інтеграція pyannote + Whisper — 3–5 днів. Оптимізація під конкретний тип запису — до 2 тижнів. Повний контроль над даними — ще одна перевага нашого підходу.
Зв'яжіться з нами для детального аудиту ваших аудіозаписів. Оцініть ваш проєкт — ми підберемо оптимальне рішення. Замовте інтеграцію під ключ — отримайте консультацію інженера.







