The Jerusalem Post‘Hager (Land),’ an epic story of Ethiopian immigrants, wins Best Israeli Film at Haifa festESPNWeek 5 Power Rankings: Miami moves up, Missouri and Pitt join the top 25PunchTwo dead, one missing as floods hit Spain cityDaily MaverickSOCIAL (IN)SECURITY: A Cape Town mother buys bread on credit to stretch her children’s grants, then spends payday settling the debtRTP Desporto12h30 Henrique Calisto quer saída digna para Cristiano RonaldoSky TG24Istat, la pressione fiscale aumenta al 43,5%. Cala il potere d'acquisto delle famiglieZDF heuteAktuelle Pressemitteilungen des ZDFObservador DesportoAs notícias das 13hGlobal NewsU.S. Coast Guard suspends search for missing Ontario air ambulanceStraits Times SportFrom jiu-jitsu fighter Noah Lim a lovely lesson: Grace after gritABC NewsSouth Korea blames North Korean mines for border blast injuries and demands apologyسكاي نيوز عربيةمقاعد من الركام.. رحلة غزاوي لإعالة أسرته ومساعدة الطلاب
The Daily Newsstand · Free, Always
Monday, October 5, 2026

Почему одного Whisper оказалось мало: ASR на 100 песнях для домашней игры

Translate

К Новому году мы с друзьями договорились, что каждый подготовит по конкурсу. Мне хотелось сделать что‑нибудь музыкальное, а идеи нашлись в воспоминаниях о двух корпоративах: с одного я принёс желание сочинить песню для нашей компании, с другого позаимствовал механику конкурса. Так появилась What The Track, в которой нужно угадать последнее слово оборванной строки песни.

Первую версию с вопросами, нарезанными вручную, мы довольно быстро опробовали на друзьях. Когда захотелось сыграть ещё, я решил автоматизировать подготовку, чтобы самому не знать все ответы заранее. Оказалось, что между «нейросеть умеет распознавать речь» и «ей можно доверить музыкальный конкурс» помещается отдельный проект по сравнению систем автоматического распознавания речи (ASR, automatic speech recognition).

Сначала была песня

На новогоднем корпоративе диджей собрал фразы гостей и превратил их в песню. Мне такая активность понравилась настолько, что дома я полез разбираться, как сделать что‑нибудь похожее для друзей. Так я нашёл Suno, собрал у друзей по одной фразе и сделал собственный новогодний гимн с мощным припевом:

Мы вместе, мы живы! И на том спасибо!

Гимн у нас теперь был, но договорённость про конкурс никуда не делась. Тут я вспомнил другой корпоратив, летний, где ведущая включала с телефона треки из нижнего интернета, а нам предлагала выбрать, какой текст прозвучит дальше. Для такого конкурса необязательно знать песню: можно попытаться угадать продолжение по рифме, а можно придумать что‑нибудь смешное и потом сравнить с тем, что написал автор.

Эту механику я и решил забрать для нашей встречи, немного переделав под привычный нам формат. Мы с друзьями любим Jackbox, где все играют со своих телефонов, поэтому хотелось обойтись без возни с телефоном ведущего: пусть музыка звучит для всех, а каждый вводит ответ в собственном браузере. Я нарезал треки, подготовил вопросы, навайбкодил веб‑интерфейс и выложил его на домашний сервер. Готовые варианты ответа убрал, чтобы каждый мог написать своё продолжение. После отрывка ведущий включает правильный ответ и показывает, кто что придумал, а за угаданное слово игрок получает два балла. В таком виде мы и сыграли первую партию.

Я тоже хочу играть

Друзьям понравилось, и они попросили ещё. Это означало, что для следующей партии мне снова придётся прослушать песни, найти подходящие строки и нарезать вопросы с продолжениями. Больше всего меня не устраивало, что после такой подготовки я сам уже не мог нормально участвовать: все ответы были известны заранее. Хотелось добавлять музыку в игру и садиться угадывать вместе с остальными, поэтому я взялся за автоматизацию.

Я работаю DevOps‑инженером в GS‑Labs и AI‑лихорадка не обошла нас стороной. Одной из моих задач была разработка сервиса для подготовки отчётов по конференциям с помощью LLM, так что с распознаванием речи я уже успел познакомиться и решил попробовать тот же подход на песнях. К нынешней версии я пришёл не сразу. Чтобы дальше было проще следить за изменениями, сначала покажу два пути, по которым генератор обрабатывает песню сегодня.

Схема двух путей генерации
Два пути подготовки вопроса

Два пути подготовки вопроса

WhisperX на песнях

