Офлайн распознавание речи. Библиотека Vosk

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

Недавно нам была поставлена задача конвертировать аудиозаписи в текст для дальнейшего анализа. Обязательные условия: офлайн обработка, невысокая требовательность к системным ресурсам, и возможность автоматизации процесса. Мы выбрали Python и библиотеку vosk-api.

Что может Vosk

Vosk – это автономный инструмент для распознавания речи с открытым исходным кодом. Он позволяет использовать модели для 17 языков и диалектов (на момент написания статьи). Модели Vosk малы (50Мб) и позволяют преобразовывать речь в текст «на лету». Существуют и более точные модели. Их размер достигает 2Гб.

Существует реализация библиотеки на Python, Java, NodeJS, C#, C++ и др.

Возможен запуск на ОС Windows, Linux, Android.

Установка

Нам понадобится: python 3.8, библиотеки PyAudio == 0.2.11, vosk == 0.3.1.2

Следующим шагом загружаем модель распознавания. На данный момент для русского доступны две модели:

  • vosk-model-small-ru-0.4 50Мб

  • vosk-model-ru-0.10 2Гб

Большая модель распознает чуть-чуть лучше, а занимает в 40 раз больше места.

После распаковки в каталог модели будет содержать каталоги am, conf, graph и другие.

При появлении ошибки вида:

RuntimeError: Cannot open config file: Z:\Python\Trifonov\vosk\vosk-model-ru-0.10/mfcc.conf

необходимо найти файл в одной из папок модели и переместить в корневой каталог модели. В нашем случае в файл mfcc.conf можно обнаружить в папку conf и переместить его на уровень наверх. С подобной ошибкой я сталкивался на ОС Windows. Для запуска мне пришлось переместить все содержимое папок am, conf, graph, ivector, rmmlm в корень модели.

Использование

Важным параметром является частота дискретизации. Большая модель поддерживает частоту 8000, следовательно, и читать данные с микрофона нужно с такой же частотой

Распознавание «на лету» с микрофона:

from vosk import Model, KaldiRecognizer import os import pyaudio model = Model(r"/home/user/vosk-model-ru-0.10") # полный путь к модели rec = KaldiRecognizer(model, 8000) p = pyaudio.PyAudio() stream = p.open( format=pyaudio.paInt16, channels=1, rate=8000, input=True, frames_per_buffer=8000 ) stream.start_stream() while True: data = stream.read(4000) if len(data) == 0: break print(rec.Result() if rec.AcceptWaveform(data) else rec.PartialResult()) print(rec.FinalResult())

Для распознавания аудио из файлов необходимо конвертировать в формат WAV с частотой дискретизации, поддерживаемый выбранной моделью, в моем случае 8000 Гц.

Листинг кода распознавания аудио файла:

from vosk import Model, KaldiRecognizer import sys import json import os import time import wave model = Model(r"/home/user/vosk-model-ru-0.10") wf = wave.open(r'test.wav', "rb") rec = KaldiRecognizer(model, 8000) result = '' last_n = False while True: data = wf.readframes(8000) if len(data) == 0: break if rec.AcceptWaveform(data): res = json.loads(rec.Result()) if res['text'] != '': result += f" {res['text']}" last_n = False elif not last_n: result += '\n' last_n = True res = json.loads(rec.FinalResult()) result += f" {res['text']}" print(result)

Для примера я распознал новогоднюю речь президента РФ за 2021 год используя большую модель:

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

Качество распознавания очень сильно зависит от шумов в исходном файле. Менее удачный пример распознавания той же моделью (минута из видео c YouTube):

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

Также стоит отметить, что данная библиотека распознавания речи не обучена определять жаргонизмы и ненормативную лексику, но позволяет проводить дообучение моделей на пользователькой выборке. Описание данной функции можно найти в документации: https://alphacephei.com/vosk/adaptation.

Библиотека vosk показала хороший результат при обработке аудио в «тепличных условиях», но при появлении шумов качество распознавания значительно снижается.

На слабом офисном ПК мне удалось обработать запись длиной 4 часа за 20 минут.

0
8 комментариев
Написать комментарий...
DR20

Вы не сказали куда кидать Vosk?

Ответить
Развернуть ветку
NTA
Автор

Vosk можно установить с помощью PyPi, подробная инструкция есть здесь https://alphacephei.com/vosk/install

Ответить
Развернуть ветку
Topik Lite

пожалуйста помогите с ошибкой

raise Exception("Failed to create a model")
Exception: Failed to create a model

Ответить
Развернуть ветку
Ludmila Vybornova

+

Ответить
Развернуть ветку
NTA
Автор

Добрый день! Вам необходимо проверить путь к модели. Если это не принесет результатов - выкладывайте ошибку вместе с кодом, который ее вызывает, и подробным трейсбэком ошибки, будем разбираться :)

Ответить
Развернуть ветку
Dimas PITER

Добрый день! Подскажите пожалуйста что записать в коде чтоб программа запрашивала путь к файлу( пример - ‪E:\Python\1.wav) и после его преобразовывала. Пробовал - wf = wave.open(input("Путь к файлу:")), не получается. выдаёт ошибку:
Traceback (most recent call last):
File "E:\Python\Proba\main.py", line 11, in
wf = wave.open(input("Путь к файлу:"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\79110\AppData\Local\Programs\Python\Python311\Lib\wave.py", line 630, in open
return Wave_read(f)
^^^^^^^^^^^^
File "C:\Users\79110\AppData\Local\Programs\Python\Python311\Lib\wave.py", line 280, in __init__
f = builtins.open(f, 'rb')
^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument: '\u202aE:\\Python\\1.wav'

Ответить
Развернуть ветку
NTA
Автор

Добрый день! Уточним информацию, вернемся с ответом )

Ответить
Развернуть ветку
NTA
Автор

«u202a» - символ юникода обозначающий вставку слева-направо. Считайте строку, а потом извлеките этот символ из строки методом strip.

Решение вашей проблемы описано здесь: https://stackoverflow.com/questions/49267999/remove-u202a-from-python-string

Либо используйте необработанные строки.

Подробнее о необработанных строках тут: https://pythonim.ru/string/neobrabotannaya-stroka-v-python

Ответить
Развернуть ветку
5 комментариев
Раскрывать всегда