Понижаем барьеры на вход в распознавание речи +18





image


Автоматическое распознавание речи (STT или ASR) прошло долгий путь совершенствования и имеет довольно обширную историю. Расхожим мнением является то, что лишь огромные корпорации способны на создание более-менее работающих "общих" решений, которые будут показывать вменяемые метрики качества вне зависимости от источника данных (разные голоса, акценты, домены). Вот несколько основных причин данного заблуждения:


  • Высокие требования к вычислительным мощностям;
  • Большое количество данных, необходимых для обучения;
  • В публикациях обычно пишут только про так называемые state-of-the-art решения, имеющие высокие показатели качества, но абсолютно непрактичные.

В данной статье мы развеем некоторые заблуждения и попробуем немного приблизить точку "сингулярности" для распознавания речи. А именно:


  • Расскажем, что можно достигнуть отличного результата в рамках разумного времени, используя лишь две видеокарты NVIDIA GeForce 1080 Ti;
  • На всякий случай еще раз представим датасет Open STT для русского языка на 20 000 часов;
  • Опишем различные подходы, позволяющие ускорить процесс тренировки STT на порядок.

В этой статье есть 3 основных блока — критика литературы и доступных инструментов, паттерны для проектирования своих решений и результаты нашей модели.


Оглавление



Технологии


Для экспериментов мы выбрали PyTorch, а в качестве отправной точки для нейросети — Deep Speech 2.


Причины выбора данного стека:


  • Масштабируемость вычислительных мощностей количеством GPU;
  • Простота. Python и PyTorch упрощают процесс исследования, можно сфокусироваться на самих экспериментах;
  • Гибкость. Добавление новых фич не занимает много времени и усилий;

Также немаловажно, что экосистема PyTorch постепенно обрастает такими "вкусными" фичами из коробки как квантизация, деплой на мобилку, обертки и конвертеры для других языков программирования (например, C++ и JAVA).


Датасет Open STT


Ранее мы писали на Хабре об огромном открытом датасете русской речи с более чем 20 000 часами разметки для русского языка. Этот датасет содержит бОльшую часть данных (~90%), используемых для тренировки наших моделей.


Критика индустрии


Большинство научных статей, которые мы прочли, как правило, были написаны исследователями из “индустрии” (напр. Google, Baidu, и Facebook). В целом, большую часть критики статей и решений STT можно отнести к опыту исследователя в “индустрии” либо в “академии”.


Если кратко, наши основные претензии к индустрии, когда мы говорим об STT, такие:


  • Создание продакшен решений на основе приватных данных, о чем в самих публикациях информации очень мало;
  • Сложные фреймворки и инструменты;
  • Решение несуществующих проблем;
  • Обфусцированные результаты.

Давайте подробно разберём каждый из приведенных пунктов.


Создание продакшен решений на основе приватных данных, о чем в самих публикациях информации очень мало


Знаменитая статья Deep Speech 2 (2015) приводит следующую таблицу:


Процент данных, % Часы, ч Обычные данные WER, % Шумные данные WER, %
1 120 29,23 50,97
10 1200 13,80 22,99
20 2400 11,65 20,41
50 6000 9,51 15,90
100 12000 8,46 13,59

Сравнение WER (word error rate, процент ошибок на уровне слов) для английского языка для Обычного и Шумного датасетов при увеличении размеров датасета. Архитектура сети: 9-слойная модель с 2 слоями 2D-инвариантных сверток и 7 рекуррентными слоями с 68 млн. параметров, Deep Speech 2.

Вывод на основе нее такой: чтобы сделать модель хорошего качества, нужно много данных. Это одна из немногочисленных статей, явно на это обращающих внимание и проводящих валидацию на данных из внешних датасетов. Большинство современных STT статей обычно сильно оверфитятся на корпусе LibriSpeech ASR (LibriSpeech) все более и более экстравагантными способами.


Вполне вероятно, что Google, Facebook, и Baidu имеют у себя в распоряжении датасеты на 10 000 — 100 000 часов для тренировки своих моделей. На это можно найти намеки, например, в последних публикациях Facebook, но, естественно, корпорациям невыгодно делиться тем, на каких данных натренированы их продакшен решения.


К этому прибавляется еще и относительная трудоемкость ручной разметки. На 1 час разметки может понадобиться от 2 до 10 часов труда разметчика (влияют сложность домена и наличие автоматической разметки на входе, например, результатов распознавания STT модели).


Все это приводит к текущей ситуации, когда все заявляют о невероятных результатах на идеализированном публичном датасете (LibriSpeech), но молчат о том, как эти модели ведут себя на реальных данных и на чем собственно какие продакшен-модели натренированы. Экономического стимула выпускать в open-source большие проприетарные датасеты у таких компаний, как Google, естественно нет. В конечном счете, возникает высокий барьер на вход для тех, кто хочет создать свою STT-систему. Есть, конечно, проекты типа Common Voice, но данных там пока очень мало для всех языков кроме английского.


Сложные фреймворки и инструменты


Проект Коммитов Разработчиков Язык/Фреймворк Комментарий
Wav2Letter++ 256 21 C++ Коммиты тут скорее это релизы версий
FairSeq 956 111 PyTorch
OpenNMT 2 401 138 PyTorch
EspNet 5 441 51 PyTorch
Типичный ML проект 300-500 1 — 10 PyTorch

Обычный подход в машинном обучении (как и в разработке в целом) — использование фреймворков вместо написания всего с нуля. Казалось бы, должны быть фреймворки для STT, из которых можно было бы брать готовые части/модели, чтобы не писать модели с нуля на PyTorch и TensorFlow. Но, к сожалению, с речью дело обстоит несколько иначе.