В сервисе для конференций я использовал WhisperX: FFmpeg подготавливает запись, Whisper распознаёт речь, отдельная модель уточняет таймкоды слов, а pyannote разделяет реплики по спикерам. Получившуюся расшифровку уже можно передать дальше для подготовки отчёта. С песней задача поначалу казалась даже проще, ведь обычно поёт один человек и делить реплики по спикерам не нужно. Зато вместо обычной речи распознаватель получает музыку с бэк‑вокалом, растянутыми гласными и проглоченными согласными. Для моей игры ошибка в одном слове могла испортить весь вопрос, если именно это слово предстояло угадывать.

В ранней версии я отдавал текст расшифровки локальной LLM (gpt‑oss-20b) и просил выбрать интересное слово, но вместе с настоящими словами она выбирала и ошибки распознавателя. Так в игру попадали ответы, которых в песне вообще не было, хотя по тексту расшифровки вопрос мог выглядеть вполне разумно. Текст подсказки тоже мог разъехаться со звуком: например, слова перед проигрышем оставались, а после него пропадали. К этому добавлялось ожидание ответа локальной LLM на каждом треке, и подготовка новой партии получалась одновременно долгой и ненадёжной.

Сначала я попробовал помочь распознавателю подготовкой звука: отделил вокал через Mel‑Band RoFormer, добавил фильтрацию низких частот, нормализацию и компрессию. Распознавание стало лучше, но ошибок всё ещё хватало, чтобы регулярно получать неудачные вопросы. Следующим шагом подключил тексты из Яндекс Музыки, откуда мы уже брали сами треки. С готовым текстом можно восстановить строки и правильное написание слов, а распознавание использовать для поиска нужного места в аудио. Такой вариант работал заметно лучше, однако у части песен, которые хотелось взять в игру, текста не было.

Для части песен Яндекс отдавал и метки времени, но для нарезки вопросов их оказалось недостаточно: в сохранённых LRC отмечено начало строки, а мне нужно остановить музыку перед последним словом внутри неё. Вычислить этот момент по длине строки не получится: певец может растянуть один слог, быстро проговорить несколько слов или сделать паузу. К тому же в тестах метки строк расходились с таймкодами распознавания, иногда больше чем на секунду. Например, в «Выходи гулять» Касты начало строки «Собираемся свободно и гуляем где угодно» отмечено в LRC на отметке 24,68 с, а WhisperX и обе GigaAM находят её первое слово на 25,80–25,92 секунды. Текст этой строки все три модели распознали без ошибок. Для обрыва перед словом такая разница существенна: можно оборвать предыдущую фразу или успеть выдать часть ответа. Поэтому готовый текст я использую для выбора и проверки слов, а точку обрыва определяю по пословным таймкодам, полученным из самого аудио.

Выбор слова я переписал на правила

Пока я разбирался с качеством распознавания, стало понятнее, по каким признакам вообще выбираю вопрос вручную. Обычно это длинное, содержательное слово в конце строки, перед которым достаточно текста, чтобы игрок успел предположить продолжение. При этом хочется пропустить самый старт трека, не брать бесконечно повторяющийся припев и убедиться, что ответ не прозвучал в том же отрывке несколькими секундами раньше. Всё это можно описать обычными правилами.

Если готовый текст есть, алгоритм перебирает последние слова строк, в основном в диапазоне от 25 до 85 процентов текста, и оценивает длину слова, повторы и окончания соседних строк. Затем он ищет выбранное слово в распознанном аудио и проверяет конкретное вхождение, поскольку одно и то же слово может встречаться в песне несколько раз. Без готового текста выбирать приходится прямо из расшифровки, поэтому к отбору добавляются проверки времени: сколько длится слово, не пересекается ли оно с соседними и хватает ли контекста перед ним. Через pymorphy3 определяю части речи, чтобы чаще выбирать существительные и отбрасывать служебные слова, а если первый кандидат не проходит проверки, алгоритм переходит к следующему. После этого LLM для выбора вопроса больше не понадобилась, но проблема с ошибками распознавания осталась. Несколько удачных песен ничего не говорили о том, какие настройки действительно помогают, поэтому сравнивать варианты пришлось более последовательно.

Пришлось собрать лабу

Для этого я собрал отдельную ASR‑лабу, где результаты моделей можно посмотреть рядом, строка к строке, и сразу послушать соответствующее место в исходном треке или отделённом вокале. Так стало гораздо удобнее разбирать конкретные промахи и понимать, на каком этапе они появляются. Начал с WhisperX large‑v3 с подсказкой и без неё, GigaAM v3, GigaAM Multilingual и Qwen3-ASR, а затем добавил Parakeet, Canary, Voxtral, Vosk и русские дообучения Whisper. Каждой модели давал разные варианты звука: исходный микс, вокал после Mel‑Band RoFormer, тот же вокал с фильтрами и компрессором, а также результат BS‑RoFormer.

Для основного сравнения собрал 100 треков 86 исполнителей, не больше четырёх песен на одного. Распознаватели получали только звук, а для проверки результата использовал референсные тексты: 92 из Яндекс Музыки и восемь из LRCLIB. Кроме этих 100 песен, в лабе были и треки без референсного текста: их я сравнивал на слух, а в таблицу WER они не вошли.

