Распознавание речи
Распознавание речи с Python
Сравнение 9 наиболее известных альтернатив.
Технологии распознавания речи стремительно развиваются в течение последних двух лет и переходят из области науки в область инженерии. С ростом популярности голосовых помощников, таких как Alexa, Siri и Google Assistant, некоторые приложения (например, YouTube, Gana, Paytm Travel, My Jio) начинают иметь функции, управляемые голосом. В Slang Labs мы создаем платформу, позволяющую программистам легко дополнять существующие приложения голосовыми функциями.
Автоматическое распознавание речи (ASR) - необходимый первый шаг в обработке голоса. В ASR аудиофайл или речь, произносимая в микрофон, обрабатывается и преобразуется в текст, поэтому она также известна как преобразование речи в текст (STT). Затем этот текст передается в модуль обработки / понимания естественного языка (NLP / NLU) для понимания и извлечения ключевой информации (например, намерений, настроений), после чего предпринимаются соответствующие действия. Существуют также автономные приложения ASR, например расшифровка диктовки или создание субтитров для видео в реальном времени.
Нас интересуют ASR и NLU в целом и их эффективность в цикле преобразования голоса в действие в приложениях, в частности. Наши Android и веб-SDK предоставляют простые API-интерфейсы, подходящие с точки зрения программистов приложений, в то время как платформа Slang берет на себя бремя сложности объединения ASR, NLU и преобразования текста в речь (TTS). Но, естественно, нам интересно узнать о состоянии дел в ASR, NLU и TTS, хотя мы не представляем эти части нашего технологического стека как отдельные предложения SaaS. Это исследование существующих решений ASR - результат этого любопытства.
Сервис против программного обеспечения
Есть две возможности: позвонить в SaaS для преобразования речи в текст в облаке или разместить один из программных пакетов ASR в своем приложении.
Служба - самый простой способ начать. Вы должны подписаться на SaaS и получить ключ / учетные данные. Затем вы готовы использовать его в своем коде либо через конечные точки HTTP, либо через библиотеки на языках программирования по вашему выбору. Однако при достаточно большом использовании он обычно стоит больше денег.
Пакеты программного обеспечения предлагают вам полный контроль при его размещении, а также возможность создавать модели меньшего размера, адаптированные для вашего приложения, и развертывать их на устройстве / периферии без необходимости подключения к сети. Но для обучения и развертывания моделей требуются опыт и предварительные усилия.
Это обратимый выбор. Например, вы можете начать с облачной службы и, при необходимости, перейти к собственному развертыванию программного пакета; и наоборот. Вы можете разработать свой код, чтобы ограничить радиус взрыва такого обращения, а также в случае перехода на другой SaaS или программный пакет.
Пакетная или потоковая передача
Вам необходимо определить, требуется ли вашему приложению пакетная ASR или потоковая ASR.
Пакетный. Если у вас есть аудиозаписи, которые необходимо расшифровать в автономном режиме, пакетная обработка будет более экономичной. В пакетном API аудиофайл передается в качестве параметра, а преобразование речи в текст выполняется за один раз.
Потоковая передача: если вам нужно обрабатывать речь в режиме реального времени (например, в приложениях с голосовым управлением, субтитрах к видео), вам понадобится API потоковой передачи. В случае потокового API он многократно вызывается с доступными фрагментами аудиобуфера. Он может отправлять промежуточные результаты, но окончательный результат доступен в конце.
Все сервисы и программные пакеты имеют пакетные API-интерфейсы, но в некоторых из них на данный момент отсутствуют потоковые API-интерфейсы. Так что, если у вас есть потоковое приложение, это избавляет от некоторых вариантов.
Выбор Python
Большинство речевых сервисов предоставляют библиотеки на популярных языках программирования. В худшем случае вы всегда можете использовать конечные точки HTTP. То же самое и с речевыми пакетами, они имеют привязки на разных языках программирования. В худшем случае вы можете создавать привязки самостоятельно. Таким образом, нет никаких ограничений на использование Python.
Я выбираю Python для этой статьи, потому что большинство речевых облачных сервисов и программных пакетов ASR имеют библиотеки Python. Кроме того, вы можете запускать фрагменты кода статьи с помощью сопутствующего ему Colab notebook в браузере, не требуя установки чего-либо на ваш компьютер.
Один из распространенных вариантов использования - это сбор звука с микрофона и передача буфера (пакетного или потокового) в API распознавания речи. Неизменно в таких транскриберах доступ к микрофону осуществляется через PyAudio, который реализован поверх PortAudio. Но поскольку микрофон недоступен в Colab, мы его упрощаем. Мы будем использовать полный аудиофайл для изучения пакетного API. А для потокового API мы разбиваем аудиофайл на куски и имитируем поток.
Как лучше всего использовать остальную часть статьи
Покрываются следующие услуги и пакеты программного обеспечения.
Услуги:
- Преобразование речи в текст Google
- Речь Microsoft Azure
- IBM Watson Speech to Test
- Amazon Transcribe
- Нюанс
Программное обеспечение:
- КМУ Сфинкс
- Mozilla DeepSpeech
- Kaldi
- Facebook wav2letter
Примеры кода для wav2letter Amazon Transcribe, Nuance, Kaldi и Facebook не предоставляются из-за некоторых особенностей или ограничений (перечисленных в соответствующих разделах). Вместо этого даются ссылки на образцы кода и ресурсы.
В следующем разделе представлены общие служебные функции и тестовые примеры. В последнем разделе рассматривается пакет Python SpeechRecognition
, который обеспечивает абстракцию над пакетным API нескольких сервисов и программных пакетов.
Если вы хотите получить обзор всех услуг и пакетов программного обеспечения, откройте Colab и выполните код, читая этот пост. Если вас интересует только конкретная услуга или пакет, сразу переходите к этому разделу. Но в любом случае поиграйте с кодом в Colab, чтобы лучше изучить его.
Давайте погрузимся в код.
Общая настройка
Загрузите аудиофайлы, которые мы будем использовать для тестирования сервисов и программных пакетов распознавания речи:
$ curl -LO https://github.com/mozilla/DeepSpeech/releases/download/v0.6.0/audio-0.6.0.tar.gz
$ tar -xvzf audio-0.6.0.tar.gz
$ ls -l ./audio/
В нем три аудиофайла. Определите тестовые примеры с необходимыми метаданными:
TESTCASES = [
{
'filename': 'audio/2830-3980-0043.wav',
'text': 'experience proves this',
'encoding': 'LINEAR16',
'lang': 'en-US'
},
{
'filename': 'audio/4507-16021-0012.wav',
'text': 'why should one halt on the way',
'encoding': 'LINEAR16',
'lang': 'en-US'
},
{
'filename': 'audio/8455-210777-0068.wav',
'text': 'your power is sufficient i said',
'encoding': 'LINEAR16',
'lang': 'en-US'
}
]
Также напишите несколько служебных функций. read_wav_file()
принимает путь к аудиофайлу и возвращает байты буфера и частоту дискретизации:
def read_wav_file(filename) -> Tuple[bytes, int]:
with wave.open(filename, 'rb') as w:
rate = w.getframerate()
frames = w.getnframes()
buffer = w.readframes(frames)
return buffer, rate
simulate_stream()
полезен для имитации Steam, чтобы попробовать потоковые API. Обычно используется источник звука, например микрофон. Через определенные промежутки времени микрофон будет генерировать речевой фрагмент, который необходимо передать в потоковый API. Функция simulate_stream()
помогает избежать всей этой сложности и сосредоточиться на API. Требуется аудиобуфер и размер пакета, и генерирует фрагменты этого размера. Обратите внимание на оператор yield buf
в следующем:
def simulate_stream(buffer: bytes, batch_size: int = 4096): buffer_len = len(buffer) offset = 0 while offset < buffer_len: end_offset = offset + batch_size buf = buffer[offset:end_offset] yield buf offset = end_offset
Преобразование речи в текст Google
В Google есть функция преобразования речи в текст как одна из облачных служб Google. Имеет библиотеки на C #, Go, Java, JavaScript, PHP, Python и Ruby. Он поддерживает как пакетный, так и потоковый режимы.
Настраивать
Вам понадобятся ваши Учетные данные Google Cloud. Вам нужно будет настроить переменную среды GOOGLE_APPLICATION_CREDENTIALS
, указывающую на файл cred:
$ export GOOGLE_APPLICATION_CREDENTIALS='/path/to/google/cloud/cred/file/gc-creds.json'
$ ls -l $GOOGLE_APPLICATION_CREDENTIALS
Пакетный API
Использовать пакетный API преобразования речи в текст очень просто. Вам нужно создать SpeechClient
, создать config
со звуковыми метаданными и вызвать recognize()
метод речевого клиента.
from google.cloud import speech_v1
from google.cloud.speech_v1 import enums
def google_batch_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
client = speech_v1.SpeechClient()
config = {
'language_code': lang,
'sample_rate_hertz': rate,
'encoding': enums.RecognitionConfig.AudioEncoding[encoding]
}
audio = {
'content': buffer
}
response = client.recognize(config, audio)
# For bigger audio file, replace previous line with following:
# operation = client.long_running_recognize(config, audio)
# response = operation.result()
for result in response.results:
# First alternative is the most probable result
alternative = result.alternatives[0]
return alternative.transcript
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('google-cloud-batch-stt: "{}"'.format(
google_batch_stt(t['filename'], t['lang'], t['encoding'])
))
Когда вы запустите это, вы увидите текст каждого из файлов аудио-теста на выходе:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
google-cloud-batch-stt: "experience proves this"
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
google-cloud-batch-stt: "why should one halt on the way"
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
google-cloud-batch-stt: "your power is sufficient I said"
Потоковый API
API потоковой передачи Google также довольно прост. Для обработки аудиопотока вы можете многократно вызывать потоковый API с доступным фрагментом звука, и он вернет вам промежуточные результаты:
from google.cloud import speech
from google.cloud.speech import enums
from google.cloud.speech import types
def response_stream_processor(responses):
print('interim results: ')
transcript = ''
num_chars_printed = 0
for response in responses:
if not response.results:
continue
result = response.results[0]
if not result.alternatives:
continue
transcript = result.alternatives[0].transcript
print('{0}final: {1}'.format(
'' if result.is_final else 'not ',
transcript
))
return transcript
def google_streaming_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
client = speech.SpeechClient()
config = types.RecognitionConfig(
encoding=enums.RecognitionConfig.AudioEncoding[encoding],
sample_rate_hertz=rate,
language_code=lang
)
streaming_config = types.StreamingRecognitionConfig(
config=config,
interim_results=True
)
audio_generator = simulate_stream(buffer) # chunk generator
requests = (
types.StreamingRecognizeRequest(audio_content=chunk)
for chunk in audio_generator
)
responses = client.streaming_recognize(
streaming_config, requests
)
# Now, put the transcription responses to use.
return response_stream_processor(responses)
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('google-cloud-streaming-stt: "{}"'.format(
google_streaming_stt(
t['filename'], t['lang'], t['encoding']
)
))
На выходе вы можете видеть, что результат улучшается по мере поступления большего количества звука:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
interim results:
not final: next
not final: iSpy
not final: Aspira
not final: Xperia
not final: Experian
not final: experience
not final: experience proved
not final: experience proves
not final: experience proves the
not final: experience proves that
not final: experience
final: experience proves this
google-cloud-streaming-stt: "experience proves this"
Речь Microsoft Azure
Когнитивные службы Microsoft Azure - это семейство служб ИИ и когнитивных API. Речевые услуги включают услуги Преобразование речи в текст, Преобразование текста в речь, услуги перевода речи.
Настраивать
Установите пакет речи Azure:
$ pip3 install azure-cognitiveservices-speech
Вы можете включить службу речи и найти учетные данные для своей учетной записи на портале Microsoft Azure. Вы можете бесплатно открыть счет здесь. Учетные данные службы:
AZURE_SPEECH_KEY = 'YOUR AZURE SPEECH KEY'
AZURE_SERVICE_REGION = 'YOUR AZURE SERVICE REGION'
Пакетный API
Пакетный API Azure тоже прост. Он принимает конфигурацию и аудиовход и возвращает текст:
import azure.cognitiveservices.speech as speechsdk
def azure_batch_stt(filename: str, lang: str, encoding: str) -> str:
speech_config = speechsdk.SpeechConfig(
subscription=AZURE_SPEECH_KEY,
region=AZURE_SERVICE_REGION
)
audio_input = speechsdk.AudioConfig(filename=filename)
speech_recognizer = speechsdk.SpeechRecognizer(
speech_config=speech_config,
audio_config=audio_input
)
result = speech_recognizer.recognize_once()
return result.text if result.reason == speechsdk.ResultReason.RecognizedSpeech else None
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('azure-batch-stt: "{}"'.format(
azure_batch_stt(t['filename'], t['lang'], t['encoding'])
))
Результат будет следующим:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
azure-batch-stt: "Experience proves this."
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
azure-batch-stt: "Whi should one halt on the way."
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
azure-batch-stt: "Your power is sufficient I said."
Потоковый API
В Azure есть несколько видов потокового API. Создавая различные типы источников звука, можно либо отправить фрагменты звука, либо передать обратный вызов в Azure для получения фрагмента звука. Он запускает несколько типов событий распознавания речи для обратных вызовов. Вот как можно связать push-аудиопоток с генератором аудиопотока:
import time
import azure.cognitiveservices.speech as speechsdk
def azure_streaming_stt(filename: str, lang: str, encoding: str) -> str:
speech_config = speechsdk.SpeechConfig(
subscription=AZURE_SPEECH_KEY,
region=AZURE_SERVICE_REGION
)
stream = speechsdk.audio.PushAudioInputStream()
audio_config = speechsdk.audio.AudioConfig(stream=stream)
speech_recognizer = speechsdk.SpeechRecognizer(
speech_config=speech_config,
audio_config=audio_config
)
# Connect callbacks to the events fired by the speech recognizer
speech_recognizer.recognizing.connect(
lambda evt: print('interim text: "{}"'.format(
evt.result.text
))
)
speech_recognizer.recognized.connect(
lambda evt: print('azure-streaming-stt: "{}"'.format(
evt.result.text
))
)
# start continuous speech recognition
speech_recognizer.start_continuous_recognition()
# push buffer chunks to stream
buffer, rate = read_wav_file(filename)
audio_generator = simulate_stream(buffer)
for chunk in audio_generator:
stream.write(chunk)
time.sleep(0.1) # to give callback a chance against fast loop
# stop continuous speech recognition
stream.close()
time.sleep(0.5) # give chance to VAD to kick in
speech_recognizer.stop_continuous_recognition()
time.sleep(0.5) # Let all callback run
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
azure_streaming_stt(t['filename'], t['lang'], t['encoding'])
Результат для первого тестового примера выглядит так:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
interim text: "experience"
interim text: "experienced"
interim text: "experience"
interim text: "experience proves"
interim text: "experience proves this"
azure-streaming-stt: "Experience proves this."
Речь в текст IBM Watson
IBM Watson Speech to Text - это служба ASR с библиотеками .NET, Go, JavaScript, Python, Ruby, Swift и Unity API, а также конечными точками HTTP. Имеет богатую документацию.
Настраивать
Вам нужно будет зарегистрироваться / войти, получить учетные данные ключа API и URL-адрес службы и заполнить его ниже.
Пакетный API
Пакетный API предсказуемо прост:
import os
from ibm_watson import SpeechToTextV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
def watson_batch_stt(filename: str, lang: str, encoding: str) -> str:
authenticator = IAMAuthenticator(WATSON_API_KEY)
speech_to_text = SpeechToTextV1(authenticator=authenticator)
speech_to_text.set_service_url(WATSON_STT_URL)
with open(filename, 'rb') as audio_file:
response = speech_to_text.recognize(
audio=audio_file,
content_type='audio/{}'.format(
os.path.splitext(filename)[1][1:]
),
model=lang + '_BroadbandModel',
max_alternatives=3,
).get_result()
return response['results'][0]['alternatives'][0]['transcript']
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('watson-batch-stt: "{}"'.format(
watson_batch_stt(t['filename'], t['lang'], t['encoding'])
))
Вот результат:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
watson-batch-stt: "experience proves this "
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
watson-batch-stt: "why should one hold on the way "
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
watson-batch-stt: "your power is sufficient I set "
Потоковый API
API потоковой передачи Watson работает через WebSocket и требует небольшой работы, чтобы все это настроить. Он состоит из следующих этапов:
- Создайте
RecognizeCallback
объект для получения уведомлений и результатов распознавания речи. - Создайте буферную очередь. Аудио фрагменты, созданные микрофоном (или имитатором потока), должны быть записаны в эту очередь, и Watson считывает и потребляет фрагменты.
- Запустить поток, в котором выполняется распознавание речи (вместе с обменом данными через WebSocket).
- Запустите микрофон или симулятор речи, чтобы начать воспроизведение звуковых фрагментов.
- По завершении присоединитесь к потоку распознавания речи (т.е. дождитесь его завершения).
import json
import logging
import os
from queue import Queue
from threading import Thread
import time
from ibm_watson import SpeechToTextV1
from ibm_watson.websocket import RecognizeCallback, AudioSource
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
# Watson websocket prints justs too many debug logs, so disable it
logging.disable(logging.CRITICAL)
# Chunk and buffer size
CHUNK_SIZE = 4096
BUFFER_MAX_ELEMENT = 10
# A callback class to process various streaming STT events
class MyRecognizeCallback(RecognizeCallback):
def __init__(self):
RecognizeCallback.__init__(self)
self.transcript = None
def on_transcription(self, transcript):
# print('transcript: {}'.format(transcript))
pass
def on_connected(self):
# print('Connection was successful')
pass
def on_error(self, error):
# print('Error received: {}'.format(error))
pass
def on_inactivity_timeout(self, error):
# print('Inactivity timeout: {}'.format(error))
pass
def on_listening(self):
# print('Service is listening')
pass
def on_hypothesis(self, hypothesis):
# print('hypothesis: {}'.format(hypothesis))
pass
def on_data(self, data):
self.transcript = data['results'][0]['alternatives'][0]['transcript']
print('{0}final: {1}'.format(
'' if data['results'][0]['final'] else 'not ',
self.transcript
))
def on_close(self):
# print("Connection closed")
pass
def watson_streaming_stt(filename: str, lang: str, encoding: str) -> str:
authenticator = IAMAuthenticator(WATSON_API_KEY)
speech_to_text = SpeechToTextV1(authenticator=authenticator)
speech_to_text.set_service_url(WATSON_STT_URL)
# Make watson audio source fed by a buffer queue
buffer_queue = Queue(maxsize=BUFFER_MAX_ELEMENT)
audio_source = AudioSource(buffer_queue, True, True)
# Callback object
mycallback = MyRecognizeCallback()
# Read the file
buffer, rate = read_wav_file(filename)
# Start Speech-to-Text recognition thread
stt_stream_thread = Thread(
target=speech_to_text.recognize_using_websocket,
kwargs={
'audio': audio_source,
'content_type': 'audio/l16; rate={}'.format(rate),
'recognize_callback': mycallback,
'interim_results': True
}
)
stt_stream_thread.start()
# Simulation audio stream by breaking file into chunks and filling buffer queue
audio_generator = simulate_stream(buffer, CHUNK_SIZE)
for chunk in audio_generator:
buffer_queue.put(chunk)
time.sleep(0.5) # give a chance to callback
# Close the audio feed and wait for STTT thread to complete
audio_source.completed_recording()
stt_stream_thread.join()
# send final result
return mycallback.transcript
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('watson-cloud-streaming-stt: "{}"'.format(
watson_streaming_stt(t['filename'], t['lang'], t['encoding'])
))
Произведено продукции:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
not final: X.
not final: experts
not final: experience
not final: experienced
not final: experience prove
not final: experience proves
not final: experience proves that
not final: experience proves this
final: experience proves this
watson-cloud-streaming-stt: "experience proves this "
Amazon Transcribe
Amazon Transcribe - это облачный сервис AWS для преобразования речи в текст с библиотеками на C #, Go, Java, JavaScript, PHP, Python и Ruby. Он имеет пакетный API преобразования речи в текст (также доступный как командная строка), но требует, чтобы аудиофайл находился либо в сегменте S3, либо был доступен через HTTP. Также есть потоковый API на WebSocket и HTTP / 2. Вот пример с AWS Java SDK, но без привязок Python (конечно, можно использовать библиотеку сокетов Python, но для этого потребуется попасть в низкоуровневое кодирование потока событий).
API-интерфейсы Amazon Transcribe Python в настоящее время не поддерживают сценарии использования, описанные в этой статье, поэтому примеры кода здесь не включены.
Нюанс
Nuance, скорее всего, является старейшим коммерческим продуктом для распознавания речи, даже настроенным для различных областей и отраслей. У них есть привязки Python для службы распознавания речи. Вот образец кода в их репозитории на GitHub.
Я не мог придумать способ создать учетную запись разработчика. Я надеюсь, что есть способ получить ограниченный период бесплатных пробных кредитов, как и на другие продукты, и получить учетные данные, необходимые для доступа к услугам.
КМУ Сфинкс
CMUSphinx существует уже довольно давно и адаптируется к достижениям в технологиях ASR. PocketSphinx - пакет Python для преобразования речи в текст.
Настраивать
Сначала установите swig. В macOS вы можете установить, используя brew
:
$ brew install swig
$ swig -version
В Linux вы можете использовать apt-get
:
$ apt-get install -y swig libpulse-dev
$ swig -version
А затем установите pocketsphinx
с помощью pip:
$ pip3 install pocketsphinx
$ pip3 list | grep pocketsphinx
Создать объект декодера
Независимо от того, используете ли вы пакетный или потоковый API, вам потребуется объект декодера:
import pocketsphinx
import os
MODELDIR = os.path.join(os.path.dirname(pocketsphinx.__file__), 'model')
config = pocketsphinx.Decoder.default_config()
config.set_string('-hmm', os.path.join(MODELDIR, 'en-us'))
config.set_string('-lm', os.path.join(MODELDIR, 'en-us.lm.bin'))
config.set_string('-dict', os.path.join(MODELDIR, 'cmudict-en-us.dict'))
decoder = pocketsphinx.Decoder(config)
Пакетный API
Пакетный API ожидаемо прост, всего пара строк кода:
def sphinx_batch_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
decoder.start_utt()
decoder.process_raw(buffer, False, False)
decoder.end_utt()
hypothesis = decoder.hyp()
return hypothesis.hypstr
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text'])
)
print('sphinx-batch-stt: "{}"'.format(
sphinx_batch_stt(t['filename'], t['lang'], t['encoding'])
))
И вы увидите уже знакомый результат:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
sphinx-batch-stt: "experience proves this"
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
sphinx-batch-stt: "why should one hold on the way"
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
sphinx-batch-stt: "your paris sufficient i said"
Обратите внимание на ошибки в транскрипции. Чем больше обучающих данных, тем лучше.
Потоковый API
API-интерфейсы потоковой передачи также довольно просты, но для получения промежуточных результатов нет никакого крючка:
def sphinx_streaming_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
audio_generator = simulate_stream(buffer)
decoder.start_utt()
for chunk in audio_generator:
decoder.process_raw(chunk, False, False)
decoder.end_utt()
hypothesis = decoder.hyp()
return hypothesis.hypstr
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('sphinx-streaming-stt: "{}"'.format(
sphinx_streaming_stt(t['filename'], t['lang'], t['encoding'])
))
Mozilla DeepSpeech
Mozilla выпустила программный пакет DeepSpeech 0.6 в декабре 2019 года с API-интерфейсами на языках C, Java, .NET, Python и JavaScript, включая поддержку моделей TensorFlow Lite для использования на периферийных устройствах.
Настраивать
Вы можете установить DeepSpeech с помощью pip (сделайте это deepspeech-gpu==0.6.0
, если вы хотите использовать графический процессор в среде выполнения Colab или на своем компьютере):
$ pip install deepspeech==0.6.0
Загрузите и разархивируйте модели (это займет некоторое время):
$ curl -LO https://github.com/mozilla/DeepSpeech/releases/download/v0.6.0/deepspeech-0.6.0-models.tar.gz
$ tar -xvzf deepspeech-0.6.0-models.tar.gz
$ ls -l ./deepspeech-0.6.0-models/
Убедитесь, что все работает. Изучите вывод последних трех команд, и вы увидите результаты «меньше опыта», «почему нужно останавливаться на пути» и «ваш мощности достаточно, я сказал » соответственно. У вас все настроено.
$ deepspeech --model deepspeech-0.6.0-models/output_graph.pb --lm deepspeech-0.6.0-models/lm.binary --trie ./deepspeech-0.6.0-models/trie --audio ./audio/2830-3980-0043.wav
$ deepspeech --model deepspeech-0.6.0-models/output_graph.pb --lm deepspeech-0.6.0-models/lm.binary --trie ./deepspeech-0.6.0-models/trie --audio ./audio/4507-16021-0012.wav
$ deepspeech --model deepspeech-0.6.0-models/output_graph.pb --lm deepspeech-0.6.0-models/lm.binary --trie ./deepspeech-0.6.0-models/trie --audio ./audio/8455-210777-0068.wav
Создать объект модели
Первый шаг - прочитать файлы модели и создать объект модели DeepSpeech.
import deepspeech
model_file_path = 'deepspeech-0.6.0-models/output_graph.pbmm'
beam_width = 500
model = deepspeech.Model(model_file_path, beam_width)
# Add language model for better accuracy
lm_file_path = 'deepspeech-0.6.0-models/lm.binary'
trie_file_path = 'deepspeech-0.6.0-models/trie'
lm_alpha = 0.75
lm_beta = 1.85
model.enableDecoderWithLM(lm_file_path, trie_file_path, lm_alpha, lm_beta)
Пакетный API
Для пакетного преобразования речи в текст требуется всего пара строк кода:
import numpy as np
def deepspeech_batch_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
data16 = np.frombuffer(buffer, dtype=np.int16)
return model.stt(data16)
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('deepspeech-batch-stt: "{}"'.format(
deepspeech_batch_stt(t['filename'], t['lang'], t['encoding'])
))
Вывод:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
deepspeech-batch-stt: "experience proof less"
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
deepspeech-batch-stt: "why should one halt on the way"
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
deepspeech-batch-stt: "your power is sufficient i said"
Потоковый API
API потоковой передачи DeepSpeech требует создания контекста потока и многократного его использования для подачи фрагментов звука:
def deepspeech_streaming_stt(filename: str, lang: str, encoding: str) -> str:
buffer, rate = read_wav_file(filename)
audio_generator = simulate_stream(buffer)
# Create stream
context = model.createStream()
text = ''
for chunk in audio_generator:
data16 = np.frombuffer(chunk, dtype=np.int16)
# feed stream of chunks
model.feedAudioContent(context, data16)
interim_text = model.intermediateDecode(context)
if interim_text != text:
text = interim_text
print('inetrim text: {}'.format(text))
# get final resut and close stream
text = model.finishStream(context)
return text
# Run tests
for t in TESTCASES:
print('\naudio file="{0}" expected text="{1}"'.format(
t['filename'], t['text']
))
print('deepspeech-streaming-stt: "{}"'.format(
deepspeech_streaming_stt(t['filename'], t['lang'], t['encoding'])
))
DeepSpeech возвращает промежуточные результаты:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
inetrim text: i
inetrim text: e
inetrim text: experi en
inetrim text: experience pro
inetrim text: experience proof les
deepspeech-streaming-stt: "experience proof less"
Kaldi
Kaldi - очень популярный программный инструментарий для распознавания речи среди исследовательского сообщества. Он предназначен для экспериментов с различными исследовательскими идеями и возможностями. Он имеет богатую коллекцию различных возможных техник и альтернатив. Кривая обучения более крутая по сравнению с другими альтернативами, обсуждаемыми в лаборатории кода.
PyKaldi предоставляет привязки Python. Пожалуйста, взгляните на README их репозитория на GitHub.
Готового к использованию пакета PyPI для предварительной сборки не существует, и вы должны собрать его либо из исходного кода, либо из Conda. Ни один из вариантов не подходит для среды Colab.
Facebook wav2letter
Facebook выпустил wav2letter @where в январе 2020 года. Он может похвастаться полностью сверточной (CNN) акустической моделью вместо рекуррентной нейронной сети (RNN), которая используется в других решениях. Очень многообещающий, в том числе для использования в периферийных устройствах. Он имеет привязки Python для своей структуры вывода.
Как и Kaldi, он также не предоставляет пакет PyPI, и его необходимо собирать и устанавливать из исходников.
Пакет Python SpeechRecognition
Пакет SpeechRecognition предоставляет красивую абстракцию над несколькими решениями. Мы уже исследовали использование сервиса Google и CMU Sphinxpackage. Теперь мы будем использовать их через API пакета SpeechRecognition. Его можно установить с помощью pip:
Пакетный API
SpeechRecognition имеет только пакетный API. Первый шаг для создания аудиозаписи из файла или с микрофона, а второй шаг - вызов функции recognize_<speech engine name>
. В настоящее время у него есть API для CMU Sphinx, Google, Microsoft, IBM, Houndify и Wit. Давайте оформим заказ, используя один облачный сервис (Google) и один программный пакет (Sphinx) через абстракцию SpeechRecognition.
import speech_recognition as sr
from enum import Enum, unique
@unique
class ASREngine(Enum):
sphinx = 0
google = 1
def speech_to_text(filename: str, engine: ASREngine, language: str, show_all: bool = False) -> str:
r = sr.Recognizer()
with sr.AudioFile(filename) as source:
audio = r.record(source)
asr_functions = {
ASREngine.sphinx: r.recognize_sphinx,
ASREngine.google: r.recognize_google,
}
response = asr_functions[engine](audio, language=language, show_all=show_all)
return response
# Run tests
for t in TESTCASES:
filename = t['filename']
text = t['text']
lang = t['lang']
print('\naudio file="{0}" expected text="{1}"'.format(
filename, text
))
for asr_engine in ASREngine:
try:
response = speech_to_text(filename, asr_engine, language=lang)
print('{0}: "{1}"'.format(asr_engine.name, response))
except sr.UnknownValueError:
print('{0} could not understand audio'.format(
asr_engine.name
))
except sr.RequestError as e:
print('{0} error: {0}'.format(asr_engine.name, e))
Вывод:
audio file="audio/2830-3980-0043.wav" expected text="experience proves this"
sphinx: "experience proves that"
google: "experience proves this"
audio file="audio/4507-16021-0012.wav" expected text="why should one halt on the way"
sphinx: "why should one hold on the way"
google: "why should one halt on the way"
audio file="audio/8455-210777-0068.wav" expected text="your power is sufficient i said"
sphinx: "your paris official said"
google: "your power is sufficient I said"
API для других провайдеров
Для других провайдеров распознавания речи вам нужно будет создать учетные данные API, которые вы должны передать функции recognize_<speech engine name>
, вы можете проверить этот пример.
Он также имеет красивую абстракцию для микрофона, реализованную через PyAudio / PortAudio. Ознакомьтесь с примерами захвата входного сигнала с микрофона пакетно и непрерывно в фоновом режиме.
Хотите написать расшифровщик Python, который преобразует ввод с микрофона в текст? Проверь это:
Если вам это понравилось, пожалуйста:
Изначально опубликовано в Блоге Slang Labs.