Использовать такие инструменты/фреймворки (таблица выше), чтобы придать первичный импульс своему проекту, нерационально по целому ряду причин:


  • Код оптимизирован под большие вычислительные возможности (десятки или даже сотни видеокарт);
  • Рецепты (end-to-end примеры, показывающие, как использовать фреймворк) существуют только для небольших академических датасетов и не масштабируются на реальные данные без опять же больших вычислительных мощностей;
  • Рецепты очень прожорливы (выдающийся пример — тренировка 10GB-ых языковых моделей на датасетах из нескольких сотен мегабайт текста);
  • Даже если сделать претренировку модели на LibriSpeech, вероятнее всего, она не заработает на реальных данных;
  • При желании создать внутреннее STT решение на основе таких инструментов, подогнать его под себя, разобраться в нем и оптимизировать, с большой вероятностью вам понадобятся или большая команда, или значительное количество времени;
  • Эти инструменты являются либо опубликованными внутренними инструментами, или сделаны в целях PR, в соответствии со стратегией “быть первыми на рынке” или призваны создать “экосистему”. А это значит, что вероятнее всего, эти решения могут служить минимально жизнеспособным продуктом или базовым решением, вот только подогнать их под себя, не инвестировав запретительное количество ресурсов, не удастся (а если вы корпорация, то вы, скорее всего, сами напишете свой инструмент);
  • Если вы все-таки дойдете до нужного качества, то скорее всего встанет вопрос скорости работы решения, и не факт, что решение, которое изначально дизайнилось прожорливым, будет очень быстрым;

Исходя из личного опыта, мы несколько раз подходили к некоторым пайплайнам из FairSeq и EspNet, и пришли к выводу, что в разумные сроки и разумным количеством усилий их не одолеть. Может быть, у вас получилось?


Решение несуществующих проблем


Создание нового инструмента для LibriSpeech, который работает на 8 GPU за US $10 000 не поможет в решении реальных задач.


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


Тем не менее, пока из внешних датасетов по-настоящему "народным" можно считать разве что Common Voice от Mozilla.


Невоспроизводимые результаты


Регулярно наблюдаемая картина в ML: каждую неделю кто-то заявляет о новом рекордном (state-of-the-art, SOTA) результате, только результаты эти редко воспроизводимы или приведены вместе с запускаемым кодом.


Добавить сюда безумное количество требуемого железа, большие датасеты, время, требуемое для обучения, и задача воспроизводимости становится только сложнее.


Мы верим в то, что фокус должен быть смещен c “пробивания лидербордов” в сторону “решений, достаточных для применения в решении реальных задач” и публичных датасетов.


Критика академии


Если не сильно углубляться, то суть сводится к следующему:


  • Когда большая группа людей преследует какую-либо метрику, эта метрика становится бесполезной (см. Goodhart's Law);
  • Оверфиттинг на маленьком “стандартном” датасете сломан ничуть не меньше, чем конкурсные лидерборды (да и по сути, такой оверфиттинг сам же и является лидербордом);
  • Использование больших, прожорливых сетей на больших вычислительных мощностях вместе с невоспроизводимостью результатов оставляют желать лучшего;
  • Подход к модели как к алгоритму сжатия может быть куда более привлекательным и полезным, чем погоня за высокими метриками на лидерборде;
  • В идеальном сценарии статьи должны быть достаточно детальными, чтобы независимый исследователь мог воспроизвести хотя бы 95% того, что удалось достичь авторам. В реальности же содержание и структура статей вызывают вопросы к их действительной цели и возможности реального применения. То есть они опубликованы в соответствии с ментальностью “без бумажки ты букашка” (“publish or perish”), и сложная математика использована для объяснения новых концепций, несмотря на то, что сами исследователи к этой математике никакого отношения не имеют, а для вычислений использовали готовые пакеты;
  • Когда дело касается генерализации решения, то есть тестирования вне домена, статьи, мягко говоря, расплывчаты. По прочтению статей может сложиться впечатление, что люди проигрывают нейросетям в распознавании речи, но это не так, это всего лишь еще один симптом лидерборда. В противном случае, приложения с идеальным распознаванием речи были бы многочисленны повсюду и на всех устройствах.


    Было бы куда проще достигать результатов, если бы ML статьи следовали следующей структуре:


    • Использованы следующие инструменты/ имплементации/ идеи;
    • Внесены следующие важные модификации;
    • Проведены следующие эксперименты и получены следующие результаты.


На что еще можно обратить внимание


На что еще обратить внимание, имея дело с машинным обучением и распознаванием речи:


  • Очень мало внимания уделяется стабильности гипер-параметров;
  • Совершенно новые semi-supervised и unsupervised подходы обучения (wav2vec, циклическое обучение STT-TTS) не проводят никаких проверок прожорливости, устойчивости, генерализуемости и в основном продвигают фактор новизны;
  • Академики обычно оверфитят свои языковые модели и методы end-to-end обработки на маленьком и идеализированном датасете (LibriSpeech), при этом их методы очень субоптимальны, так как данных в текстовых доменах как минимум в 1000 раз больше (просто сравните размер Википедии и весь корпус LibriSpeech);
  • Привычка слишком сильно полагаться на MFCC в литературе. Мы пока не видели хорошего сравнения разных фильтров. В наших экспериментах на небольших датасетах заметной разницы не было, на реальных же шумных данных лучше всего себя показывал STFT. Ко всему прочему, у нас не получилось запустить какие-то значимые эксперименты на более новых фильтрах вроде SincNet.

Критика нашего решения


Мы сами, на самом деле, отчасти подвержены тому же, что критикуем. Можно свести основные пункты к следующему:


  • Мы использовали приватные данные для тренировки своих моделей, хотя размер нашего приватного датасета меньше полного размера датасета на порядок;
  • Мы не выложили в open-source наш тренировочный пайплайн (во всяком случае, пока).

Как создать действительно хорошую STT модель


Одни из ключевых составляющих действительно хорошей STT модели:


  • Быстрый инференс;
  • Эффективность с точки зрения количества параметров;
  • Простота в поддержке и возможность доработки;
  • Нетребовательность к ресурсам и вычислительным мощностям, для тренировки достаточно 2-4 видеокарт 1080Ti.

Методология выбора лучшей модели


Самый распространенный подход при выборе лучшей модели — это сравнение качества на паре "эталонных" валидационных выборок. Как мы уже разобрались выше, такой способ не всегда отражает истинное положение вещей (получается лидерборд). Также следует помнить, что при работе с реальными данными не существует идеальной валидационной выборки — важно сравнить качество отдельно для каждого домена.


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


Например, AWS предлагает только NVIDIA Tesla GPU, ориентированные на продакшн, которые в 5-10 раз дороже стандартных пользовательских GPU.

Для максимально эффективной оптимизации модели мы придерживаемся следующего набора методов и допущений:


  • В грубом приближении, качество модели примерно равно [ёмкости модели] x [её производительность]. Как правило, это означает, что нужно оценить следующие две вещи: 1) как быстро модель тренируется и 2) когда кривая функции потерь выходит на плато? Так, если модели не хватает параметров для обучения, функция потерь никогда не выйдет на плато;


    Очевидно, что между ёмкостью модели и скоростью тренировки всегда приходится искать компромисс.


    l_curve


    Современные модели обычно не переобучаются, а сходятся как "L-кривые"

  • Ёмкость модели — функция её сложности. Большие модели, также как и более сложные слои, обучаются гораздо дольше и "капризнее". Поэтому лучше остановить свой выбор на стандартных протестированных модулях с простой параллелизуемой архитектурой;


  • Тесты с полным перебором гиперпараметров требуют много ресурсов. Поэтому лучше а) объединять гиперпараметры в группы; б) сначала менять только те гиперпараметры, которые отвечают за серьезные изменения в логике модели;


  • Сначала мы оптимизируем сеть для того, чтобы сделать её более быстрой и компактной, затем добавляем сложность. На первый взгляд, такой подход кажется не самым эффективным, но последние архитектуры Mobilenet/EfficientNet/FBNet говорят об обратном;


  • Есть два принципа, которые ML исследователи часто упускают из виду: 1) Бритва Оккама: Мы не используем модуль, если не знаем, зачем он нужен и какие у него свойства; 2) Ceteris paribus: если в пайплайне поменялась одна незначительная вещь, необязательно прогонять эксперимент заново, т.к. скорее всего, можно предсказать поведение модели на основе предыдущих тестов;


  • Таким образом, чтобы найти лучшую модель, нужно построить (или найти) хороший пайплайн, провести пару полноценных экспериментов с нуля и уже затем начинать добавлять небольшие изменения. Раз в 10 или 20 экспериментов, когда таких изменений накопится слишком много, можно устроить несколько тестов, чтобы проверить свой пайлайн на наличие "бесполезных" фич.