«Атомная романтика»

Хорошо видно, с чем приходится иметь дело, на примере «Атомной романтики» хардкор‑панк‑группы «Пурген». Здесь хриплый, почти кричащий вокал, а в припеве сильно растянута первая гласная. Для сравнения я взял фрагмент с 01:03 до 01:10 со строкой:

И ядерные взрывы освещают пути нам.

Следом идёт «А‑а-а‑а-атомная романтика!». Вот несколько расшифровок этого места:

Модель

Что ей дали послушать

Что она написала

WhisperX large‑v3 с подсказкой

Исходный трек

«ядерных взрывов посвящают пути нам. Водопная романтика»

WhisperX large‑v3 с подсказкой

Вокал Mel‑Band RoFormer

«ядерный взрыв. Освещают Путина. Атомная романтика»

WhisperX large‑v3 без подсказки

Вокал Mel‑Band RoFormer

«ядерный взрыв освещает Путина. Вот такая романтика!»

Qwen3-ASR 1.7B

Исходный трек

«она»

Qwen3-ASR 1.7B

Вокал Mel‑Band RoFormer

«ядерный взрыв освещает пути нам Вот она и романтика»

GigaAM v3 e2e RNN‑T

Исходный трек

«ядерный взрывы освещают путь и нам! О‑о-о! Вода проигратика!»

GigaAM v3 e2e RNN‑T

Вокал Mel‑Band RoFormer

«ядерные взрывы посвящают Путина! О‑о-о! Вот моя романтика!»

GigaAM Multilingual

Вокал Mel‑Band RoFormer

«ядерные взрывы посвящают путина адомная романтика»

GigaAM v3 CTC

Исходный трек

«и ядерные взрывы освещают пути и нам водовая роматикано»

GigaAM v3 CTC

Вокал Mel‑Band RoFormer

«не ядерные взрывы освещают путина вот она роматика»

На исходном миксе WhisperX сохраняет «пути нам», хотя ошибается в соседних словах, а после отделения вокала превращает их в «Путина». Ту же склейку на вокале выдают все три показанные GigaAM. Для CTC я отдельно повторил распознавание полного трека на исходном миксе и сохранённом вокале Mel‑Band: на миксе получилось «пути и нам», а после разделения тоже «путина». В финальную тройку CTC вошла по результатам сравнения на 100 песнях и проверки совместного отбора вопросов, о которых расскажу ниже. Этот пример показывает ограничение такой проверки: несколько моделей могут согласиться и на ошибке, поэтому само по себе совпадение слова ещё не гарантирует правильного ответа.

С припевом получается ещё веселее: «Водопная романтика», «Вот моя романтика», «Вода проигратика». У Qwen на миксе от всего фрагмента остаётся одно «она», зато на отделённом вокале модель восстанавливает гораздо больше текста и правильно распознаёт «пути нам», хотя с самим припевом всё равно не справляется. Хрип, растянутая гласная, инструменты поверх голоса: что именно мешает сильнее, по этому примеру не выяснить. Видно только, что отделение вокала помогло Qwen восстановить строку, а от общей ошибки остальных моделей не спасло. Синхронизированного текста «Атомной романтики» в Яндексе не нашлось, поэтому слова я сверил отдельно, а сам трек оставил за пределами таблицы точности на 100 песнях.

Михаил Круг и «двери»

Другой характерный промах встретился в «Девочке‑пай» Михаила Круга: на отрезке с 01:08.27 до 01:14.98 несколько моделей споткнулись о слова «В нашей Твери». В этом случае текст для сверки есть в Яндекс Музыке.

Модель на исходном миксе

Во что превратилось «Твери»

WhisperX large‑v3 без подсказки

Твери

GigaAM v3 CTC и e2e RNN‑T

Твери

Parakeet TDT v3

двери

Vosk Zipformer2

двери

Voxtral Realtime

твире

Qwen3-ASR, фрагменты до 30 секунд

тюрьи

Parakeet и Vosk превратили «Твери» в «двери», причём отделение вокала через BS‑RoFormer эту ошибку не исправило. В соседних словах тоже было на что посмотреть: у Parakeet появились «штурцы дровых», а у Qwen «шкурцем травык». WhisperX без подсказки и две GigaAM распознали строку правильно на обоих вариантах звука, так что для этого фрагмента им хватило исходного микса.

Б.А.У. и пицца

Ещё один пример из «угарного метала» Б.А.У.. В «Венском конвертике» на 01:52.76 поют:

Зубами бы впиться в слоёный край.

