Создаем проект по распознаванию речи в Python

Узнайте, как выполнять автоматическое распознавание речи (ASR), используя API и/или непосредственно выполняя вывод Whisper на в Python.

Распознавание речи – это технология, позволяющая преобразовывать человеческую речь в цифровой текст. В этом руководстве вы узнаете, как выполнить автоматическое распознавание речи с помощью Python.

В этом практическом руководстве, вы научитесь использовать следующее:

  • Библиотека SpeechRecognition: Эта библиотека содержит несколько движков и API, как онлайн, так и офлайн. Мы будем использовать Google Speech Recognition, так как он быстрее запускается и не требует ключа API. У нас есть отдельный учебник по этому вопросу.
  • API Whisper: Whisper – это надежная модель распознавания речи общего назначения, выпущенная OpenAI. API стал доступен 1 марта 2023 года. Мы будем использовать API OpenAI для распознавания речи.
  • Работать с Whisper, которая имеет открытый исходный код. Поэтому мы можем напрямую использовать наши вычислительные ресурсы для выполнения ASR. У нас будет гибкость и возможность выбора, какой размер модели Whisper использовать. 

С помощью библиотеки распознавания речи

Библиотека SpeechRecognition предлагает множество движков для транскрибирования, например, Google Speech Recognition, и именно его мы будем использовать.

Прежде чем приступить к работе, давайте установим необходимые библиотеки:

$ pip install SpeechRecognition pydub

Откройте новый файл с именем speechrecognition.py и добавьте следующее:

# importing libraries 
import speech_recognition as sr 
import os 
from pydub import AudioSegment
from pydub.silence import split_on_silence

# create a speech recognition object
r = sr.Recognizer()

Приведенная ниже функция загружает аудиофайл, выполняет распознавание речи и возвращает текст:

# a function to recognize speech in the audio file
# so that we don't repeat ourselves in in other functions
def transcribe_audio(path):
    # use the audio file as the audio source
    with sr.AudioFile(path) as source:
        audio_listened = r.record(source)
        # try converting it to text
        text = r.recognize_google(audio_listened)
    return text

Далее мы создаем функцию для разделения аудиофайлов на фрагменты в тишине:

# a function that splits the audio file into chunks on silence
# and applies speech recognition
def get_large_audio_transcription_on_silence(path):
    """
    Splitting the large audio file into chunks
    and apply speech recognition on each of these chunks
    """
    # open the audio file using pydub
    sound = AudioSegment.from_file(path)  
    # split audio sound where silence is 700 miliseconds or more and get chunks
    chunks = split_on_silence(sound,
        # experiment with this value for your target audio file
        min_silence_len = 500,
        # adjust this per requirement
        silence_thresh = sound.dBFS-14,
        # keep the silence for 1 second, adjustable as well
        keep_silence=500,
    )
    folder_name = "audio-chunks"
    # create a directory to store the audio chunks
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)
    whole_text = ""
    # process each chunk 
    for i, audio_chunk in enumerate(chunks, start=1):
        # export audio chunk and save it in
        # the `folder_name` directory.
        chunk_filename = os.path.join(folder_name, f"chunk{i}.wav")
        audio_chunk.export(chunk_filename, format="wav")
        # recognize the chunk
        with sr.AudioFile(chunk_filename) as source:
            audio_listened = r.record(source)
            # try converting it to text
            try:
                text = r.recognize_google(audio_listened)
            except sr.UnknownValueError as e:
                print("Error:", str(e))
            else:
                text = f"{text.capitalize()}. "
                print(chunk_filename, ":", text)
                whole_text += text
    # return the text for all chunks detected
    return whole_text

Давайте попробуем:

print(get_large_audio_transcription_on_silence(“7601-291468-0006.wav”))

Вывод:

audio-chunks\chunk1.wav : His abode which you had fixed in a bowery or country seat. 
audio-chunks\chunk2.wav : Have a short distance from the city. 
audio-chunks\chunk3.wav : Just at what is now called dutch street. 
audio-chunks\chunk4.wav : Soon abounded with proofs of his ingenuity. 
audio-chunks\chunk5.wav : Patent smokejack. 
audio-chunks\chunk6.wav : It required a horse to work some. 
audio-chunks\chunk7.wav : Dutch oven roasted meat without fire. 
audio-chunks\chunk8.wav : Carts that went before the horses. 
audio-chunks\chunk9.wav : Weather cox that turned against the wind and other wrongheaded contrivances. 
audio-chunks\chunk10.wav : So just understand confound it all beholders. 
His abode which you had fixed in a bowery or country seat. Have a short distance from the city. Just at what is now called dutch street. Soon abounded with proofs of his ingenuity. Patent smokejack. It required a horse to work some. Dutch oven roasted meat without fire. Carts that went before the horses. Weather cox that turned against the wind and other wrongheaded contrivances. So just understand confound it all beholders.

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

Если вам нужен более надежный API, я предлагаю вам использовать API Whisper от OpenAI. Чтобы начать работу, вам необходимо зарегистрировать учетную запись OpenAI здесь.

Как только вы зарегистрируете аккаунт, перейдите на страницу API-ключей и создайте API-ключ:

Создаем проект по распознаванию речи в Python

После этого установите библиотеку openai для Python:

$ pip install openai

Теперь скопируйте ключ API в новый файл Python с именем whisper_api.py:

import openai

# API key
openai.api_key = "<API_KEY>"

Поместите туда свой ключ API и добавьте следующий код:

def get_openai_api_transcription(audio_filename):
    # open the audio file
    with open(audio_filename, "rb") as audio_file:
        # transcribe the audio file
        transcription = openai.Audio.transcribe("whisper-1", audio_file) # whisper-1 is the model name
    return transcription


if __name__ == "__main__":
    transcription = get_openai_api_transcription("7601-291468-0006.wav")
    print(transcription.get("text"))

Как видите, использовать API OpenAI до смешного просто: мы используем метод openai.Audio.transcribe() для распознавания речи. Возвращаемый объект – это OpenAIObject, из которого мы можем извлечь текст с помощью метода get() Python dict. Вот результат:

His abode, which he had fixed at a bowery or country seat at a short distance from the city, just at what is now called Dutch Street, soon abounded with proofs of his ingenuity —patent smoke-jacks that required a horse to work them, Dutch ovens that roasted meat without fire, carts that went before the horses, weathercocks that turned against the wind, and other wrong-headed contrivances that astonished and confounded all beholders.

Для больших аудиофайлов мы можем просто использовать функцию get_large_audio_transcription_on_silence() выше, но заменить transcribe_audio() на функцию get_openai_api_transcription(), полный код вы можете получить здесь.

Использование 🤗 трансформеров

Whisper – это универсальная трансформационная модель распознавания речи с открытым исходным кодом, обученная на большом наборе данных разнообразного слабо контролируемого аудио (680 000 часов) на нескольких языках для различных задач (распознавание речи, перевод речи, идентификация языка и определение голосовой активности).

Модели Whisper демонстрируют сильную способность адаптироваться к различным наборам данных и доменам без необходимости тонкой настройки. Как говорится в документе о Whisper: “Цель Whisper – разработать единую надежную систему обработки речи, которая будет надежно работать без необходимости тонкой настройки под конкретный набор данных для достижения высококачественных результатов на конкретных дистрибутивах”.

Чтобы начать работу, давайте установим необходимые для этого библиотеки:

$ pip install transformers==4.28.1 soundfile sentencepiece torchaudio pydub

Мы будем использовать библиотеку Huggingface Transformers для загрузки наших моделей Whisper. Если вам нужно более подробное руководство по этому вопросу, ознакомьтесь с этим руководством.

Откройте новый файл Python с именем transformers_whisper.py и добавьте следующий код:

from transformers import WhisperProcessor, WhisperForConditionalGeneration
import torch
import torchaudio