Теми же приниципами мы руководствовались при оптимизации текущей модели (подробнее об основных идеях можно почитать ниже):


  • Ceteris paribus: Все прочие условия, кроме указанных как объект эксперимента, оставались постоянными. Тренировочная и валидационная выборки, так же, как и железо, не менялись;
  • Сравнение метрик проводилось на валидационном датасете Open STT v0.5-beta;
  • Хотя некоторые изменения и были направлены на улучшение производительности, все эксперименты выполнялись при достаточно высокой нагрузке на железо (не было "узких горлышек" в I/O, обработка данных занимала мало времени, итд итп).

Общий прогресс


models


Иллюстрация достигнутого прогресса — кривые схождения моделей. Если экстраполировать первые модели — экономия вычислительного времени на порядок. Самые "плохие" модели на графике — простые сверточные модели в стиле Wav2Letter. Логи для рекуррентных моделей в стиле DeepSpeech не сохранились, но они были еще в 2-3 раза медленней. GPU часы — это часы тренировки модели, умноженные на число использованных видеокарт. Изменения в архитектуру вносились маленькими шагами, все остальные параметры были неизменны.

Мы начинали наш путь с реализации Deep Speech 2 на Pytorch. В основе этой модели лежат глубокие реккурентные LSTM и GRU сети, не отличающиеся высокой скоростью. График выше наглядно иллюстрирует эффект основных оптимизаций, которые мы добавили в оригинальный пайплайн. Как итог, нам удалось сделать следующее, не снизив при этом качество распознавания:


  • Уменьшить размер модели в ~3-5 раз;
  • Ускорить сходимость в 5-10 раз;
  • Натренировать одну из финальных моделей на двух 1080Ti вместо четырех.

Идея №1: Оптимизировать шаг свёртки.


Подробнее

Можно оптимизировать шаг свертки (всей модели целиком) исходя из соотношения полезных токенов к пустым токенам.


Идея №2: Использовать компактные регуляризованные сети.


Подробнее

Сетки, переоптимизированные под мобильные устройства — не лучший источник архитектурных решений. Однако, из первых поколений таких моделей можно почерпнуть довольно много крутых идей: например, separable convolutions.


Как бонус, небольшие регуляризованные модели легче обучать, так как оверфитятся они заметно меньше. С другой стороны, сходятся такие сети медленнее. Судя по нашему опыту, если веса компактной модели в 3-4 раза меньше весов исходной большой модели, при прочих равных условиях ей потребуется в 3-4 раза больше итераций чтобы дойти до того же уровня качества.


Идея №3: Использовать Byte-Pair-Encoding для токенизации текста.


Подробнее

Тут важно найти компромисс. Акустическая модель с BPE на выходе начинает вести себя как слабая языковая модель и, как следствие, WER (доля ошибок в словах) снижается. Однако, тут есть и оборотная сторона: при увеличении размера BPE словаря есть риск переобучить акустическую модель распознавать только знакомые последовательности. Также стоит учесть, что BPE не в силах заменить полноценную языковую модель, натренированную на большом объёме текстов.
Подробнее с этим и альтернативными подходами можно ознакомиться в статье.


Идея №4: Использовать более эффективный энкодер.


Подробнее

Суть данной идеи в поиске оптимальной архитектуры encoder-decoder. Наш свёрточный энкодер работает так быстро, что мы можем позволить себе гораздо более тяжелый декодер, в том числе state-of-the-art подходы вроде трансформера.


В целом, сети с такой структурой получаются настолько вычислительно эффективными, что им даже не требуются GPU в продакшене. Так, наша акустическая модель может спокойно обрабатывать 500-1000 секунд аудио за одну GPU секунду, и 3-4 секунды аудио за CPU секунду без потерь в качестве распознавания (и это до квантизации, прунинга и некоторых последних оптимизаций). Потенциально, можно получить прирост скорости еще в 2-4 раза, в зависимости от того, какие идеи сработают.


Идея №5: Соблюдать баланс между ёмкостью модели и вычислительными возможностями.


Заголовок спойлера