На исходном миксе whisper-podlodka-turbo пишет «в пицца» вместо «впиться», и Qwen с фрагментами до 30 секунд выдаёт то же самое. Рядом со слоёным краем пицца выглядит вполне уместно, но в самой песне её нет. Canary добавляет ещё и лишние слова: «карточку», «или», в другом варианте «пиццу». С таким текстом подсказка уже сомнительная, даже если последнее слово распознано правильно. После BS‑RoFormer whisper-podlodka-turbo справляется со строкой, а Qwen по‑прежнему пишет «в пицца». Базовому WhisperX и двум GigaAM достаточно исходного микса, поэтому и здесь польза отделения вокала зависит от того, какой распознаватель слушает результат.

Сравнение проверенных конфигураций на 100 песнях

После сравнения я отдельно проверил, не испортил ли эксперимент подготовкой звука: все распознаватели получали 16 кГц, как Whisper. Сама частота соответствует входу этих моделей, но способ её получения оказался важен. Я повторил пилот на тех же пяти песнях, заменив прежнее преобразование через pydub на SoXR, который корректнее отсекает высокие частоты перед понижением частоты дискретизации. Однозначного улучшения не получилось: на отделённом вокале WER базового Whisper изменился с 15,78% до 16,00%, а у Canary снизился с 36,44% до 33,37%. У GigaAM на исходном миксе качество заметно упало, причём изменилось уже поведение детектора речи: он стал пропускать фрагменты, которые прежде отправлял на распознавание. Поэтому таблицы ниже описывают результат всей проверенной цепочки с прежней подготовкой аудио, а не универсальные свойства моделей независимо от настроек.

От отдельных примеров перешёл к WER, доле ошибок распознавания: число замен, пропусков и вставок слов делится на число слов в референсном тексте, поэтому меньший результат означает более точную расшифровку. Я считал WER отдельно для каждой песни, а затем брал среднее, чтобы длинные треки не перевешивали короткие. В таблице этот показатель обозначен как «WER macro по сопоставленным строкам», поскольку перед подсчётом расшифровка распределяется по строкам эталона.

Перед подсчётом оба текста приводились к нижнему регистру, без пунктуации и различия между «ё» и «е»; дефисы разделяли слова, числа переводились в словесную форму, а растянутые написания вроде «дааааа» сокращались. Распевки в скобках убирались, осмысленный бэк‑вокал оставался; междометия вне скобок не удалялись автоматически. Нормализатор также исправлял латинские буквы внутри русских слов и приводил к общей форме некоторые разговорные и числовые варианты, например «щас» и «сейчас». Повторы припевов сохранялись отдельными вхождениями и сопоставлялись с расшифровкой по тексту и времени.

Референсные тексты не проходили сплошную ручную сверку с аудио: замеченные ошибки я разбирал отдельно, но не переписывал исходные файлы под ответы моделей. Поэтому в WER могут попадать опечатки, несовпадения версии песни и ошибки сопоставления повторяющихся строк. В таблице сохранены все 100 песен каждой конфигурации, включая случаи с предупреждениями о таком сопоставлении. В расчёт входят все слова референсных строк после нормализации: если для строки не нашлось расшифровки, её слова засчитываются как пропуски. Однако слова распознавания, которые алгоритм не отнёс ни к одной референсной строке, учитываются отдельно и в этот WER не входят. Поэтому он отличается от WER при сравнении двух полных текстов целиком. Подтверждение выбранных слов‑ответов ниже является отдельной проверкой, а не ручной верификацией всех текстов.

Покрытие в таблицах показывает долю референсных строк, к которым удалось отнести хотя бы одно распознанное слово, в среднем по песням. Оно не означает, что строка распознана правильно или полностью: даже одно ошибочное слово делает её покрытой. Непокрытые строки остаются в расчёте WER, поэтому этот столбец помогает увидеть пропуски и ограничения сопоставления, а не задаёт отдельную выборку для оценки точности.

Настройки распознавания и расчёта WER

В основной таблице использованы Whisper large‑v3 в WhisperX и GigaAM v3 с checkpoint’ами v3_ctc и v3_e2e_rnnt. У Whisper задан русский язык, float16, batch size 8, beam size 10, best_of 5 и patience 2; включено выравнивание слов. Пороги VAD: onset 0,1, offset 0,36, минимальная длительность речи 200 мс. Для декодирования указаны log_prob_threshold −1,0, no_speech_threshold 0,4, hallucination_silence_threshold 4 с и length_penalty 1. Варианты с подсказкой и без неё различаются только статичным описанием песни; сам текст песни распознавателям не передаётся. Батчевый WhisperX обрабатывает найденные VAD‑фрагменты независимо, поэтому параметр переноса предыдущего текста в этой реализации не даёт эффекта.

GigaAM получает полный трек через transcribe_longform, который сначала выделяет речь с помощью VAD, затем распознаёт полученные участки. Используется fp16 для энкодера и штатное декодирование выбранного checkpoint’а; отдельный языковой параметр в этом адаптере не передаётся. Варианты звука готовятся заранее: моно, 16 кГц, преобразование через pydub, а разделители вокала получают исходное аудио. BS‑RoFormer использует model_bs_roformer_ep_317_sdr_12.9755.ckpt, Mel‑Band RoFormer использует model_mel_band_roformer_ep_3005_sdr_11.4360.ckpt.

