Время прочтения: 4 мин.

Недавно мне была поставлена задача конвертировать аудиозаписи в текст для дальнейшего анализа. Обязательные условия: офлайн обработка, невысокая требовательность к системным ресурсам, и возможность автоматизации процесса. Я выбрал 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):

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

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

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

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