Вступление
Доброго времени суток Хабр. Меня зовут Андрей, я занимаюсь разного толка разработкой на C#, сегодня я предлагаю сравнить Vosk и Whisper.
Начало
Перед непосредственным началом сравнения хотелось бы добавить немного контекста и в целом объяснить «что, почему и как», поэтому начнем немного «из далека».
Темы преобразования текста в речь (TTS) и обратного преобразования (STT) сейчас весьма актуальны, особенно если учитывать набирающую обороты популярность нейросетей, в которых оные активно используются, да и сам принцип этих преобразований, в современных решениях, основан как раз таки на нейросетях. А явная тенденция стремительного развития нейросетей, и всего, что с ними связано, за последние пару лет — обосновывает эту актуальность.
И Vosk и Whisper выполняют одну глобальную цель — преобразование речи в текст (STT), для дальнейшей работы с последним. Более подробно про Vosk и Whisper можно почитать тут и тут.
Это разные проекты, несмотря на одну цель, у них разные возможности «из коробки», но тем не менее — в этой статье я постарался их таки сравнить, показать, что у кого есть, кто что имеет и умеет и самое главное — постараться помочь в выборе между ними!
Так как я занимаюсь разработкой на C#, то сравнение между Vosk и Whisper будет в рамках проектов whisper.net (на основе whisper.cpp) для Whispera и vosk‑api (на основе kaldi) для Vosk. Все используемые модели для обоих проектов я разворачивал и запускал локально, обработку производил только на процессоре, поэтому тесты и выводы будут только в рамках запуска и обработки на процессоре.
Что Vosk, что Whisper — могут работать и на видеокарте, и в принципе все эти преобразователи речи в текст (или обратно) стараются запускать именно на видеокарте, так как это дает совершенно другие скорости, нежели запуск на процессоре, НО...
с Vosk возникли некоторые проблемы (так и не удалось собрать проект из исходников и скомпилировать под использование на видеокарте, может позже разберусь, если поможет кто), а у Whisper в принципе все удалось и возможно в следующий раз я сделаю тест между Vosk и Whisper, но уже на видеокарте.
На этом контекста думаю достаточно.
Модели
Что Vosk, что Whisper для своей работы используют модели. Это некие специально натренированные нейросети, которые и занимаются обработкой и преобразованием речи в текст.
У Vosk, глобально, существуют всего два вида моделей (big и small), а у Whisper их прям широкий выбор (tiny, base, small, medium, large). Я специально не указывал остальные виды и версии моделей Whisper, так как их прям реально много.
Так же стоит отметить, что у Whisper модель сразу определяет пунктуацию и заглавные буквы, нежели чем у Vosk. В Vosk для пунктуации надо использовать специальную модель, в этом между моделями Vosk и Whisper принципиальное отличие. Еще стоит упомянуть и то, что модели Whisper могут быть под английский язык, тогда в названии есть «en», либо могут быть мультиязычными. У Vosk в этом плане каждая модель заточена под определенный язык.
Продолжаем про модели.
Чем больше используемая модель, тем точнее, в теории, она преобразует речь в текст и тем медленней она работает, а так же больше занимает ресурсов (место на диске и место в памяти) компьютера.
Дабы постараться уровнять условия, я использовал у Vosk модели:
model‑small‑ru-0.22
model‑ru-0.22 (как некий вариант medium у Whisper, хоть это и не совсем корректно)
model‑ru-0.42
Взяты отсюда
И примерно соответствующие им модели Whisper:
ggml‑base.bin
ggml‑medium.bin
ggml‑large‑v3.bin
Взяты отсюда
Требования к исходному аудиофайлу
Аудио файлы, что подаются «на вход» преобразователей текста в речь, должны соответствовать определённым требованиям.
Для Vosk и Whisper это:
wav формат аудио файла
моно канал
16000 Гц частота дискретизации
16 бит динамический диапазон
продолжительность не более 30 секунд
Насчет некоторых пунктов стоит сделать небольшое пояснение. Vosk может работать и на большей частоте дискретизации (субъективно это дает лучшее распознавание, но прям сознательно я не проверял это), но у Whisper это 16 000 Гц. Whisper может работать на глубине динамического диапазона 8 бит и 32 бита, но у Vosk это только 16 бит.
Так же хочу остановиться и подробнее рассказать о последнем пункте. Насколько я понял, у Whisper аудио файл не может быть продолжительней 30 секунд. Если превысить это значение, то контекст начнется заново (он как бы переполнится) и распознаваться будет звук (слова в аудио файле), что идет дальше, без учета всего предыдущего.
Это связано с размером контекстного окна нейронной сети (в любой модели Whisper), которая лежит в основе. Более подробно об этом можно почитать тут и тут. К слову, вторая ссылка это обсуждения в рамках проекта Whisper Fast, что является перспективным развитием Whisper, но сейчас не об этом.
В целом, изначальное применение Whisper (за Vosk не знаю, но думаю что тоже, хотя он и лишён данного 30 секундного недуга) — это потоковое распознавание, и отсюда такие вот ограничения и особенности. Хотя могу и ошибаться.
Сравнение
В данном сравнении рассматриваются только модели для работы с русским языком.
Для сравнения были созданы аудио файл, который будет подаваться на вход Vosk и Whisper и соответствующий ему эталонный текстовый файл. Текстовый файл нужен для определения качества работы Vosk и Whisper по метрике WER.
Если кратко, то сгенерированный текст (а именно — слова) с выхода STT сверяется с эталонным текстовым файлом и по WER определяется насколько хорошо отработал либо Vosk, либо Whisper.
К данному способу проверки качества работы STT несомненно есть вопросы и лично я бы прям сильно не «убивался» по каждой 0,01% его значения, но тем не менее — нам же нужно как то оценивать качество преобразования? Поэтому и была выбрана эта метрика, которая «по классике» используется в таких случаях, но допускаю, что есть что то лучше и точнее. Так или иначе — некую оценку она дает, а нам, в рамках этой, не очень глубокой, статьи, большего и не надо.
Аудио файл соответствует всем, ранее указанным, требованиям и имеет продолжительность 29 секунд. Далее аудио файл был поделён на 5-ти, 10-ти и 20-ти секундные варианты, так же как и эталонный текстовый файл. И каждый такой вариант был пропущен через 3 модели каждого из проектов.
Таким образом, мы имеем:
5-ти секундный аудио файл и эталонный текстовый (полностью соответствующим этому 5-ти секундному аудио файлу) файл
10-ти секундный аудио файл и эталонный текстовый (полностью соответствующим этому 10-ти секундному аудио файлу) файл
15-ти секундный аудио файл и эталонный текстовый (полностью соответствующим этому 15-ти секундному аудио файлу) файл
29-ти секундный аудио файл и эталонный текстовый (полностью соответствующим этому 29-ти секундному аудио файлу) файл
Аудио файлы подаются на вход преобразователей Whisper и Vosk, в результате работы которых, мы получаем текст, который сравниваем (по метрике WER) с эталонным текстом из текстового файла.
Так же для оценки работы Vosk и Whisper будет использоваться такой параметр как время их обработки (Time).
Таблица результатов сравнения:
Audio file (sec) | Vosk | Whisper | ||||
Time (sec) | Model name | WER (%) | Time (sec) | Model name | WER (%) | |
5 | 0,21 | model-small-ru-0.22 | 26,6 | 2,3 | ggml-base.bin | 40 |
10 | 0,42 | model-small-ru-0.22 | 19,3 | 2,3 | ggml-base.bin | 32,2 |
20 | 0,8 | model-small-ru-0.22 | 25 | 2,8 | ggml-base.bin | 23 |
29 | 1,2 | model-small-ru-0.22 | 33,9 | 3,3 | ggml-base.bin | 37,8 |
5 | 1,8 | model-ru-0.22 | 20 | 22,4 | ggml-medium.bin | 20 |
10 | 3,5 | model-ru-0.22 | 19,3 | 23,2 | ggml-medium.bin | 19,3 |
20 | 6,5 | model-ru-0.22 | 13,4 | 25,5 | ggml-medium.bin | 11,5 |
29 | 9,2 | model-ru-0.22 | 26,2 | 27,4 | ggml-medium.bin | 26,2 |
5 | 1,9 | model-ru-0.42 | 13,3 | 42 | ggml-large-v3.bin | 20 |
10 | 3,4 | model-ru-0.42 | 12,9 | 45,5 | ggml-large-v3.bin | 16,1 |
20 | 6,7 | model-ru-0.42 | 11,5 | 46,7 | ggml-large-v3.bin | 7,6 |
29 | 9 | model-ru-0.42 | 25,2 | 55,3 | ggml-large-v3.bin | 23,3 |
Выводы
По результатам вывод вполне очевиден, но я ни к чему не призываю!)))
И для полноты картины добавлю еще немного контекста, который, возможно что, что то прояснит.
Очевидно что скорость распознавания у Vosk выше, причем примерно на порядок (!), а иногда даже больше, чем у Whisper, при этом качество/точность тоже лучше!
Тут стоит сделать несколько уточнений и оговорок:
В данном сравнении было обычное распознавание, а не стриминговое. Хотя вполне возможно, что там будет такая же «картина».
Сильная разница во времени загрузки моделей. Средняя или большая модель Vosk загружается около 2–3 минут (да, это происходит один раз при инициализации, но все же). Whisper в этом плане значительно быстрее и даже самая большая модель загружается в течении нескольких секунд.
У Vosk любая модель полностью грузится в оперативную память и занимает в ней: размер модели на диске + примерно 30–50% от этого размера. Например, модель model‑ru-0.42, размером в 3,5 Гб на диске, будет занимать около 5,5 Гб оперативной памяти. Whisper, в этом плане, в памяти держит ровно тот размер, что модель занимает на диске или даже чуть меньше. Например, модель ggml‑large‑v3.bin, размером в 3 Гб на диске, в памяти занимает столько же или даже чуть меньше. Именно в связи с этим, на мой взгляд, такая и существенная разница в скорости обработки между этими STT.
Whisper, в момент работы/распознавания загружает процессор примерно на 16–20%, Vosk загружает на 5–8%. Потребляемая оперативная память не повышается ни у Vosk, ни у Whisper.
«За кадром», я сделал проверку Whisper на модели ggml‑tiny.bin и получил практически те же самые результаты, что и для ggml‑base.bin
Возможно я не до конца разобрался в проектах whisper.net (на основе whisper.cpp) для Whispera и vosk‑api (на основе kaldi) для Vosk и там надо что то «докрутить‑довертеть» и результаты будут совершенно другими.
По мимо перевода речи в текст Whisper имеет встроенную функцию перевода текста на другой язык, этого нет у Vosk.
У Vosk есть модель vosk‑model‑spk-0.4, которая, является многоязыковой. Как написано в самом Vosk — «...это модель распознавания говорящего». Как ей пользоваться я нашел лишь на примерах Python. И как я понял — до распознавания голоса нужно сделать векторный слепок (эмбеддинг) эталонного голоса и его можно будет потом сравнивать с векторным слепком, который отправляется при каждом ответе‑распознавании Vosk. Сверка идет по косинусному расстоянию и в его результате можно довольно точно определить говорящего. Сам я не пробовал, но возможность явно крутая.
Да, проверка на одном, хоть и поделённом, статичном исходнике — «такое себе» сравнение. Тут не спорю, но некое понимание мы все равно получили. Именно поэтому в планах сделать два (для большой и маленькой модели) Telegram бота, которые позволят «в живую» оценить работу Vosk и Whisper. Это будет и наглядней и лишено некой синтетики!
P.S.
Говорю сразу — Alpha Cephei мне не «занесла», а могла бы, и это сравнение ни в коем случае не реклама (по крайней мере не целенаправленная) их творения — Vosk. У них есть своя таблица результатов, причем весьма свежая. Верить ей или нет (как и моему сравнению) — выбор каждого.
Более того, Alpha Cephei те еще «жуки»! У них есть свежие (вроде как) модели на HF, но они само собой не подходят под ту версию Vosk, что есть в открытом доступе! А новой версии Vosk нет, и как я понимаю, не будет!)))
Возможно, что кому то будут интересны характеристики компьютера, на котором проводились сравнения из статьи. Поэтому привожу их:
Процессор: Xeon E5 2699V3 (18 ядер, 36 потоков), мат плата: F8 X99, оперативная память: 32Гб (DDR4, 2133МГц, 4-х канал), диск: P400 EVO PCIE 4.0 1TB.
Статья вышла весьма поверхностной и возможно однобокой, но свою цель — «дать пищу для размышления и примерный ориентир, при выборе конкретных решений, для конкретных целей и условий», она выполнила, хотя и осталось «куда копать» и что проверять.