В пилоте на пяти песнях русские дообучения Whisper запускались через CTranslate2-конверсии с теми же параметрами декодирования. Для antony66/whisper-large-v3-russian использовалась bzikst/faster-whisper-large-v3-russian: её автор прямо указывает исходную модель и команду конверсии в float16 в карточке модели. Для второго дообучения использовалась bond005/whisper-podlodka-turbo-ct2. Остальные checkpoint’ы: nvidia/parakeet-tdt-0.6b-v3, nvidia/canary-1b-v2, Qwen/Qwen3-ASR-1.7B, mistralai/Voxtral-Mini-4B-Realtime-2602 и csukuangfj/sherpa-onnx-zipformer-ru-2025-04-20. Parakeet определяет язык автоматически; у Canary заданы русский вход и выход, у Qwen язык Russian. Qwen, Voxtral и Vosk получают фрагменты до 30 секунд с границами по тихим местам; у Vosk используется greedy search, у Voxtral do_sample=False. Qwen работает в bfloat16, с max_new_tokens 2048 и выравнивателем Qwen/Qwen3-ForcedAligner-0.6B; Voxtral тоже в bfloat16, без пословного выравнивателя. Модели NeMo получают полный файл и используют своё разбиение и штатные настройки декодирования.

Точные ревизии всех исторических библиотек и весов не зафиксированы единым lock‑файлом, поэтому это описание проверенных настроек, а не гарантия побитового воспроизведения старых расшифровок. Для статистической проверки я использую уже сохранённые результаты. 95%‑е интервалы ниже рассчитаны бутстрапом по песням: 2000 раз случайно выбирались 100 песен с возвращением, то есть одна песня могла попасть в выборку несколько раз. Для каждой выборки считалось среднее WER, а границами служили 2,5-й и 97,5-й процентили (seed 20260922). Для сравнения двух конфигураций использовались одни и те же выбранные песни. Повторно запускать нейросети для этого не нужно: расчёт выполнен по сохранённым числам ошибок и слов. Эти интервалы описывают чувствительность к составу корпуса, но не устраняют систематические ошибки референсов или разметки.

Проверенная конфигурация

WER macro по сопоставленным строкам

95%‑й бутстрап‑интервал

Покрытие строк, macro

WhisperX large‑v3 без подсказки, BS‑RoFormer

17,7%

14,7–21,1%

96,2%

GigaAM v3 e2e RNN‑T, BS‑RoFormer

18,4%

15,3–21,6%

96,0%

GigaAM v3 CTC, BS‑RoFormer

18,5%

15,4–21,8%

97,2%

WhisperX без подсказки, Mel‑Band RoFormer

19,3%

16,1–22,8%

95,9%

WhisperX без подсказки, Mel‑Band + DSP

19,0%

15,9–22,5%

96,0%

WhisperX с подсказкой, Mel‑Band + DSP (прежняя схема)

24,6%

21,2–28,3%

90,3%

GigaAM v3 e2e RNN‑T, исходный микс

24,7%

21,2–28,4%

92,8%

GigaAM v3 CTC, исходный микс

25,1%

21,6–28,9%

94,2%

WhisperX без подсказки, исходный микс

26,1%

22,2–30,3%

87,8%

WhisperX с подсказкой, исходный микс

33,5%

29,1–38,1%

82,4%

Одна из самых полезных правок оказалась простой: я убрал подсказку, в которой объяснял Whisper, что перед ним песня с рифмами, куплетами и припевом. Самого текста песни там не было, однако без этой подсказки WER на исходном миксе снизился с 33,5% до 26,1%. А вот фильтры и компрессор поверх отделённого вокала почти ничего не дали: 19,3% без обработки против 19,0% с ней. Парный бутстрап дал для разницы интервал от −0,78 до +0,40 процентного пункта, включающий ноль, поэтому убедительного выигрыша от этого этапа я не увидел.

На вокале после BS‑RoFormer результаты WhisperX и двух GigaAM оказались близки: 17,7%, 18,4% и 18,5% соответственно. WhisperX показал наименьшую долю ошибок, но проверка бутстрапом не подтвердила уверенного преимущества: при повторных выборках песен порядок моделей менялся. Поэтому по этому корпусу я не стал объявлять единственного победителя.

Остальные модели сначала проверил на пяти песнях, чтобы понять, стоит ли запускать их на всём корпусе. Набор здесь другой, поэтому напрямую сопоставлять проценты с предыдущей таблицей нельзя.

Модель, вокал после BS‑RoFormer

WER macro по сопоставленным строкам на 5 песнях

Покрытие строк, macro

WhisperX large‑v3 без подсказки (база)

15,5%

98,0%

Русское дообучение antony66/whisper-large-v3-russian

