Блог AST-SoftPro
ASR с разделением спикеров на русском: как реализовать и какие модели выбрать
Введение
Распознавание речи (ASR) давно перестало быть «просто расшифровкой»: в 2026 году бизнес-задачи всё чаще требуют понимать, кто сказал. Запись совещания, интервью с двумя гостями, телефонный звонок поддержки — во всех этих случаях одного текста недостаточно. Нужен протокол вида «Спикер 1: … / Спикер 2: …», причём на русском языке.
Эта задача называется speaker diarization (разделение спикеров) и решается отдельным классом моделей, которые комбинируются с ASR-моделью. В статье разберём: как устроена связка «ASR + diarization», какие модели работают с русским языком, как собрать пайплайн на WhisperX или NeMo, где подводные камни и что выбрать под конкретную задачу.
💡 Практическая выгода: автоматический протокол совещаний экономит часы ручного конспекта. Для служб поддержки — это готовая атрибуция реплик оператора и клиента для анализа качества разговора (QA). Для медиа — черновой сценарий интервью без ручной разметки тайм-кодов.
Как устроено: два отдельных этапа
Важно сразу понять архитектуру: одна модель почти никогда не делает обе вещи хорошо. ASR отвечает на вопрос «что сказано», diarization — «кто и когда говорил». Связка из двух этапов даёт лучший результат, потому что каждая модель обучена на своей задаче.
Типовой пайплайн выглядит так:
-
VAD (Voice Activity Detection) — находит участки с речью, отбрасывает тишину и музыку.
-
Diarization — внутри участков речи определяет границы реплик и группирует их по спикерам (SPEAKER_00, SPEAKER_01…). На этом этапе нет текста — только временные интервалы с метками «кто».
-
ASR — расшифровывает речь в текст с тайм-кодами на уровне слов или сегментов.
-
Слияние (alignment) — по пересечению временных интервалов каждому слову/сегменту текста приписывается метка спикера.
аудио → VAD → diarization (интервалы + spk) ─┐
└→ ASR (текст + тайм-коды) ───────────┴→ слияние по времени → «Спикер 1: текст»
⚠️ Типичная ошибка: запускать diarization и ASR на разных срезах аудио без синхронизации тайм-кодов. Если VAD обрезает хвосты реплик в одном пайплайне, но не в другом, метки спикеров «съедут» относительно текста. Используйте один источник тайм-кодов (обычно — ASR с word-level timestamps).
Метрика качества: DER
Качество diarization измеряется DER (Diarization Error Rate) — суммой трёх ошибок: пропущенной речи (missed), ложно обнаруженной (false alarm) и перепутанных спикеров (confusion). Для справки ориентиры по бенчмаркам:
| Модель / пайплайн | DER на AMI | DER на DIHARD-III | Примечание |
|---|---|---|---|
| pyannote 3.1 (legacy) | ~18,8% | ~27% | стандарт open-source, 2023–2026 |
| pyannote community-1 (v4.0) | ~17,0% | — | новый открытый пресет, 2025 |
| NVIDIA Sortformer 4spk-v1 | не публиковалось для AMI в одном источнике | DIHARD3-Eval 16,28% (14,76% с доп. постобработкой) | оптимизирован под ≤4 спикеров |
💡 Важно про цифры: DER на бенчмарках — это «лабораторные» условия. На реальных записях (эхо, фоновый шум, многоголосие) ошибка вырастает в 1,5–2 раза. Перед внедрением обязательно прогоните 3–5 своих файлов и оцените качество руками.
Модели diarization: что поддерживает русский
Pyannote — де-факто стандарт
pyannote.audio (модель speaker-diarization-3.1, лицензия MIT, релиз ноября 2023) остаётся самым распространённым open-source решением для diarization в 2026 году. Ключевые факты:
-
Языковая независимость: модель обучена на аудио без привязки к языку — она работает по голосовым характеристикам, а не по словам. Русский поддерживается «из коробки», без дообучения.
-
Пайплайн из трёх стадий: VAD → сегментация (
segmentation-3.0) → эмбеддинги спикеров + кластеризация. -
Требования: для загрузки весов нужен токен Hugging Face и принятие лицензии модели (даже при MIT — это механизм распространения данных).
-
Ограничения: точность деградирует при >6–8 одновременно говорящих; на «чужих» доменах (много шума, телефонная линия) DER заметно растёт.
В 2025 году pyannote выпустила v4.0 с открытым пресетом community-1, который показывает немного лучшие цифры на AMI/AliMeeting, чем legacy 3.1. Если начинаете проект с нуля — берите свежий пресет; если воспроизводите чужую статью по 3.1 — не путайте версии.
NVIDIA NeMo Sortformer — для до четырёх спикеров
Sortformer (diar_sortformer_4spk-v1 и стриминговый diar_streaming_sortformer_4spk-v2.1) — end-to-end трансформер от NVIDIA, оптимизированный под сценарии до 4 спикеров. Это важно: если у вас интервью «ведущий + гость» или звонок поддержки «оператор + клиент», Sortformer попадает в свою зону оптимальности и показывает DER ниже, чем pyannote на аналогичных данных (DIHARD3-Eval: 16,28% против ~27% у legacy pyannote).
Особенности:
-
Языко-независимый — русский поддерживается.
-
Есть стриминговый вариант для онлайн-разметки в реальном времени (релиз августа 2025) — актуально для живых совещаний и звонков.
-
Требует больше VRAM, чем pyannote; при >4 спикерах качество падает, поэтому не универсален.
Что ещё встречается в связках с Whisper
-
WhisperX — обёртка над faster-whisper + pyannote (см. ниже). Самый популярный «всё-в-одном» вариант для self-hosted.
-
FunASR / SenseVoice — семейство от Alibaba (FunAudioLLM). SenseVoiceSmall поддерживает китайский, кантонский, английский, японский и корейский — русского в списке нет, поэтому для русскоязычных задач его брать не стоит (хотя сам FunASR как toolkit содержит VAD и diarization-модули на базе CAM++/3D-Speaker).
-
Сторонние API (AssemblyAI, Deepgram, Speechmatics) — поддерживают русский ASR и diarization «из коробки», без GPU. AssemblyAI расширил поддержку diarization до 16 языков; при выборе API проверяйте именно наличие русского в списке, а не только общий список функций.
⚠️ Не путайте «многоязычная ASR» с «диаризация на русском». Whisper поддерживает русский как язык распознавания, но сам по себе не делает diarization — для этого нужен отдельный модуль (pyannote/Sortformer). Это частая причина, почему «просто Whisper» не выдаёт метки спикеров.
ASR-модели для русского языка
Whisper large-v3 и его варианты
Whisper large-v3 (OpenAI, MIT, 1,55 млрд параметров) — базовый open-source ASR для мультиязычных задач. По русскому:
-
На Common Voice русский WER порядка 6–10% в зависимости от источника; специализированные дообученные версии (например,
whisper-large-v3-russian) снижают его относительно base large-v3 примерно на треть. -
Чистая речь даёт лучшие цифры, нольный/шумный — заметно хуже. Всегда бенчмарьте на своих данных.
Практические варианты:
| Вариант | Скорость | Точность (русский) | Когда брать |
|---|---|---|---|
whisper-large-v3 (faster-whisper, CTranslate2) |
~4–8× быстрее реального времени на GPU | базовая, WER ~6–10% | универсальный выбор для offline-расшифровки |
distil-large-v3 |
~6× быстрее large-v3 (на английском −1% WER) | только английский — русский не поддерживается | не подходит для русской речи |
| faster-whisper (CTranslate2, fp16) | самый быстрый путь на NVIDIA GPU | та же модель, другое исполнение | продакшен-серверы с GPU |
💡 Для русского языка distil-large-v3 не вариант — он обучен только на английском. Не экономьте время, пытаясь его использовать: просто возьмите
large-v3через faster-whisper.
WhisperX — связка «ASR + word-level тайм-коды + diarization»
WhisperX (pip install whisperx) — самый простой способ получить расшифровку с метками спикеров одним вызовом. Под капотом: faster-whisper для ASR, wav2vec2 forced alignment для точных word-level тайм-кодов и pyannote для diarization.
import torch
import whisperx
device = "cuda" if torch.cuda.is_available() else "cpu"
compute_type = "float16" if device == "cuda" else "int8"
# 1) ASR с word-level тайм-кодами
model = whisperx.load_model("large-v3", device, compute_type=compute_type)
audio = whisperx.load_audio("meeting_ru.wav")
result = model.transcribe(audio, batch_size=16, language="ru")
# 2) Forced alignment — точные тайм-коды слов
align_model, align_meta = whisperx.load_align_model(
language_code="ru", device=device
)
result = whisperx.align(result["segments"], align_model, align_meta, audio, device)
# 3) Diarization (нужен HF-токен и принятая лицензия pyannote)
diarize_model = whisperx.DiarizePipeline(use_auth_token=HF_TOKEN, device=device)
diarization = diarize_model(audio)
# 4) Слияние: каждому слову — метка спикера
whisperx.assign_word_speakers(result, diarization)
for seg in result["segments"]:
for word in seg["words"]:
print(f"[{word['speaker']}] {word['word']}")
Что делает этот код: загружает large-v3, расшифровывает с явным указанием языка ru (это снижает галлюцинации Whisper на неанглийских языках), выравнивает слова по времени и приписывает спикеров. Для продакшена добавьте обработку исключений (ошибки загрузки модели, пустые сегменты) и кэшируйте загрузку моделей между запросами — они тяжёлые.
⚠️ Язык явно задавайте. Если не передать
language="ru", Whisper сам детектирует язык, но на коротких или шумных фрагментах может ошибиться и «галлюцинировать» текст. Явное указание языка — дешёвая страховка.
Что выбрать: self-hosted vs API
| Критерий | Self-hosted (WhisperX / NeMo) | Облачный API |
|---|---|---|
| GPU | нужен (для скорости) | не нужен |
| Данные остаются у вас | да | нет — аудио уходит в облако |
| Стоимость на объёме | фиксированная (амортизация GPU) | pay-per-minute, растёт линейно |
| Скорость внедрения | дни–недели (инфраструктура) | часы (API-ключ) |
| Тонкая настройка (домен, словарь) | полная | ограничена параметрами API |
Для служб с чувствительными данными (медицина, юриспруденция, госсектор) self-hosted часто обязателен по требованиям к хранению данных. Для старта и прототипа — API быстрее.
Практические рекомендации
Подбор под сценарий
-
Звонок поддержки (2 спикера): Sortformer 4spk или pyannote + WhisperX. Оба хороши; Sortformer точнее именно в зоне ≤4.
-
Совещание 3–6 человек: pyannote community-1 / 3.1 — универсальнее по числу спикеров.
-
Живой поток (стриминг):
diar_streaming_sortformer_4spk-v2.1— единственный зрелый open-source вариант онлайн-diarization с приличным DER. -
Максимальная точность на офлайн-записях: pyannote 3.1 + large-v3 через faster-whisper (fp16) + word-level alignment.
Частые проблемы и как их решать
| Проблема | Причина | Решение |
|---|---|---|
| Спикеры «слипаются» в одного | похожие голоса / мало реплик у спикера | увеличить число кластеров, добавить дообучение на эталонных образцах голосов (speaker embedding) |
| Текст смещён относительно меток | разные VAD-срезы в ASR и diarization | один источник тайм-кодов; alignment через WhisperX |
| Галлюцинации текста на русском | автодетект языка ошибся | явный language="ru" |
| Медленно на CPU | large-v3 тяжёлый | faster-whisper + GPU (fp16) или int8 на CPU для прототипа |
| DER растёт в реальном мире | шум, эхо, многоголосие | предобработка (шумоподавление), доменная адаптация модели |
⚠️ Риск «вайб-кодинга» здесь реальный. Скрипт из 20 строк работает на одной чистой записи. В продакшене появятся: фоновый шум, пересечения реплик (barge-in), тишина посреди слова, разные уровни громкости между спикерами. Без обработки этих edge-кейсов и мониторинга качества DER будет «плыть», а вы заметите это только когда клиент скажет «протокол кривой». Для критичных задач — привлекайте специалистов по аудио-ML: проектирование пайплайна, доменная адаптация и оценка качества на ваших данных требуют опыта.
Оценка качества перед запуском
Не запускайте пайплайн в продакшен без замеров:
-
Возьмите 5–10 реальных записей из вашей доменной области (не бенчмарки).
-
Прогоните и оцените DER вручную (или через
pyannote.metrics/ NeMo-скриптe2e_diarize_speech.py). -
Проверьте WER на русском по вашим данным — не по Common Voice.
-
Зафиксируйте цифры как baseline, чтобы видеть деградацию после изменений.
Заключение
Разделение спикеров для русского языка в 2026 году — зрелая задача с готовыми open-source решениями:
-
Diarization: pyannote (универсально, MIT) или NVIDIA Sortformer (точнее при ≤4 спикерах, есть стриминг).
-
ASR на русском: Whisper large-v3 через faster-whisper; distil-large-v3 не подходит (только английский).
-
Самый быстрый старт: WhisperX — один вызов даёт текст + word-level тайм-коды + метки спикеров.
Главное правило: бенчмарк на своих данных, а не на чужих таблицах DER/WER. И помните: выбор модели — половина задачи. Вторая половина — корректная реализация пайплайна с обработкой реальных edge-кейсов (шум, пересечения реплик), что требует системного подхода и опыта в аудио-ML.
Источники
-
WhisperX — автоматическое распознавание речи с word-level тайм-кодами и diarization (GitHub): https://github.com/m-bain/whisperx
-
pyannote/speaker-diarization-3.1 — бенчмарки DER (Hugging Face): https://huggingface.co/pyannote/speaker-diarization-3.1
-
pyannote.audio — репозиторий (GitHub): https://github.com/pyannote/pyannote-audio
-
Community-1: open-source diarization от pyannote: https://www.pyannote.ai/blog/community-1
-
nvidia/diar_sortformer_4spk-v1 — DER на DIHARD3-Eval (Hugging Face): https://huggingface.co/nvidia/diar_sortformer_4spk-v1
-
Streaming Sortformer: стриминговая diarization от NVIDIA (MarkTechPost): https://www.marktechpost.com/2025/08/21/nvidia-ai-just-released-streaming-sortformer-a-real-time-speaker-diarization-that-figures-out-whos-talking-in-meetings-and-calls-instantly
-
openai/whisper-large-v3 (Hugging Face): https://huggingface.co/openai/whisper-large-v3
-
Сравнение вариантов: faster-whisper, insanely-whisper, WhisperX (Modal): https://modal.com/blog/choosing-whisper-variants
-
Бенчмарки точности и скорости локальных моделей Whisper V3: https://www.saytowords.com/blogs/Whisper-V3-Benchmarks
-
FunAudioLLM/SenseVoiceSmall — Hugging Face (поддерживаемые языки)