В общей сложности, оптимизировав разные части модели, нам удалось получить сеть, которая быстро тренируется всего на двух 1080Ti и, в то же время, показывает качество, сравнимое с моделями, требующими 4 или даже 8 GPU для обучения (а в некоторых статьях говорят и про десятки GPU). На наш взгляд, это самое впечатляющее наше достижение на данный момент.


Идея №6: Генерализация и хаки для обучения на нескольких доменах.


Подробнее

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


Для решения этой проблемы лучше всего подходит метод curriculum learning. Грубо говоря, сначала мы показываем сетке простые примеры, затем постепенно переходим к более сложным.


Идея №7. Быстрая постобработка выдачи акустической модели.


Подробнее

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


  • Sequence-to-sequence модели;
  • Beam search с языковой моделью — довольно медленный по сравнению с AM.

В ходе экспериментов нам удалось в разы ускорить нашу реализацию beam search на базе KenLM и достичь идеализированной скорости обработки в 25 секунд аудио на одно CPU ядро.


Бенчмарки и генерализация


Распознаванию речи присуща большая вариативность данных:


  • Уровень шума может варьироваться от студийных записей до телефонных звонков, распознавание которых вызывает трудности даже у людей;
  • Произношение. Люди из разных географических областей могут совершенно иначе произносить одни и те же слова и предложения;
  • Словари/Область применения. Речь с заседания суда и пранки практически не пересекаются в плане используемых "редких" слов;
  • Кодеки для сжатия аудио тоже влияют на качество с точки зрения модели.

Как правило, качество большинства доступных коммерческих решений (за редким исключением) на доменах, которые они не видели при тренировке, оставляет желать лучшего. Интересно, что по поведению модели на широкой области валидацонных сетов можно понять, какие данные были использованы при ее тренировке.


Домены


Чтобы свести предвзятость к минимуму, мы выбрали следующий список доменов разной степени приближенности к реальным данным:


  • Чтение. Самый простой и далекий от реальности домен — люди читают в микрофон. Качество идеальное, словарь не очень большой;
  • Звонки (такси). Реальные звонки в такси. Словарь перекошен в сторону адресов, качество среднее;
  • Публичные выступления. Большое разнообразие кодеков и форматов, большой словарь, довольно высокое качество;
  • Радио. Большое разнообразие кодеков и форматов, большой словарь, среднее качество;
  • Заседания суда. Большой словарь, перекошенный в сторону юридических терминов, среднее качество записи;
  • Аудио книги. Высокое качество речи, монотонные интонации, большой словарь;
  • YouTube. Огромное разнообразие по качеству, формату, словарю. Как бонус — аудио с фоновой музыкой;
  • Звонки (e-commerce). Довольно среднее качество аудио, много очень специфичной лексики;
  • "Yellow pages". Звонки в различные бизнесы с целью бронирования и записи. Низкое и среднее качество, малый словарь, много артефактов телефонии и шумов;
  • Медицинские термины. Стресс-тест моделей. Низкое качество записи, все аудиозаписи содержат "непонятные" обычному человеку термины. Мы убрали все записи, где нет таких терминов;
  • Звонки (пранки). Низкое качество, много обсценной лексики, очень много шумов, очень неровные интонации.

Результаты


Мы протестировали большую часть доменов на следующих системах:


  • Tinkoff (тестировали несколько раз, качество сильно выросло);
  • ЦРТ (звонки, общая модель, медицина, телеком, финансы);
  • Yandex SpeechKit;
  • Google;
  • Kaldi 0.6 / Kaldi 0.7 (сначала через свой билд, а потом через vosk-api);
  • wit.ai;
  • stt.ai;
  • Azure;
  • Speechmatics;
  • Voisi;

Основная метрика в задаче распознавани речи — Word error rate (WER).


Т.к некоторые системы используют денормализацию текста ("первая" -> "1-ая"), мы привели их результаты к общему формату с помощью алгоритма нормализации. Алгоритм неидеален, поэтому истинный WER может отличаться от указанного нами на ~1 процентный пункт.


Большая часть тестов проводилась с использованием публичных АПИ описанных выше сервисов в конце 2019 начале 2020 года. Мы использовали ОДНУ И ТУ ЖЕ нашу модель без разных словарей под каждый домен, за исключением такси. В такси словарь улучшал WER на ~1 процентный пункт. Системы, где был сильный рост по качеству, мы тестировали повторно недавно.

Домен Систем лучше Систем хуже Наш WER Лучший WER Худший WER
Чтение 2 14 10% 3% 29%
Звонки (такси) 0 17 13% 13% 86%
Публичные выступления 0 16 15% 15% 60%
Радио 0 16 18% 18% 70%
Заседания суда 0 7 21% 21% 53%
Аудио книги 4 14 27% 22% 70%
YouTube 1 17 31% 30% 73%
Звонки (e-commerce) 2 13 32% 29% 76%
Yellow pages 1 6 33% 31% 72%
Медицинские термины 1 6 40% 39% 72%
Звонки (пранки) 3 14 41% 38% 85%

