Продолжаем серию статей по практическому применению Python. Попробуем решить задачу транскрибации записи речи из аудио в текст. Это не rocket science :) Такие задачи уже решаются продуктами на рынке и довольно неплохо (Сбер, Yandex). Моя цель – не конкурировать, а показать, что такие серьезные задачи можно начать решать с минимальным порогом входа: достаточно базовых знаний в программировании на Python.
Направление естественного анализа речи – целая область в NLP (Natural Language Processing). Дело в том, что компьютер очень быстро считает, но вот с пониманием смысла у него проблемы. Программа может быстро подсчитать количество слов в произведении «Война и мир», но с анализом смысла будут проблемы. А вот NLP пытается докопаться до смыслов.
Прежде чем анализировать речь, ее необходимо перевести в текст, а уже его подвергать анализу. Напрямую анализировать аудио – такого я не встречал (поправьте, если есть реализации, очень интересно посмотреть). В этой статье мы как раз займемся расшифровкой аудио в текст.
Для работы нам понадобится Python 3.8+, библиотека для распознавания речи – Vosk. Немного про библиотеку Vosk:
- Поддерживает 20+ языков и диалектов.
- Работает без доступа к сети даже на мобильных устройствах – Raspberry Pi, Android, iOS.
- Устанавливается с помощью простой команды pip3 install vosk без дополнительных шагов.
- Сделана для потоковой обработки звука, что позволяет реализовать мгновенную реакцию на команды.
- Поддерживает несколько популярных языков программирования – Java, C#, Javascript, Python.
- Позволяет быстро настраивать словарь распознавания для улучшения точности распознавания.
- Позволяет идентифицировать говорящего.
- Библиотека активно контрибьютится и поддерживается.
Перевод аудио в текст
Чтобы реализовать транскрибацию из аудио в текст, нам необходимо решить следующие задачи:
- Вытащить части речи из аудио.
- Расставить пробелы на паузах между частями речи.
- Добавить пунктуацию в текст.
Все действия буду делать на машине с Ubuntu 20 (Python 3.8) со следующей конфигурацией:
- CPU 2vCPU.
- RAM 12GB.
- HDD 20GB.
Причина использования такого количества RAM в том, что мы делаем распознавание на универсальной модели, то есть модели размером 50 Мб, которая требует в разы меньше оперативной памяти в работе, чем полноценная модель. Правда, качество распознавания в этом случае уменьшится.
Создаем директорию speech
:
mkdir speech
cd speech
Далее необходимо поставить зависимости для Python:
apt install python3-pip
pip3 install ffmpeg
pip3 install pydub
pip3 install vosk
pip3 install torch
pip3 install transformers
Также скачиваем и распаковываем модель для распознавания русской речи, выполнив команды:
curl -o ./model.zip https://alphacephei.com/vosk/models/vosk-model-ru-0.22.zip
unzip model.zip
mv vosk-model-ru-0.22/ model
rm -rf model.zip
В результате этих действий мы скопировали к себе модель, разархивировали ее и переименовали директорию. Также удалили скачанный архив. Всё-таки он весит 1.5 Гб. Для расстановки пунктуации делаем похожие действия: скачиваем еще одну модель весом 1.5 Гб.
curl -o recasepunc.zip https://alphacephei.com/vosk/models/vosk-recasepunc-ru-0.22.zip
unzip recasepunc.zip
mv vosk-recasepunc-ru-0.22/ recasepunc
rm -rf recasepunc.zip
Код файла app.py
, который выполняет перевод аудио в текст.
from vosk import Model, KaldiRecognizer, SetLogLevel
from pydub import AudioSegment
import subprocess
import json
import os
SetLogLevel(0)
# Проверяем наличие модели
if not os.path.exists("model"):
print ("Please download the model from https://alphacephei.com/vosk/models and unpack as 'model' in the current folder.")
exit (1)
# Устанавливаем Frame Rate
FRAME_RATE = 16000
CHANNELS=1
model = Model("model")
rec = KaldiRecognizer(model, FRAME_RATE)
rec.SetWords(True)
# Используя библиотеку pydub делаем предобработку аудио
mp3 = AudioSegment.from_mp3('Song.mp3')
mp3 = mp3.set_channels(CHANNELS)
mp3 = mp3.set_frame_rate(FRAME_RATE)
# Преобразуем вывод в json
rec.AcceptWaveform(mp3.raw_data)
result = rec.Result()
text = json.loads(result)["text"]
# Добавляем пунктуацию
cased = subprocess.check_output('python3 recasepunc/recasepunc.py predict recasepunc/checkpoint', shell=True, text=True, input=text)
# Записываем результат в файл "data.txt"
with open('data.txt', 'w') as f:
json.dump(cased, f, ensure_ascii=False, indent=4)
Последний штрих – разместить файл Song.mp3
в нашей директории с исполняемым файлом app.py
. Затем запускаем app.py
. В результате наша программа обработает файл .mp3
и на основе натренированных моделей из библиотеки Vosk сделает транскрибацию аудио в текст с сохранением результата в файл data.txt
.
Наша реализация решает поставленные задачи в начале статьи. Но это скорее MVP, чем продуманное решение для продакшена. Если мы начнем углубляться, то перед нами встанут задачи обработки больших аудио (от часа и более), организации многопоточности, балансировки и горизонтального масштабирования и много чего интересного. Библиотека VOSK позволяет со всем этим справиться. Но это уже другая история :)
Комментарии
Добрый день.
ОС Linux Mint 21.1 Cinnamon 5.6.8 Результат отсутствует.
Выдает: LOG (VoskAPI:ReadDataFiles():model.cc:213) Decoding params beam=13 max-active=7000 lattice-beam=6 LOG (VoskAPI:ReadDataFiles():model.cc:216) Silence phones 1:2:3:4:5:6:7:8:9:10 LOG (VoskAPI:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 1 orphan nodes. LOG (VoskAPI:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 2 orphan components. LOG (VoskAPI:Collapse():nnet-utils.cc:1488) Added 1 components, removed 2 LOG (VoskAPI:ReadDataFiles():model.cc:248) Loading i-vector extractor from model/ivector/final.ie LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:204) Done. LOG (VoskAPI:ReadDataFiles():model.cc:279) Loading HCLG from model/graph/HCLG.fst LOG (VoskAPI:ReadDataFiles():model.cc:297) Loading words from model/graph/words.txt LOG (VoskAPI:ReadDataFiles():model.cc:308) Loading winfo model/graph/phones/word_boundary.int LOG (VoskAPI:ReadDataFiles():model.cc:315) Loading subtract G.fst model from model/rescore/G.fst LOG (VoskAPI:ReadDataFiles():model.cc:317) Loading CARPA model from model/rescore/G.carpa LOG (VoskAPI:ReadDataFiles():model.cc:323) Loading RNNLM model from model/rnnlm/final.raw Убито
В папке файл data.txt отсутствует. Че не так? Спасибо!
Не получается выполнить в jupyter notebook вот такая ошибка \AppData\Local\Temp\ipykernel_14808\3286289763.py in 19 CHANNELS = 1 20 ---> 21 model = Model(model_path) 22 rec = KaldiRecognizer(model, FRAME_RATE) 23 rec.SetWords(True)
E:\anaconda\envs\ML_Udemy\lib\site-packages\vosk__init.py in init__(self, model_path, model_name, lang) 55 self._handle = _c.vosk_model_new(model_path.encode("utf-8")) 56 if self._handle == _ffi.NULL: ---> 57 raise Exception("Failed to create a model") 58 59 def del(self):
Exception: Failed to create a model
Вот логи [I 17:56:58.969 NotebookApp] Saving file at /Transcribition.ipynb LOG (VoskAPI:ReadDataFiles():model.cc:213) Decoding params beam=13 max-active=7000 lattice-beam=6 LOG (VoskAPI:ReadDataFiles():model.cc:216) Silence phones 1:2:3:4:5:6:7:8:9:10 LOG (VoskAPI:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 1 orphan nodes. LOG (VoskAPI:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 2 orphan components. LOG (VoskAPI:Collapse():nnet-utils.cc:1488) Added 1 components, removed 2 LOG (VoskAPI:ReadDataFiles():model.cc:248) Loading i-vector extractor from E:/work/model/ivector/final.ie LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:204) Done. LOG (VoskAPI:ReadDataFiles():model.cc:279) Loading HCLG from E:/work/model/graph/HCLG.fst LOG (VoskAPI:ReadDataFiles():model.cc:297) Loading words from E:/work/model/graph/words.txt LOG (VoskAPI:ReadDataFiles():model.cc:308) Loading winfo E:/work/model/graph/phones/word_boundary.int LOG (VoskAPI:ReadDataFiles():model.cc:315) Loading subtract G.fst model from E:/work/model/rescore/G.fst LOG (VoskAPI:ReadDataFiles():model.cc:317) Loading CARPA model from E:/work/model/rescore/G.carpa LOG (VoskAPI:ReadDataFiles():model.cc:323) Loading RNNLM model from E:/work/model/rnnlm/final.raw [I 18:07:49.393 NotebookApp] Saving file at /Transcribition.ipynb
Вот что в итоге...
LOG (VoskAPI:ReadDataFiles():model.cc:213) Decoding params beam=13 max-active=7000 lattice-beam=6 LOG (VoskAPI:ReadDataFiles():model.cc:216) Silence phones 1:2:3:4:5:6:7:8:9:10 LOG (VoskAPI:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 1 orphan nodes. LOG (VoskAPI:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 2 orphan components. LOG (VoskAPI:Collapse():nnet-utils.cc:1488) Added 1 components, removed 2 LOG (VoskAPI:ReadDataFiles():model.cc:248) Loading i-vector extractor from ./model/ivector/final.ie LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:204) Done. LOG (VoskAPI:ReadDataFiles():model.cc:279) Loading HCLG from ./model/graph/HCLG.fst LOG (VoskAPI:ReadDataFiles():model.cc:297) Loading words from ./model/graph/words.txt LOG (VoskAPI:ReadDataFiles():model.cc:308) Loading winfo ./model/graph/phones/word_boundary.int LOG (VoskAPI:ReadDataFiles():model.cc:315) Loading subtract G.fst model from ./model/rescore/G.fst LOG (VoskAPI:ReadDataFiles():model.cc:317) Loading CARPA model from ./model/rescore/G.carpa LOG (VoskAPI:ReadDataFiles():model.cc:323) Loading RNNLM model from ./model/rnnlm/final.raw Traceback (most recent call last): File "c:\Users\kolde\Documents\TtS\main.py", line 21, in model = Model("./model") File "C:\Users\kolde\Documents\TtS\venv\lib\site-packages\vosk__init.py", line 57, in init__ raise Exception("Failed to create a model") Exception: Failed to create a model
Command 'recasepunc/recasepunc.py predict recasepunc/checkpoint' returned non-zero exit status 1. куда копать с этой ошибкой, код исполнен на винде
Была такая же проблема, решилось установкой конкретной версии transformers:
pip install transformers==4.16.2
Всем привет Подскажите вот такая ошибка появляется
Traceback (most recent call last): File "/Users/dmitribernackij/pythonProject/main_2.py", line 33, in cased = subprocess.check_output('python3 recasepunc/recasepunc.py predict recasepunc/checkpoint', shell=True, text=True, input=text) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 466, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 571, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command 'python3 recasepunc/recasepunc.py predict recasepunc/checkpoint' returned non-zero exit status 2.
Process finished with exit code 1
Вам нужно скачать vosk-recasepunc-ru-0.22 и переименовать файл в recasepunc там все прописано в статье
Vosk хорошая библиотека, но есть лучшее решение для преобразования аудио записей в текст это библиотека Whisper. Wisper умеет определять язык и распознавать речь в песнях и в других шумных записях. Ссылка на библиотеку https://github.com/openai/whisper
Привет, интересный референс. Гляну обязательно.
У Вас получилось сделать diarization? идет звонок, нужно раскидать реплики по участникам разговора. в итоге получается Участник 2: Обращаем ваше внимание, разговор может быть записан.... тут куча текста Хорошо. Спасибо. Участник 1: Участник 2: Участник 1: Участник 2: Участник 0:
После строки mp3 = AudioSegment.from_mp3('Song.mp3') выдаёт ошибку hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] Не удается найти указанный файл
Такая же ошибка, вы нашли решение?
Вы забыли указать pip install ffprobe
или как вариант поставить локально пакет ffmpeg. apt install ffmpeg