19,1%

91,6%

bond005/whisper-podlodka-turbo

23,3%

89,0%

Parakeet TDT 0.6B v3

26,1%

98,6%

Qwen3-ASR 1.7B, фрагменты до 30 секунд

26,4%

98,2%

Voxtral Mini 4B Realtime

29,4%

86,0%

Vosk 0.54 Zipformer2

31,7%

89,4%

Canary 1B v2

36,4%

81,4%

Пяти песен недостаточно для общего рейтинга, но на этом наборе русские дообучения Whisper не обошли базовую модель. Qwen здесь уже запускался с фрагментами до 30 секунд: после раннего неудачного запуска я пересмотрел его настройки.

Как теперь выбирается вопрос

За сравнением распознавателей я постепенно ушёл довольно далеко от исходного конкурса, хотя для одного раунда мне по‑прежнему было нужно только одно подходящее место в песне. Ошибка в другом куплете никак не мешает этому вопросу, если выбранный фрагмент распознан правильно. Поэтому дальше я занялся отбором участков, которым можно доверять.

Для треков без готового текста оставил три распознавателя: WhisperX large‑v3 без подсказки, GigaAM v3 CTC и GigaAM v3 e2e RNN‑T. Сначала все они слушают исходный микс, после чего алгоритм сопоставляет слова по порядку и времени и ищет места, где совпали все три расшифровки. Для выбора ответа двух голосов из трёх недостаточно. Перед ответом должны совпасть ещё хотя бы три слова подряд, желательно пять, без длинной паузы. Среди таких участков алгоритм ищет конец фразы, по возможности с существительным, и дополнительно проверяет, не прозвучало ли слово‑ответ раньше в том же отрывке.

Если на исходном миксе подходящего места не нашлось, BS‑RoFormer отделяет вокал, который затем слушают те же три модели. Здесь появляется дополнительное условие: выбранное слово должны были распознать хотя бы две модели на исходном миксе, поскольку игрок будет слушать оригинальную песню вместе с инструментами. Когда и этот вариант не проходит проверки, трек пропускается.

Пары моделей я тоже пробовал и встретил показательный случай в песне «37» группы «джинсы тарковского»: WhisperX и GigaAM CTC выбрали «самолёта», хотя в тексте «самолётом». Тройка отвергла этот участок благодаря проверке согласованного контекста, причём само окончание неверно услышали все три модели. Получается, от ошибки спасла именно проверка соседних слов, а одного совпадения ответа было бы недостаточно.

В этой схеме WhisperX даёт таймкоды для нарезки, знаки препинания GigaAM RNN‑T помогают найти конец фразы, а CTC участвует в проверке совпадений. По моим замерам на видеокарте, две GigaAM при уже загруженных моделях суммарно тратят примерно две секунды на распознавание четырёхминутного трека, без учёта подготовки звука и загрузки моделей. Такая прибавка ко времени подготовки меня устраивает.

Сколько приходится ждать

Полный рабочий прогон из 100 входных треков на NVIDIA GeForce RTX 5060 Ti с 16 ГБ видеопамяти занял 4 часа 4 минуты 40 секунд. Получение песен и текстов из Яндекса заняло первые 4 минуты 34 секунды, а на последующую обработку приходилось в среднем 144 секунды на входной трек. Это время конкретного запуска через веб‑интерфейс: 93 песни с готовым текстом прошли через Mel‑Band RoFormer и WhisperX, а семь без текста через согласие трёх моделей. Это те же 100 треков, что и в WER‑корпусе, но числа описывают разные вещи: 92 + 8 обозначает источники сохранённых референсов, а 93 + 7 наличие готового текста у генератора в этом запуске. Разница приходится на «Индустрию смерти» Пургена: её лабораторный референс взят из LRCLIB, а в рабочем прогоне текст был доступен.

Полный рабочий прогон дал 97 вопросов. Отдельная проверка режима согласия на 100 треках дала 98: там готовые тексты не передавались алгоритму вообще. В первом случае проверялась подготовка партии целиком, во втором только алгоритм выбора вопроса по сохранённым расшифровкам.

Основную часть ожидания занял RoFormer: в пути с готовым текстом отделение вокала требовало в среднем 107 секунд на песню, около 73% времени разделения и распознавания. Если смотреть на качество полной расшифровки, убирать разделение вокала совсем невыгодно: WER Whisper после BS‑RoFormer составлял 17,7%, а на миксе 26,1%. Зато в режиме согласия можно сначала попробовать микс и отделять вокал только при неудаче; уже загруженные GigaAM добавляют к распознаванию четырёхминутного трека примерно две секунды.

Замеры производительности: этапы, загрузка моделей и VRAM

Самым долгим этапом оказался RoFormer. Для 93 песен с готовым текстом время распределилось так:

Этап

Среднее на трек

Диапазон

Отделение вокала через Mel‑Band RoFormer

107,1 с

55,6–188,5 с

Освобождение разделителя и подготовка звука перед WhisperX

6,9 с

3,7–12,0 с

Загрузка WhisperX, распознавание, выравнивание слов и очистка памяти

33,0 с

29,7–47,4 с

Выбор вопроса и сохранение двух MP3, если вопрос найден

1,1 с

0,8–2,2 с

На отделение вокала пришлось около 73% суммарного времени разделения и распознавания в этом режиме. Например, в «Новый год чем‑то снова…» группы «кьюаркод» Mel‑Band отработал за 56 секунд, а в «Моя бабушка курит трубку» Гарика Сукачёва за 189 секунд. Вместе с подготовкой звука и WhisperX эти песни заняли соответственно 89 и 235 секунд. У «Венского конвертика» длительностью 3 минуты 45 секунд разделение заняло 132 секунды, оставшаяся обработка 55 секунд, а выбор вопроса и запись файлов ещё около секунды.

Время загрузки моделей здесь входит в соответствующие этапы, но первоначальное скачивание весов из интернета в этот замер не входит. Последняя строка таблицы посчитана по 91 успешно созданному вопросу из этого режима; для двух пропущенных песен сохранять MP3 было нечего.

Просто убрать разделение вокала означало бы заметно ухудшить расшифровку. На корпусе из 100 песен WER WhisperX без подсказки составлял 17,7% после BS‑RoFormer и 26,1% на исходном миксе, то есть без разделения доля ошибок вырастала на 8,4 процентного пункта. У GigaAM CTC она увеличивалась с 18,5% до 25,1%, у RNN‑T с 18,4% до 24,7%. Здесь речь именно о качестве полного текста: из этих процентов нельзя заключить, что столько же вопросов окажутся неправильными.

Для игры это различие позволило сэкономить время. Даже в расшифровке с ошибками часто находится подходящий фрагмент, который все три модели распознали одинаково, поэтому сначала можно попытаться выбрать вопрос на миксе. Для пяти треков полного рабочего прогона, которым не понадобился запасной проход через вокал, распознавание тремя моделями и отбор заняли в среднем 47 секунд, от 41 до 53 секунд на трек. Это другие песни, поэтому напрямую делить их время на время «Конвертика» было бы некорректно. В отдельной проверке самого «Конвертика» тот же путь без отделения вокала подготовил вопрос и оба MP3 за 59 секунд.

Экономия получается, когда вопрос удаётся найти с первой попытки. Если приходится переходить к BS‑RoFormer, ко времени распознавания микса добавляются разделение вокала и ещё один проход моделей. Два трека, дошедшие до запасного прохода в полном рабочем прогоне, обрабатывались 159 и 207 секунд, в среднем 183 секунды, причём один закончился пропуском трека. В отдельном замере на том же «Конвертике» один BS‑RoFormer занял около 150 секунд. Поэтому я оставил его запасным вариантом для режима согласия; путь с готовым текстом пока по‑прежнему использует Mel‑Band RoFormer для каждого трека.

Загрузка моделей и видеопамять

Чтобы понять, сколько из этого времени уходит на смену моделей, я отдельно повторил обработку полного «Венского конвертика» с замером каждого этапа. Загрузка Mel‑Band RoFormer заняла 5,7 секунды, BS‑RoFormer 3,1 секунды, а освобождение Mel‑Band после обработки около 0,1 секунды. У WhisperX загрузка распознавателя заняла 17,5 секунды, загрузка модели для выравнивания слов ещё 11,6 секунды. Между распознаванием и загрузкой выравнивателя сборка мусора и очистка CUDA‑кеша заняли около 0,2 секунды. Само распознавание в этом запуске заняло 5,5 секунды, выравнивание 1,3 секунды: значительная часть ожидания действительно пришлась на подготовку моделей. Веса уже лежали локально, но загрузчики обращались к Hugging Face за метаданными, поэтому это время нельзя считать только чтением файлов с диска.

У GigaAM разницу хорошо видно на двух последовательных обращениях с одним и тем же файлом. Первый запрос к CTC занял 11,7 секунды, повторный с уже загруженной моделью 0,5 секунды; у RNN‑T получилось 6,4 и 1,2 секунды. Время первого запроса включает запуск нужных компонентов и распознавание, поэтому целиком приписывать его переключению модели было бы неверно. Это отдельный замер, а не среднее по всей партии: в журнале большого прогона загрузка и работа каждой модели не разделялись.

В том же запуске я измерял занятую видеопамять через nvidia-smi. Перед обработкой на видеокарте уже было занято около 1,2 ГиБ; таблица показывает полное наблюдаемое потребление вместе с этим фоном и моделями, которые оставались загруженными.

Этап

Наблюдаемый пик занятой VRAM

Mel‑Band RoFormer

4,6 ГиБ

BS‑RoFormer

4,2 ГиБ

GigaAM CTC

