⚡ Градиент обреченный   Есть ряд платных решений по переводу речи в текст (Automatic Speech Recognition). Сравнительно малыми усилиями можно сделать бесплатное решение, — дообучить на своих данных end2end модель (например, взять фреймворк NeMo от NVIDIA) или гибридную модель типа kaldi. Сверху понадобится добавить расстановку пунктуации и денормализацию для улучшения читаемости ("где мои семнадцать лет" → "Где мои 17 лет?").  Недавно в открытый доступ была выложена мультиязычная модель whisper от OpenAI. Попробовал ее large вариант на нескольких языках и расшифровал 30 выпусков "Своей игры". Результат понравился, но есть нюансы. Модель транскрибирует тексты вместе с пунктуацией и капитализацией, расставляет временные метки, умеет генерировать субтитры и определять язык. Языков в обучающем датасете порядка ста. Чтобы прикинуть по качеству, нужно посмотреть на их распределение — данных на 100 часов и более было лишь для 30 языков, более 1000 ч. — для 16, ~10 000 часов — у 5 языков, включая русский. Модель заслуживает внимания так как умеет делать очень много "из коробки". Давайте разберемся подробнее и научимся ей пользоваться. Пара слов про whisper. В тесном мире ASR данных хватает, но не всегда хватает разметки. По этой причине появились unsupervised подходы по обучению на данных без транскрипций с последующим дообучением на небольшом размеченном датасете. В этом случае объем первичных данных можно увеличить до миллиона часов (см. wav2vec 2.0). Энкодер при этом выучивает очень качественные представления для звуков (точнее для их численного представления), но для преобразования их в человеческий вид все равно потребуется целевой размеченный людьми датасет. Объемы таких датасетов могут быть от ста до нескольких тысяч часов, то есть на много порядков меньше всех аудио, которые можно найти в интернете. Для русского языка также есть открытые датасеты, нарпример OpenSTT и SOVA. Авторы whisper идут по пути компромисса, используя weakly supervised подход. Взяли все доступные аудио с транскрипцями из интернета и пофильтровали их, но не сильно. Получили некий зашумленный датасет, в котором в том числе есть и транскрипции сделанные другими ASR системами, много тишины и шумов, смех, апплодисменты и т.д. Объем получился 680 000 часов на 97 языках, из которых 117 000 часов не на английском. Обучение на таком большом зашумленном датасете, по мнению авторов, дает значительное улучшение обобщающей способности модели и её устойчивости к посторонним звукам. Еще одной особенностью модели является её многозадачность. Задачи распознавания речи, перевода (с языка X на английский), определения языка и детекции голоса (VAD) при обучении были приведены к единому виду (в виде последовательности токенов, включая специальные —  
,  
, 
 и другие) в seq2seq манере. Это позволяет упаковать несколько специализированных моделей в одну и обучать все задачи совместно. Моделей натренировали несколько, — с увеличением количества параметров качество растет, но не драматически. Base и small моделями можно пользоваться на домашнем компьютере на CPU, medium и large тоже запустятся, но будут работать довольно медленно. Все эксперименты я проводил на large модели с использованием 3090 ti. Размер Веса Английская модель Мультиязычная модель Сколько нужно RAM tiny 39 M tiny.en tiny ~1 GB base 74 M base.en base ~1 GB small 244 M small.en small ~2 GB medium 769 M medium.en medium ~5 GB large 1550 M n/a large ~10 GB В качестве архитектуры взяли трансформер. Основной гипотезой авторов было обучение на большом шумном датасете, поэтому они не стали вносить значительных изменений в модель, чтобы не получить "побочных улучшений". Подробнее про процесс обучения можно почитать в статье, а мы пойдем дальше. Для начала установим библиотеку. Чтобы запустить whisper у себя на компьютере, поставим библиотеку: Это консольный клиент, модели подгрузятся при первом запуске.  Также нужно, чтобы в системе был установлен ffmpeg для работы с медиа данными. Для windows ffmpeg.exe нужно скачать отсюда, положить в любую папку и добавить её в PATH. Под linux библиотеку можно установить через консоль, например так: Ещё установим библиотеку yt-dlp для работы с youTube, она нам скоро пригодится. Если что-то не получилось, не стесняйтесь писать, мы все здесь чему-то учимся. Попробуем расшифровать несколько типичных видео разных жанров и с разным набором лексики. Cпециализированные домены (звонки в коллл-центр и т.д.) мы сейчас рассматривать не будем, так как без дообучения под такой домен результат будет заведомо плохой (я пробовал). И напротив, обычная речь с микрофона на общие темы распознается на отлично. Сначала попробуем транскрибировать ролик с несколькими спикерами, без специальной лексики и названий. Возьмем репортаж про Питерский трамвай. Скачаем файл командой: VPPknXEXk1k — это id ролика на youTube (файл). Теперь переведем его в текст: В папке result появится файлик piter.mp3.txt. Вот его начало: Самый обычный день из жизни большого города, пробкина дорогах, люди куда-то спешат, на остановке толькомы с оператором и мужчина лет 70 ждем трамвая, а покаразговариваем о том, о сём, в общем ни о чём, я говорюснимаем про трамвай, тут мой случайный попутчик представляетсяДмитрий Достоевский, в прошлом водитель трамвая,вот так, а с другой стороны чему удивляться, Петербург,трамвай, Достоевский.Дмитрий Андреевич, правнук великого писателя, кемтолько не работал и таксистом, и гидом, водил экскурсиипо местам произведения своего именитого предка,но с особой ностальгией всегда вспоминает именноо том времени, когда водил трамвай по городу.Я не могу из-под носа уехать, даже если я не мог, дажеесли я опаздываю и у меня, я знал, где я могу нагнать,где я чуть-чуть побыстрее поеду, всё это было известно,и поэтому, если кто-то бежит, я старался дожидаться.Я чуть не задавил известнейшего театрального режиссёраВладимирова.Серьёзно?Да.Как?Только благодаря моей реакции я тормознул.Но у меня там, конечно, все закричали, не картошкувезёшь, а что делать?Я по трансляции сказал, я человека сейчас спасу.Первый трамвай на электрической тяге, именно на электрическойконке уже вовсю ходили по городу, появился на Невев 1894 году. Как видим, водитель трамвая говорит простым языком, хотя и довольно сбивчиво. Модель все слова распознала корректно и расставила пунктуацию. Числа также были приведены к цифровому формату корректно. Возьмем выступление о кибербезопасности со специализированными IT-терминами и большим количеством говорящих, которые периодически друг друга перебивают.  Медиа-группа «Авангард» представляетДрузья, привет! Рад вас всех приветствовать на нашем SOC-форуме.Седьмой SOC-форум, конечно, это очень круто.Семь лет мы обсуждаем вопросы кибербезопасности.В совершенно новых форматах находим ответы.Если вспомнить, как всё начиналось семь лет назад, это был...Кто был первый SOC-форум инфопространством, мы рассчитывали, что соберём 200 человек.Мы считали, что это очень много.Пришло 400. Кофе на кофепаузе.Закончился ровно через пять минут после начала кофепаузы.И, конечно, вот этот вот темп, который мы набираемв нашей конференции, в нашем мероприятии, это очень круто.Итак, дорогие друзья, мы начинаем наш седьмой SOC-форум.SOC-форум, посвящённый практике противодействия кибератаками построению центров мониторинга. ... Юрий, хотел с вами,знаете, вот сейчас, когда говорим про поддержкуотрасли, это во многом еще и вопросфинансирования. Ведь кибербезопасностьэто, ну, в общем, прямо недешевая штука. И еслипосмотреть на некоторую статистикуфинансирования проектовпо информационной безопасности, онавыглядит, ну, такой, достаточно печальной.Если в мире в среднем выделяется105% от IT-бюджетов на обеспечениекибербезопасности, то в России по разным оценкам эта цифра где-то порядкаодного-двух процентов.И это в разы меньше.Как ты считаешь, Юр, какимдолжна быть поддержка отрасли, поддержкаразвивающихся бизнесов, стартапов для того,чтобы вот эта вот критическая массалюдей, могущих обеспечить безопасность,технологий необходимых для обеспечениябезопасности, но тем более в условияхимпортозамещения она появляласьи развивалась?Спасибо, Игорь.Я тогда продолжу свою мысль предыдущуюпро гендиров. Здесь тоже все хорошо, сеть знает о существовании некоего SOC'а, о существовании IT-шников, разговорных вариантов имен ("Юр") и даже многоточие поставила к месту. Чтобы вскрыть первую проблему возьмем случай посложнее — песни. Образный лексикон и постоянная музыка на фоне. Модель для этих целей не предназначена, но дадим ей шанс и ознакомимся с потенциальными проблемами. Транскрибируем "Очи черные" Высоцкого (файл). Получим вот такое: ВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюВахмелюСпасибо Бог вас, лошадки, что целым идут!Сколько канула, сколько схлынула,Жизнь кидала меня, не докинула.Может, спел про вас неумелая,Очи черные, скатерть белая. Как авторы пишут в статье (раздел Limitations and future work) с размером модели растет её устойчивость, но при транскрибации продолжительного аудио авторегрессионная природа модели может давать эффекты зацикливания, пропуска крайних слов сегмента и галлюцинаций (выдавать слова, которых нет на записи). Чаще всего это будет наблюдаться для малоресурсных языков и малознакомых доменов.  Можно попробовать побороться с этим, поигравшись с параметрами сэмплинга --temperature и ---logprob_threshold. Можно отключить авторегрессионность параметром --condition_on_previous_text, что ожидаемо ухудшит осмысленность текста, хоть и уберет зацикленность в нашем случае: ВахмелюСтрелял мне в лицо, только я проглочуВместе с грязью слюну,Штову горло скручу и опять затяну.Очи черные, как любил я вас,Но прикончил я то, что впрок припас.Головой тряхнул, чтоб слетела плаш,И вокруг взглянул, и присвиснул аж.Лес стеной впереди не пускает стена,Они прятут ушами, назад подают.Где просвет, где прогал, Ни беда, ни рожна.Коль утыкла меня, до костей Достают коренной тимой.Хрущай же, брат, ты куда, родной?Почему назад тошь, как яд с ветвей?Недобром пропах престижной моей.Волк нырнул под паху, вот же пьяный дурак.Вот же налил глаза, ведь погибель пришла.Обижать не суметь, из колоты моей Утащили туза, да такоготуза, Без которого смерть я ору волкам.Побери вас, прах, огоней пока, Подгоряет страх шевелюкнутом.Бью крученые и ору бритом, Очи черные, храп, да тоНо под Таляск далеко перепляс, Бубенцы плисовую играют стуки.Ах вы, кони мои, погублющие вас, Выносите, друзья, выносите враги от погони той.Даже хмели сяк, мы на кряш крутой, На одних осях в хлопьях пены мыСтруи в гря шлились, Отдышались, отхрепели Да откашлились я лошадкам Забитым, что не подвели.Поклонился в копыта До самой земли, Сбросил с воза манатки, Повёл по воду.Спасибо Богу, лошадки, Что целым иду.Сколько канула, сколько схлынула, Жизнь кидала меня, не докинула.Может, спел про вас неумелая, Очи чёрные, скатерть белая. Есть еще один хак, — можно подать в модель затравку (привет prompt-инженерам) через параметр --initial_prompt: Лесом правил яСтрелял мне в лицо, только я проглочуВместе с грязью слюнуШтову горло скручу и опять затянуОчи черные, как любил я васНо прикончил я то, что впрок припасГоловой тряхнул, чтоб слетела плашИ вокруг взглянул, и присвиснул ажЛес стеной впереди не пускает стенаОни прятут ушами, назад подаютГде просвет, где прогал, не беда, не рожнаКолю тыкла меня, до костей достаютКоренной ты мой, вручай же, братТы куда, родной, почему назад?Дождь, как яд с ветвей, недобром пропахПристежной моей волк нырнул под пахВот же пьяный дуракВот же налил глаза, ведь погибель пришлаОбижать не суметь из колоты моейУтащили туза, да такого тузаБез которого смерть я ору волкамПобери вас, прах, а коней покаПодгорает страх шевелюкнутомБью крученые и ору бритомОчи черные, храп, да то под ТаляскДа лихой перепляс, бубенцы плесовую играютСтуки, ах вы, кони мои, погублю же я васВыносите, друзья, выносите враги от погони тойДаже хмели сяк, мы на кряш крутойНа одних осях в хлопьях пены мыСтруи в кряш лились, отдышалисьОтхрепели, да откашлилисьЯ лошадкам забитым, что не подвелиПоклонился в копыта до самой землиСбросил с воза манатки, повел в поводуСпасибо Бог вас, лошадки, что целым идуСколько кануло, сколько схлынулоЖизнь кидала меня, не докинулаМожет, спел про вас неумелаяОчи черные, скатерть белая Затравка не считается транскрипцией, поэтому в результат не попадет. К ней мы еще вернемся чуть позже. Модель по умолчанию расставляет временные метки для фрагментов, поэтому еще раз заглянем в папку result, — и увидим там srt файл. Все это время уже генерировали субтитры. Вот расшифровка репортажа про трамвай: 00:00:00,000 --> 00:00:19,240Самый обычный день из жизни большого города, пробки 00:00:19,240 --> 00:00:21,860на дорогах, люди куда-то спешат, на остановке только 00:00:21,860 --> 00:00:25,400мы с оператором и мужчина лет 70 ждем трамвая, а пока 00:00:25,400 --> 00:00:28,180разговариваем о том, о сём, в общем ни о чём, я говорю ... 00:06:05,520 --> 00:06:08,920Встает солнышко, просыпаются наши пассажиры. 00:06:08,920 --> 00:06:12,080Также мы смотрим, как город засыпает, ездим по городу, 00:06:12,080 --> 00:06:15,240по центру есть маршруты, смотрим набережные. 00:06:15,240 --> 00:06:16,800Довольно красивые. 00:06:16,800 --> 00:06:28,000Для Петербурга трамвай – это не просто транспорт, 00:06:28,000 --> 00:06:30,520это еще один символ города, как Петропавловская крепость 00:06:30,520 --> 00:06:32,520или Пышечная на Большой конюшне. Ради интереса я транскрибировал большой моделью несколько последних выпусков телепередачи Своя игра и собрал из них страничку. Результат в целом мне понравился: 00:00:00.000 МУЗЫКАЛЬНАЯ ЗАСТАВКА 00:00:15.000 АПЛОДИСМЕНТЫ 00:00:19.000 Здравствуйте! Добрый день! Это «Своя игра». 00:00:22.000 Мы продолжаем наш турнир, который называется «Игры золотой девятки». 00:00:26.000 Сегодня у нас финальная игра пятого этапа «Игр золотой девятки» в 2022 году. 00:00:35.000 Сегодня играют очень сильные игроки. 00:00:37.000 С удовольствием вам представляю участников сегодняшней игры. 00:00:41.000 За первым игровым столом Дмитрий Корякин, программист из Раменского. 00:00:46.000 АПЛОДИСМЕНТЫ 00:00:48.000 За центральным игровым столом, он же второй игровой стол, Евгений Калюков, 00:00:53.000 журналист из Ульяновска. 00:00:55.000 АПЛОДИСМЕНТЫ 00:00:57.000 И за третьим игровым столом Юрий Хашимов, юрист Москва. Как мы видим, из обучающей выборки не убирали транскрипции звуков ("апплодисменты", "смех", "музыкальная заставка" и т.д.). Это не хорошо и не плохо, так как бывают различные требования к результату.  Так же я попробовал расшифровать лекции по машинному обучению от Андрея Карпати. Страничка и репозиторий. ... 00:26:57.000 Number one, let's not use 32. 00:26:59.000 We can, for example, do something like EMB.shape at 0 so that we don't hardcode these numbers. 00:27:07.000 And this would work for any size of this EMB. 00:27:10.000 Or alternatively, we can also do negative 1. 00:27:12.000 When we do negative 1, PyTorch will infer what this should be. Английские технические термины разспознаются достаточно хорошо. EMB здесь посчиталось за аббревиатуру, на самом деле произносилось название переменной. У модели есть еще один failure mode. Насколько я понял из кода, модель может перестать обуславливаться на предыдущий фрагмент, если сэмплинг был с высокой температурой (а она при ошибках начинает повышаться, так как заданы несколько дискретных значений). На эту тему есть дискуссия. Такое может чаще случаться в самом начале, а также рандомно на длинных аудио (больше часа). За время моих экспериментов я с таким не встретился. Авторы говорят, что пока что так, но вы если сломалось с самого начала, то попробуйте использовать --initial_prompt. Как человек, имеющий легкий "сдвиг" на изучении языков и смежные темы, я бы выделил и еще одно применение этой модели. По сгенерированным субтитрам можно нарезать роликов или аудио с фразами на нужную тему и использовать для улучшения языковых навыков. Это подойдет как минимум для языков из первой десятки, так как качество распознавания на них достойное.  Разумеется можно взять и готовые субтитры к какому-нибудь фильму или сериалу. В общем, я покажу как это можно сделать, а вы уж решайте дальше. Подготовим видео (фильм, сериал или видео с youTube). В случае youTube воспользуемся уже знакомой утилитой и выкачаем видео какой-нибудь лекции: Сгенерируем субтитры whisper'ом, или возьмем готовые. srt файл с субтитрами назовем subs.srt. Скрипты для следующий действий я выложил в репозиторий, качаем его. Сначала приведем субтитры к более удобному виду. Этот csv файл сдоержит начало и конец фрагмента, а также его содержание. start_time	end_time	        rename_to	content00:00:00,000	00:00:01,180	video0.mpg	Hi everyone.00:00:01,180	00:00:04,200	video1.mpg	Today we are continuing our implementation of Makemore.00:00:04,200	00:00:05,040	video2.mpg	Now in the last lecture,00:00:05,040	00:00:06,760	video3.mpg	we implemented the multilayer perceptron00:00:06,760	00:00:08,880	video4.mpg	along the lines of Benjou et al. 200300:00:08,880	00:00:10,720	video5.mpg	for character level language modeling. ... Оставим в нем только нужные строки, например, первую и третью: start_time	end_time	        rename_to	content00:00:00,000	00:00:01,180	video0.mpg	Hi everyone.00:00:04,200	00:00:05,040	video2.mpg	Now in the last lecture, Теперь нарежем по этим параметрам видео фрагменты: Запустится ffmpeg и в папке output начнут появляться наши видео. При желании можно предварительно "прожечь" субтитры прямо в исходное видео, тогда после нарезки у нас будут ролики с фразами в кадре: К вышесказанному можно добавить еще несколько направлений, которые можно попробовать. Диаризация — разделение спикеров. Понадобится при необходимости вычленить из аудиопотока определенного человека или добавить имя говорящего к субтитрам. Whisper не был на это натренирован, но вот здесь этот вопрос обсуждают и делятся наработками (colab). Дообучение. Точно повысит качество под вашу конкретную задачу, так как whisper — модель общего назначения. Опять же, официально пока скриптов нет, но обсуждается здесь и есть colab. ⚡ Градиент обреченный — завел канал про машинное обучение и рабочие моменты. Приглашаю всех, кому интересна эта тема. ➰ Транскрипции Своей игры — можно посмотреть на качество распознавания whisper и повторить на своих видео. 👄 Whisper — репозиторий с моделью и инструкциями, там же ссылка на статью. 🔨 NeMo — фреймворк для обучения своих SOTA моделей. Выбирайте модель (например, Conformer-CTC) и дообучайте на своих данных. 🎞️ Video Splitter — подготовил репозиторий для нарезки видео по субтитрам. ✏️ Multipunct — репозиторий для тренировки пунктуационной модели. Как пользоваться писал тут.  ML Engineer