device = "cuda:0" if torch.cuda.is_available() else "cpu"
# whisper_model_name = "openai/whisper-tiny.en" # English-only, ~ 151 MB
# whisper_model_name = "openai/whisper-base.en" # English-only, ~ 290 MB
# whisper_model_name = "openai/whisper-small.en" # English-only, ~ 967 MB
# whisper_model_name = "openai/whisper-medium.en" # English-only, ~ 3.06 GB
whisper_model_name = "openai/whisper-tiny" # multilingual, ~ 151 MB
# whisper_model_name = "openai/whisper-base" # multilingual, ~ 290 MB
# whisper_model_name = "openai/whisper-small" # multilingual, ~ 967 MB
# whisper_model_name = "openai/whisper-medium" # multilingual, ~ 3.06 GB
# whisper_model_name = "openai/whisper-large-v2" # multilingual, ~ 6.17 GB

Мы импортировали WhisperProcessor для обработки аудио перед выводом, а также WhisperForConditionalGeneration для выполнения распознавания речи на обработанном аудио.

Вы можете видеть различные версии и размеры моделей вместе с их размерами. Чем больше модель, тем лучше транскрипция, так что имейте это в виду. Для демонстрации я буду использовать самую маленькую модель, openai/whisper-tiny; она должна работать на обычном ноутбуке. Давайте загрузим его:

# load the model and the processor
whisper_processor = WhisperProcessor.from_pretrained(whisper_model_name)
whisper_model = WhisperForConditionalGeneration.from_pretrained(whisper_model_name).to(device)

Теперь давайте сделаем функцию, отвечающую за загрузку аудиофайла:

def load_audio(audio_path):
  """Load the audio file & convert to 16,000 sampling rate"""
  # load our wav file
  speech, sr = torchaudio.load(audio_path)
  resampler = torchaudio.transforms.Resample(sr, 16000)
  speech = resampler(speech)
  return speech.squeeze()

Конечно, частота дискретизации должна быть фиксированной, и только частота дискретизации 16 000 работает для Whisper, если вы не сделаете этот шаг обработки, то в итоге получите очень странные и неправильные транскрипции.

Далее, давайте напишем функцию вывода:

def get_transcription_whisper(audio_path, model, processor, language="english", skip_special_tokens=True):
  # resample from whatever the audio sampling rate to 16000
  speech = load_audio(audio_path)
  # get the input features from the audio file
  input_features = processor(speech, return_tensors="pt", sampling_rate=16000).input_features.to(device)
  # get the forced decoder ids
  forced_decoder_ids = processor.get_decoder_prompt_ids(language=language, task="transcribe")
  # generate the transcription
  predicted_ids = model.generate(input_features, forced_decoder_ids=forced_decoder_ids)
  # decode the predicted ids
  transcription = processor.batch_decode(predicted_ids, skip_special_tokens=skip_special_tokens)[0]
  return transcription

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

Давайте опробуем функцию:

if __name__ == "__main__":
    english_transcription = get_transcription_whisper("7601-291468-0006.wav",
                            whisper_model,
                            whisper_processor,
                            language="english",
                            skip_special_tokens=True)
    print("English transcription:", english_transcription)
    arabic_transcription = get_transcription_whisper("arabic-audio.wav",
                          whisper_model,
                          whisper_processor,
                          language="arabic",
                          skip_special_tokens=True)
    print("Arabic transcription:", arabic_transcription)
    spanish_transcription = get_transcription_whisper("cual-es-la-fecha-cumple.mp3",
                          whisper_model,
                          whisper_processor,
                          language="spanish",
                          skip_special_tokens=True)
    print("Spanish transcription:", spanish_transcription)

Выход:

English transcription:  His abode, which he had fixed at a bow-ray, or country seat, at a short distance from the city, just that what is now called Dutch Street, soon abounded with proofs of his ingenuity, patent-smoked jacks that required a horse to work them, Dutch ovens that roasted meat without fire, carts that went before the horses, weathercocks that turned against the wind, and other wrong-headed
Arabic transcription: .نرقلا اذه لاوط عافترالا يف ةبوترلا تايوتسمو ةرارحلا تاجرد رمتست نأ مولعلل ةينيصلا ةيميداكألا يف تبتلا ةبضه ثاحبأ دهعم هدعأ يذلا ريرقتلا حجرو
Spanish transcription:  ¿Cuál es la fecha de tu cumpleaños?