2,7 ГиБ

GigaAM RNN‑T, CTC остаётся загруженной

3,2 ГиБ

Whisper large‑v3, обе GigaAM остаются загруженными

10,3 ГиБ

Выравнивание слов после Whisper

8,6 ГиБ

Это ориентиры для моей конфигурации: batch size 1 у RoFormer, batch size 8 и float16 у WhisperX, опрос памяти примерно раз в 0,2 секунды. Они не доказывают, что каждая модель требует именно столько памяти или что весь проект обязательно требует 16 ГБ. Пики нельзя складывать, поскольку этапы выполняются последовательно, а в показания входят оставшиеся выделения памяти предыдущих этапов. Подготовка звука, выбор вопроса и экспорт MP3 выполняются на CPU.

Отдельная проверка режима согласия: 98 вопросов

В этой проверке все 100 треков прошли через отбор по согласию трёх моделей, без готовых текстов на входе. Использовались сохранённые расшифровки: нейросети повторно не запускались, проверялся именно выбор вопроса. Это отдельный эксперимент, тогда как полный рабочий прогон с двумя путями обработки дал 97 вопросов. Результат режима согласия:

Проверка режима согласия на 100 треках

Количество

Получили вопрос

98

Вопрос выбран без отделения вокала

91

Для вопроса понадобилось отделить вокал

7

Трек пропущен: подходящего вопроса не нашлось

2

Слово‑ответ подтверждено текстом песни

98

Все 98 слов‑ответов подтвердились по текстам песен. Иногда поправка требовалась самому референсному тексту: в «Будущих мамах» Лигалайза было написано «металлоИКателем», а модели распознали «металлоИСкателем». При этом в самих подсказках ошибки остались: например, в «Плак‑плак» система выбрала правильный ответ «умереть», но перед ним написала «И мне так уж страшно» вместо «И не так уж страшно». Проверка нескольких слов перед ответом не покрывает весь текст, который видит игрок, поэтому подтверждение всех 98 ответов ещё не означает, что каждый вопрос целиком безупречен. Точность выбранных точек обрыва аудио этой проверкой я тоже не оценивал.

Без вопроса остались «Gitar» Петра Налича, где английский текст попал в конфигурацию для русского языка, и «Батя‑токарь» ZAPRAVKA, для которого ни на миксе, ни на вокале не нашлось подходящего слова с согласованным контекстом. Для моей игры пропустить такие треки допустимо: из плейлиста всё равно получается достаточно вопросов.

Как этим пользоваться

Со стороны ведущего подготовка теперь сводится к тому, чтобы добавить ссылки на треки, альбомы или плейлисты Яндекс Музыки и запустить генерацию. Если у песни есть текст, программа использует его вместе с таймкодами распознавания, а если нет, выбирает вопрос по согласию трёх моделей. Результат сохраняется в виде фрагмента с вопросом, продолжения с ответом и текста с пропуском. К началу партии вся работа нейросетей уже закончена: Flask и Socket.IO обслуживают ведущего и игроков, а nginx раздаёт страницы и готовые файлы. Игрокам достаточно открыть страницу в браузере на телефоне. Есть и упрощённый режим с одним WhisperX и отделением вокала, если согласие моделей выключено или модели GigaAM недоступны. Результат 98 из 100 относится именно к трём моделям, на упрощённый режим его переносить нельзя.

Что в итоге

В результате у меня получилась игра, для которой больше не нужно вручную готовить каждую новую партию. В отдельной проверке режима согласия на 100 треках удалось выбрать 98 вопросов, и все слова‑ответы подтвердились по текстам. Полный рабочий прогон, где использовались оба пути обработки, дал 97 вопросов из 100 входных треков и занял около четырёх часов. Для домашнего конкурса меня такой результат устраивает, хотя ошибки в подсказках остаются, а качество обрывов ещё нужно проверять отдельно.

Главным решением за всё это время было сузить задачу до выбора одного подходящего фрагмента. Когда я сформулировал признаки хорошего вопроса, выбор удалось описать обычными правилами, и LLM для этого больше не понадобилась. Распознаватели остались источником текста и таймкодов, причём сравнение их ответов оказалось полезнее, чем попытка выбрать одну лучшую модель для всех песен. Но даже три модели способны одинаково ошибиться, поэтому в проверку пришлось включить и само слово, и контекст перед ним.

Исходники What The Track и инструкция по запуску лежат на GitHub. Если захочется устроить похожий конкурс, можно развернуть игру у себя и попробовать её на своей музыке; мне особенно интересно, на каких песнях эта схема начнёт ошибаться у других. Из двух корпоративных идей у меня в итоге получились новогодний гимн, музыкальная игра и довольно обстоятельное знакомство с ошибками распознавания песен. Зато теперь можно добавить плейлист, запустить подготовку и не подсматривать ответы, чтобы наконец сыграть в собственный конкурс вместе с друзьями.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.