Статья и так получается довольно огромной. Если вас интересует более подробная методология и позиции каждой системы на каждом домене, то расширенный вариант сравнения систем вы найдете здесь, а описание методологии сравнения здесь.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (40):

  1. snakers4
    /#21428564

    Ну и конечно не могу удержаться, чтобы не запостить такую картинку, какую изначально хотелось. Но она слишком прекрасна, чтобы быть в статье.


    image

  2. Denuo
    /#21428760 / +1

    Всегда интересовал момент как такие системы распознают речь на «близко к русскому языке»? Например говорит человек, у которого первый язык не русский, в речи встречаются слова из других словах, говорит с акцентом разной силы.

    • snakers4
      /#21428772

      А вы попробуйте демку. Вероятно, если вы задаете такой вопрос, вы говорите на каком-то еще славянском языке?


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


      Сильно портит то, что пост-процессинг настроен именно на русский язык. Но как настроить его на расшифровку другого языка "транслитом" я честно говоря не знаю.


      Украинский точно можно хакнуть натренировав пост-процессинг после ручных словарей перехода, т.к. просто поменяв буквы на их русские "аналоги".

  3. Scratch
    /#21428886 / +1

    А звуковые дорожки из фильмов с субтитрами для обучения не годятся?

    • snakers4
      /#21428906 / +1

      Даже в идеальном мире там слишком мало сигнала, слишком много трафика на скачивание и слишком все разношерстное


      OpenSubtitles тут не поможет, т.к. сабы редко делают на русском к русской речи

  4. al-zatv
    /#21429004 / +1

    Привет! Спасибо за статью. Хорошо, что тесты похожи на нормальные, а не как обычно "мы всех везде победили".
    Есть кое-какие замечания.


    1) По поводу Librispeech. Это не "маленький идеализированный тестсет, вводящий всех в заблуждение". Это задача, показывающая качество, которое может вытащить алгоритм из стандартизированных данных. Когда выходит статья с очередным рекордом на librispeech, автор не хочет сказать "я всех обманул цифрой качества на аудиокнигах". Он говорит "мы, человечество, теперь можем вытаскивать больше качества из таких данных".


    Да, было бы лучше вытаскивать их из более разнообразных данных — но на Западе серьезно относятся к авторским правам. Поэтому собрать корпус лучше — это суперсложная задача. Заметь, Librispeech это не выборка из аудиокниг — это выборка из аудиокниг со свободной лицензией! Вот интересная ссылка насколько у них все с этим серьезно: https://open-education.net/libraries/google-otsifrovala-25-mln-knig-pochemu-ih-nelzya-chitat/


    А без этого корпуса было бы невозможно сравнить алгоритмы. Скажем, кое-где в твоих тестах Яндекс лучше. У них лучше алгоритм или больше данных? Непонятно.

    • snakers4
      /#21429058 / +1

      "я всех обманул цифрой качества на аудиокнигах". Он говорит "мы, человечество, теперь можем вытаскивать больше качества из таких данных"

      Тут как бы согласен, просто у таких вещей очень долгий цикл после которого они начинают быть полезными.
      И выигрыш, к сожалению, получает не общество в целом, а только "толстые коты".
      В случае с CV профита настолько много, что он аж льется через край.


      но на Западе серьезно относятся к авторским правам

      На Западе к ним, равно как и к вами персональным данными относятся — просто никак. Там абсолютно легально DMV продают перс. данные, банки легально все продают налево-направо, список бесконечен. Так что давайте без Запада.
      Скорее там просто есть некий занавес "цивильности" над разборками.


      может вытащить алгоритм из стандартизированных данных

      Это ничего не говорит про генерализацию, про то как получить робастные модели, про то сколько реально нужно данных итд итп
      Грубо говоря — трансформеры на миллиард параметров — зло, сам модуль — добро.
      Раздувать compute можно, как мы видем на примере NLP хайпа, можно почти до безумия.

      • al-zatv
        /#21429188

        Скорее там просто есть некий занавес "цивильности" над разборками.

        +1. Но положение исправляется, как мы видим по ситуации с фейсбуком.


        Это ничего не говорит про генерализацию, про то как получить робастные модели, про то сколько реально нужно данных итд итп

        +1. Надеюсь, академический корпус нужного размера появится.
        Для некоторых частных задач (вроде распознавания в шуме) есть другие корпуса.

    • al-zatv
      /#21429156

      Кстати, ответ на вопрос "почему либриспич такой маленький" очень простой. Я помню, когда он появился, и тогда такой корпус считали большим. Ну или средним.


      Для разбиения корпуса на фразы его автор, Даниэль Повей сотоварищи, использовали модель, обученную на wall street journal, на 40 что-ли часах (ЕМНИП). Если посмотреть README к wsj, там предложено несколько способов получить этот крупный по меркам 90х годов корпус — на магнитных лентах, на пачке компакт-дисков, итд (опять же, ЕМНИП).


      Надеюсь, через пяток лет и корпуса 10к+ часов будут считаться небольшими.

      • snakers4
        /#21429466

        ну собственно за это мы и топим
        никто не помнит имена авторов ImageNet, но все помнят ImageNet


        если сделать OpenSTT на 3+ иностранных языках — то есть небольшая надежда, что FAIR как-то подтянется. они приватно подтянулись — они 100% книжки размечают там сидят в своем огромном датасете (см. их последние публикации — они даже до semi-supervised нормального догадались даже, кек)


        но Dark Forest просветлеет только когда все поймут, что король голый

  5. al-zatv
    /#21429048

    2) Насчет критики индустрии. Что-то справедливо. Что-то нет. То, что снимет большую часть твоей критики, содержится здесь.


    Большинство научных статей, которые мы прочли, как правило, были написаны исследователями из “индустрии” (напр. Google, Baidu, и Facebook).

    На самом деле, публикационно активны ребята из исследовательских подразделений: Google Labs, Facebook AI Research, Baidu-чтототам. Это!!! академические!!! ученые, которые занимаются исследованиями за деньги и с ресурсами IT-гигантов.


    Статьи от практиков, которые делают сервисы этих компаний, изредка встречаются — и с непривычки вызывают удивление "я думал у них там космические корабли бороздят, а в реальности — то же, что и у нас, с поправкой на масштаб".

    • snakers4
      /#21429094 / +1

      Это!!! академические!!! ученые, которые занимаются исследованиями за деньги и с ресурсами IT-гигантов.

      Ну… мы же так и написали?
      Статью переводили на русский и сокращали в 3 раза, но вероятно это при переводе потерялось.


      По статьям видно, что их пишут не практики.


      Статьи от практиков, которые делают сервисы этих компаний, изредка встречаются

      Вот-вот.
      Последняя статья от FAIR неплохая на эту тему.

      • al-zatv
        /#21429216

        Хм, да, и правда так и написано. Просто это в разделе "Критика индустрии", вот я и поторопился.

        • snakers4
          /#21429480

          Даже вы бросились комментировать не дочитав)

          • al-zatv
            /#21429718

            ну если бы это было в разделе «критика академии», у меня бы не было шансов)

  6. al-zatv
    /#21429112

    3) Нельзя доверять открытым или чужим тестам. Даже твоим, при всем уважении, и к сожалению.
    Как только у разработчика системы появляется тест, он может начать выдавать на нем любые результаты от 5% до 95% качества. В зависимости от скромности. Почти любой алгоритм тюнится, а если не тюнится — можно на выходе "подкостылить"
    Ты этого не делаешь, но когда твой конкурент начал этим заниматься — ты проиграл. Если ты видишь на открытом тесте у конкурента +1% качества от твоего, ты не можешь быть уверен, что это честный результат.
    Когда разработчик не хочет никого обмануть, частенько случаются ошибки и самообман. Вроде протечек тестовых данных в трейн. Скажем, записи из именно этой службы такси были в твоем трейне? А у Яндекса? А у Николая Шмырева?
    Ты написал очень хороший текст про "тёмный лес", я после него даже книжку Ли Цисиня прочитал. Вот это именно оно.

    • snakers4
      /#21429178 / +1

      Dark Forest


      Методология тестов описана тут — https://www.silero.ai/stt-quality-metrics/
      Верить или не верить — личное дело каждого


      Ты этого не делаешь, но когда твой конкурент начал этим заниматься — ты проиграл.

      На самом деле даже лгать не надо
      Можно просто взять свой датасет, выбрать реально сложные примеры, затюниться на них, и вуаля


      Если ты видишь на открытом тесте у конкурента +1% качества от твоего, ты не можешь быть уверен, что это честный результат

      Но вот когда я вижу датасет конкурента, который КОНКУРЕНТ приватно мне дал pro bono
      И на нем у него результат хуже, это информация
      Ну или наоборот когда у меня просто нет такого домена вообще и результат не плохой, но не супер секси — вот это информация


      Собственно так и живем


      Про протечки — ну тут скажем так на таком количестве данных надо мыслить доменами, а не ликами


      Почти любой алгоритм тюнится

      И тут я честно заявляю
      Эти все тесты (кроме такси где словарь накинул 1 пп) — ЭТО ОДНА И ТА ЖЕ МОДЕЛЬ
      Да она тюнится на всем чем есть. Но не вал сетах, которые дают внешние люди

      • al-zatv
        /#21429364

        Но вот когда я вижу датасет конкурента, который КОНКУРЕНТ приватно мне дал pro bono
        И на нем у него результат хуже, это информация
        Ну или наоборот когда у меня просто нет такого домена вообще и результат не плохой, но не супер секси — вот это информация


        И тут я честно заявляю
        Эти все тесты (кроме такси где словарь накинул 1 пп) — ЭТО ОДНА И ТА ЖЕ МОДЕЛЬ
        Да она тюнится на всем чем есть. Но не вал сетах, которые дают внешние люди


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

        • snakers4
          /#21429442

          sad but true


          тут я больше скажу
          по сути единственное что работает — когда есть третья сторона, которая


          • выложила и разметила все датасеты
          • поддерживает говно-врапперы над АПИ всех паблик сервисов
          • тестирует раз в месяц
          • постоянно улучшает нормализацию
          • не принимает взятки и не слушает угрозы

          и четвертая сторона, которая мотивированно выносит мозг третьей
          битва гугла и фейсбука тут кстати весьма показательна


          ...


          понятное дело мы все эти пункты сделали приватно


          чтобы вынести это в паблик, нужен инженерный effort, который по сути растворится в воздухе — надо или иметь глубокие карманы или стальные нервы


          а самое большое — нужно сделать это не раз, а нужно быть готовым В ЛЮБОЙ МОМЕНТ ВРЕМЕНИ ответить за каждую строчку кода. как за прод короче. сделать это всем в подарок, или запилить новые фичи? =)


          на практике мы имеем хейт под статьей про open stt v0.5 (я бы еще принял хейт под 1.0, но там я был удивлен), 4 бекеров хостинга датасета т.к. все самые умные, могу продолжить список =)

          • snakers4
            /#21429490

            и да оставлю это на будущее тут


            Да она тюнится на всем чем есть. Но не вал сетах, которые дают внешние люди

            когда данных оч много
            не то чтобы вал сеты вообще играют роль, они скорее нужны для тестов на домене
            скорее играет роль количество и качество разметки в этом домене

    • al-zatv
      /#21429202

      Да, уточню:


      Вроде протечек тестовых данных в трейн. Скажем, записи из именно этой службы такси были в твоем трейне?

      Неаккуратно написал. Я уверен, что протечки именно тестов в трейн у тебя не было. Это правильнее назвать адаптацией на узкий домен.

      • snakers4
        /#21429502

        модель везде одна и та же, она же в демке
        т.е. нет джерримендеринга

  7. al-zatv
    /#21429120

    4) И, еще оно замечание, вернее предложение: перестать называть систему Николая Швырева "Kaldi", это всех путает. Его система называется alpha-cefei или vosk, думаю, Николай сам прояснит.
    В реальности, Kaldi это фреймворк, на котором Николай сделал свою систему. И если продолжать этот подход, то вашу систему надо назвать "PyTorch 1.0", гуглевскую "TensorFlow x.y", а еще нескольких участников твоего сравнения тоже "Kaldi".

    • snakers4
      /#21429136 / +1

      я понимаю, да, что там фреймворк калди, версия 0.7 это релиз модели, проект это цефей, а воск это обертка публичная


      но что-то название прилипло у нас

  8. morozovsk
    /#21429132

    Спасибо за статью.
    Ожидал увидеть сравнение разных систем, но в статье только сравнение в стиле «сравнение обычного стирального порошка и нашего», хорошо что на вашем сайте есть сравнение всех систем между собой.
    Для тех кому лень искать на сайте:

    Результаты по каждому домену отдельно:









  9. serebryakovsergey
    /#21431212

    Одна из рабочих групп MLPerf — Datasets работает над большим публичным набром данных для SST. Сейчас размер примерно 70 тысяч часов, цель — 100 тысяч. Референсная модель RNN transducer, которая (грубая оценка) должна обучиться на 100к часах за 10-30 дней на 64х RTX 2080 картах. У меня недостаточно опыта чтобы прокомментировать качество данных, но вот что используется:

    • Libri Speech & Common Voice ~ 2к часов
    • Некоторые (не помню, что точно значит) данные из интернета ~ 2к часов
    • Синтезированная речь (Текст модели GPT-2 начитан Voicery) ~ 1k часов
    • Аудиокниги (LibriVox) — 65k часов

    У этой группы крутые советники — Kelly Davis, Mark Liberman, Andrew Ng и Dan Povey.

    Пара вопросов:
    1. С точки зрение текущего состояния предметной области и доступных фреймворков, как бы вы оценили Kaldi?
    2. Если порассуждать на тему больших датасетов (> 100k часов) и подходов к построению state-of-the-art моделей (будь то классические DNN/HMM модели или end-to-end) и доступных фреймворков (например, Kaldi), CPU память имеет хоть какое-либо влияние на скорость/качество обучения или нет? Скажем, система с несколькими десятками террабайт RAM и 8-16 GPU которая вместит весь рабочий сет в /dev/shm. Или стандартный размер в 256GB-1TB которые доступны в большинстве серверных машин с 8 картами «just right»?

    • snakers4
      /#21431982

      Одна из рабочих групп MLPerf — Datasets работает над большим публичным набром данных для SST. Сейчас размер примерно 70 тысяч часов, цель — 100 тысяч.

      А где вы нашли про 70к часов?
      Просто ваша ссылка введет на закрытую Google группу.


      Референсная модель RNN transducer, которая (грубая оценка) должна обучиться на 100к часах за 10-30 дней на 64х RTX 2080 картах

      Ну… как обычно =)


      Libri Speech & Common Voice ~ 2к часов
      Некоторые (не помню, что точно значит) данные из интернета ~ 2к часов
      Синтезированная речь (Текст модели GPT-2 начитан Voicery) ~ 1k часов

      Это норм, чтение тоже довольно простой домен


      Аудиокниги (LibriVox) — 65k часов

      В реальности это сильно избыточно, т.к. домен книг не то, чтобы важный или сложный.


      У этой группы крутые советники — Kelly Davis, Mark Liberman, Andrew Ng и Dan Povey.

      Интересно, по ссылке написаны другие люди
      Если они сделают так же как ChexNet, то наверное они только отбросят прогресс в этой области на несколько лет =)


      Про ваши вопросы — прошу простить за прямоту, но звучит так, как будто вы хотите получить бесплатную консультацию. Если вам интересно и у вас есть интересные данные, мы можем обучить модель на ваших данных под ключ, мои контакты есть в миллионе мест в интернете.

  10. serebryakovsergey
    /#21432276

    А где вы нашли про 70к часов?

    Интересно, по ссылке написаны другие люди

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

    Про ваши вопросы — прошу простить за прямоту, но звучит так, как будто вы хотите получить бесплатную консультацию. Если вам интересно и у вас есть интересные данные, мы можем обучить модель на ваших данных под ключ, мои контакты есть в миллионе мест в интернете.

    Упс, мне действительно просто интересно, извиняюсь что не так выразился. Я в прошлом работал над бенчмарками для DL приложений и мы в том числе запускали Kaldi в разных конфигурациях на фишере (2k часов). Когда все данные были в памяти, Kaldi работал пошустрее (понятно почему). Мы даже переписали nnet1 (да, давно было)) что-бы ускорить тренировку на CPU. В те времена Ден Повей говорил, что если ты не исследователь из Google, Baidu и т.п., то с Kaldi легче получить хорошие результаты. Ситуация, судя по всем, поменялась с тех пор.

    • snakers4
      /#21432380

      Про первое — написал им, мне даже уже ответили.
      Может сделаем проект с ними)


      Про второе — отвечу честно, не большой специалист по плюсам, перлу или на чем там еще написан Калди. Мы сами его не рассматривали, т.к. мне показалось, что технологически это тупик.

      • serebryakovsergey
        /#21443464

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

    • al-zatv
      /#21440866

      В те времена Ден Повей говорил, что если ты не исследователь из Google, Baidu и т.п., то с Kaldi легче получить хорошие результаты. Ситуация, судя по всем, поменялась с тех пор.


      Нынче уж nnet3:)
      На мой взгляд, ситуация и изменилась, и не изменилась.
      По-прежнему, калди just works и просто даёт приличный результат.
      В то же время, end2end методы, если их как следует накормить данными, позволяют получать такие же результаты, что гибриды HMM/NN (которые часто делают на калди). Ну, плюс-минус три копейки. Да и данные, чтобы ими накормить end2end'ы, сейчас у многих появляются, а не только у гугля с фейсбуком.
      При этом, есть риск больно вляпаться в не сразу очевидные особенности метода (например: сложность сделать стриминг; сложность сделать персонализацию или адаптировать под тематику; зависимость от длины записи; у некоторых — слабоватое максимально достижимое качество либо прожорливость до gpu и данных. Там в каждой избушке свои погремушки).
      Но и можно получить необычные для гибридов плюшки: возможность сделать удобную для некоторых мобильных девайсов распознающую нейроночку, возможность распознавать OOV (некоторые умеют), применимость опыта из распространенных в cv и nlu тулов. Это все можно и на гибридах, но не из коробки.
      В общем, сейчас можно выбирать.
      IMHO.

      • snakers4
        /#21441592

        По-прежнему, калди just works и просто даёт приличный результат.

        Тут сложно сравнивать яблоки с апельсинами, но на сайте Николая написано, что он мол 10 лет пилит свое решение — ну то есть оно явно уже "зрелое".


        Но судя по тестам — решение довольно неплохо работает на доменах, на которых его тренировали, а вот с генерализацией беда. Но данные там явно брались из широкого числа доменов. То есть получается это проблема подхода в целом? Или дело в чем-то ином? Может Николай ответит.


        В то же время, end2end методы, если их как следует накормить данными, позволяют получать такие же результаты, что гибриды HMM/NN (которые часто делают на калди). Ну, плюс-минус три копейки. Да и данные, чтобы ими накормить end2end'ы, сейчас у многих появляются, а не только у гугля с фейсбуком.

        Ну, фишка в том, что если бездумно кормить e2e, то вряд ли что-то хорошее получится)
        Там еще и часто пишут про 8 — 100 видеокарт.
        Прямо e2e это наверное и правда про 100к часов, но генерализацией там тоже пахнуть не будет.


        сложность сделать стриминг; сложность сделать персонализацию или адаптировать под тематику;

        Почему? У нас проблема со стримингом состоит только в том, что его надо поддерживать, а если оно и так быстро работает ...


        зависимость от длины записи;

        Опять же почему?
        Короткие записи немного грустят, но это логично — мало контекста.


        Но и можно получить необычные для гибридов плюшки: возможность сделать удобную для некоторых мобильных девайсов распознающую нейроночку, возможность распознавать OOV (некоторые умеют), применимость опыта из распространенных в cv и nlu тулов. Это все можно и на гибридах, но не из коробки.

        Я бы сказал это в принципе фишка современных фреймворков.
        Имхо лучше всегда использовать низкоуровневый код на каком-то общем тулките.
        Таким образом вы наследуете весь прогресс человечества в этой области в целом с нулевым костом.

        • al-zatv
          /#21442114

          По первой части твоего комментария, сравнению с калди — все-таки имеет место отождествление решения Николая с фреймворком:) Это забавно.

          Вообще, сравнивать решение Николая с твоим или с решением еще какой-то компании не верно. Потому, что мы не знаем, сколько и каких там данных. А также, для чего эта система делалась, и с какими усилиями.
          И даже если один человек пробует два разных подхода на одинаковых данных и говорит, что один из них отстой — возможно, он что-то просто не осилил.

          Хорошо сравнить именно методы, думаю, сейчас можно только на либриспиче. Несмотря на все недостатки, ничего лучше нет.
          Ну а если нужно сравнение для практических целей — то заказчику надо брать свои данные, делать свой тест и сравнивать коммерческие системы. Иначе как-то никак.

          • snakers4
            /#21442158

            Хорошо сравнить именно методы, думаю, сейчас можно только на либриспиче

            Но никто, почему-то, не сравнивает (буду рад ошибиться).
            И не пишет обзорных статей, в т.ч. сравнивая compute и time-to-market ...


            Вообще, сравнивать решение Николая с твоим или с решением еще какой-то компании не верно. Потому, что мы не знаем, сколько и каких там данных.

            Это так же верно, как и то, что конечному пользователю все эти нюансы глюбоко безразличны.

            • al-zatv
              /#21442308

              Но никто, почему-то, не сравнивает (буду рад ошибиться).
              И не пишет обзорных статей, в т.ч. сравнивая compute и time-to-market ...


              Обзорных статей не видел. Но вот этого достаточно, чтобы ориентироваться: github.com/syhw/wer_are_we. Посмотрев в статью и увидев «x% при обучении на librispeech» (или switchboard/fisher/chime) я уже что-то понимаю. Если там написано «учился на собственном сете» или «учился на сете, который мало кто исследовал» — то информации очень мало.

              Про compute и time2market никто не пишет, да, но это ведь инженерно-коммерческие вопросы, там еще огромная пачка переменных (какой market? на чем compute? какая у тебя орг.структура — можешь дешево тюниться под заказчика или покрываешь всех в среднем? тыщи их).

              Это так же верно, как и то, что конечному пользователю все эти нюансы глюбоко безразличны.


              Ты пишешь вначале про способность фреймворка (даже не метода) к генерализации, потом про решение Николая, а этот коммент про то, что пользователю все равно. Это разные вещи. Резюмируя мою позицию,
              * фреймворки (калди vs pytorch vs tensorflow) — не сравниваем, ни к чему.
              * метод (гибрид/LAS/...) — сравниваем на распространенном в мире бенчмарке.
              * коммерческие решения — на заведомо неизвестном вендору тесте, сделанном из данных заказчика.
              Все остальное — путь к ошибкам.

        • al-zatv
          /#21442202

          По части обсуждения особенностей, я, недостаточно четко выразился.

          При этом, есть риск больно вляпаться в не сразу очевидные особенности метода (например: сложность сделать стриминг; сложность сделать персонализацию или адаптировать под тематику; зависимость от длины записи; у некоторых — слабоватое максимально достижимое качество либо прожорливость до gpu и данных. Там в каждой избушке свои погремушки).


          Я имел в виду, что если кто-то заходит в эту область, он выбирает какой-то «алгоритм» (ну, не совсем алгоритм, а метод что-ли; не знаю, как назвать точнее. скажем, гибрид или классический ctc, или что-то с attention, или rnn-t, или что там еще).
          Если не повезет, у алгоритма будет какая-то из перечисленных выше (или каких-то других) особенностей. Из статей это не всегда очевидно. Придется импровизировать или переделывать. Это долго.
          Вы, может быть, сразу все удачно выбрали. Или переделывали несколько раз. Я не утверждал, что выданный мной список проблем нерешаемый.

          • snakers4
            /#21442596

            Посмотрев в статью и увидев «x% при обучении на librispeech» (или switchboard/fisher/chime) я уже что-то понимаю.

            Там compute может отличаться на 2 порядка
            Это делает такие сравнения даже вредными


            Про compute и time2market никто не пишет, да, но это ведь инженерно-коммерческие вопросы, там еще огромная пачка переменных

            В NLP и CV уже люди дошли, что таки писать все-таки надо про эти вещи
            Хоть как-то


            метод (гибрид/LAS/...) — сравниваем на распространенном в мире бенчмарке.

            Правильно все нормировать по времени и по compute
            В идеале по косту, но это сказка конечно уже


            Из статей это не всегда очевидно. Придется импровизировать или переделывать. Это долго.

            Поэтому всегда лучше выбирать агностик вещи и не зависеть от барина…
            Если конечно есть цель достигнуть результата, а не просто получить строчку в рейтинге

  11. ixomaxip
    /#21435814

    Привет! Спасибо огромное за статью! Наконец-то что-то свежее по русскоязычному STT. Я посмотрел на валидационный сет Open STT v0.5-beta и вопрос: валидиция была на всем сете или на каком-то его подмножестве?

    • snakers4
      /#21435822

      Там как бы 3 датасета, считали метрики на каждом отдельно
      Остальные системы — старались минимум 1-2 часа опрашивать
      Где лимиты не жесткие — опрашивали все целиком. Допустим не очень система из Англии… вообще округляет до 60 секунд)


      Также вот только что сравнили локальную модель с внутренней нормализацией и АПИ с публичной нормализацией — разница меньше 0.5пп WER

      • ixomaxip
        /#21438862

        Спасибо за ответ!
        Ну да, их три, конечно. Это я просто обобщил.