Расшифровка больших аудиофайлов

Для больших аудиофайлов мы можем просто использовать API конвейера, предлагаемого Huggingface, для распознавания речи:

from transformers import pipeline
import torch
import torchaudio

device = "cuda:0" if torch.cuda.is_available() else "cpu"
whisper_model_name = "openai/whisper-tiny" # multilingual, ~ 151 MB

def load_audio(audio_path):
  """Load the audio file & convert to 16,000 sampling rate"""
  # load our wav file
  speech, sr = torchaudio.load(audio_path)
  resampler = torchaudio.transforms.Resample(sr, 16000)
  speech = resampler(speech)
  return speech.squeeze()


def get_long_transcription_whisper(audio_path, pipe, return_timestamps=True, 
                                   chunk_length_s=10, stride_length_s=1):
    """Get the transcription of a long audio file using the Whisper model"""
    return pipe(load_audio(audio_path).numpy(), return_timestamps=return_timestamps,
                chunk_length_s=chunk_length_s, stride_length_s=stride_length_s)
    
    
if __name__ == "__main__":
    # initialize the pipeline
    pipe = pipeline("automatic-speech-recognition", 
                model=whisper_model_name, device=device)
    # get the transcription of a sample long audio file
    output = get_long_transcription_whisper(
        "7601-291468-0006.wav", pipe, chunk_length_s=10, stride_length_s=2)
    print(f"Transcription: {output}")
    print("="*50)
    for chunk in output["chunks"]:
        # print the timestamp and the text
        print(chunk["timestamp"], ":", chunk["text"])

Вот вывод при запуске скрипта:

Transcription: {'text': ' His abode, which he had fixed at a bowray, or country seat, at a short distance from the city, just that what is now called Dutch Street, soon abounded with proofs of his ingenuity. Patent smoked jacks that required a horse to work them. Dutch ovens that roasted meat without fire, carts that went before the horses, weathercocks that turned against the 
wind, and other wrong-headed quadrivances stonished and confounded all beholders.', 'chunks': [{'timestamp': (0.0, 12.56), 'text': ' His abode, which he had fixed at a bowray, or country seat, at a short distance from the city, just that what is now called Dutch Street, soon abounded'}, {'timestamp': (12.56, 15.5), 'text': ' with proofs of his ingenuity.'}, {'timestamp': (15.5, 
34.64), 'text': ' Patent smoked jacks that required a horse to work them. Dutch ovens that roasted meat without fire, carts that went before the horses, weathercocks that turned against the wind, and other wrong-headed quadrivances stonished and confounded all beholders.'}]}
==================================================
(0.0, 12.56) :  His abode, which he had fixed at a bowray, or country seat, at a short distance from the city, just that what is now called Dutch Street, soon abounded
(12.56, 15.5) :  with proofs of his ingenuity.
(15.5, 34.64) :  Patent smoked jacks that required a horse to work them. Dutch ovens that roasted meat without fire, carts that went before the horses, weathercocks that turned against the wind, and other wrong-headed quadrivances stonished and confounded all beholders.

Заключение

Эта статья содержит исчерпывающее руководство по автоматическому распознаванию речи с помощью Python. В нем рассматривались три основных подхода: использование библиотеки SpeechRecognition с Google Speech Recognition, использование API Whisper от OpenAI и выполнение выводов непосредственно на моделях Whisper с открытым исходным кодом с помощью библиотеки 🤗 Transformers.

В статью вошли примеры кода для каждого метода, демонстрирующие, как транскрибировать аудиофайлы, разбивать большие аудиофайлы на фрагменты и использовать различные модели для повышения точности транскрипции.
Кроме того, в статье были продемонстрированы многоязыковые возможности модели Whisper и представлен конвейер для транскрибирования больших аудиофайлов с использованием библиотеки 🤗 Transformers.

Полный код этого руководства вы можете получить здесь.

+1
0
+1
6
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *