Оригинальный пост был опубликован на TypethePipe.

Введение

Какое время, чтобы быть живым, а? Развитие ИИ происходит более быстрыми темпами, чем когда-либо, и виртуальные помощники быстро становятся повсеместной частью нашей цифровой жизни. Помните Сири и Алексу? Не так давно они были жемчужиной в короне, а теперь кусают пыль перед мощью моделей GPT.

В этом сообщении блога мы покажем вам, как создать виртуального помощника с помощью GPT и Whisper API. Эти мощные инструменты позволяют записывать голос пользователя, расшифровывать или переводить «на лету», если это необходимо, и генерировать ответ, используя расширенные возможности обработки естественного языка OpenAI. Мы проведем вас через этапы создания бота в двух разных вариантах — интерактивном консольном приложении и браузерной версии на базе Streamlit.

Настройка среды

Прежде чем вы сможете начать, вам нужно убедиться, что у вас есть правильные инструменты и настроенная среда. Я рекомендую настроить виртуальную среду с pipenv, чтобы все зависимости управлялись автоматически из Pipefile, включенного в репозиторий Github. Ниже приведены шаги, которые вы можете выполнить, чтобы настроить среду:

Установить зависимости

  • Начните с клонирования репозитория с помощью git clone https://github.com/PabloCanovas/chatgpt-whisper-streamlit-voice-assistant gpt_voice_assistant
  • Если у вас не установлен pipenv для управления зависимостями, продолжайте: pip install pipenv --user
  • Установите необходимые библиотеки. Вы можете установить их, просто перейдя в клонированный каталог: cd gpt_voice_assistant и запустив: pipenv install, который установит зависимости на основе файла Pipfile.lock.

Настройте свой ключ API OpenAI

Необходимо вручную управлять ключом API OpenAI. Вам нужно будет создать новый файл с именем myapikeys.py с этой строкой внутри: OPENAI_KEY = "my-apikey-goes-here" и, очевидно, использовать для этого свой ключ.

Определите вспомогательные функции

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

Запись голоса пользователя

Первым шагом в создании виртуального помощника является запись голоса пользователя. Вы можете сделать это с помощью функции record_audio_manual:

def record_audio_manual(filename, sr=44100):
    input("  ** Press enter to start recording **")
    audio = sd.rec(int(10 * sr), samplerate=sr, channels=2)
    input("  ** Press enter to stop recording **")
    sd.stop()
    write(filename, sr, audio)

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

После того, как вы записали голос пользователя, вы можете перейти к его расшифровке с помощью Whisper API.

Расшифровка голоса пользователя

Следующим шагом является преобразование голоса пользователя в текст. Вы можете сделать это с помощью предоставленной функции transcribe_audio, которая использует Whisper API для расшифровки аудио. Это удивительно просто:

def transcribe_audio(filename):
    audio_file = open(filename, "rb")
    transcript = openai.Audio.transcribe("whisper-1", audio_file)
    audio_file.close()
    return transcript

Когда вы вызываете функцию, она считывает аудиофайл в память, вызывает функцию openai.Audio.transcribe для расшифровки аудио с помощью Whisper API и возвращает результирующую расшифровку.

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

def translate_audio(filename):
    audio_file = open(filename, "rb")
    translation = openai.Audio.translate("whisper-1", audio_file)
    audio_file.close()
    return translation

Как только вы расшифруете голос пользователя, давайте отправим его в GPT.

Генерация ответа с помощью GPT

Следующим шагом в создании этого классного помощника является создание ответа на ввод пользователя с помощью GPT. Вы можете сделать это с помощью OpenAI GPT API, который, как всем уже известно, позволяет генерировать человекоподобный текст на основе заданной подсказки. Это действительно не может быть намного проще. Вот как:

bot = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages)
response = bot.choices[0].text

Функция openai.ChatCompletion.create принимает два аргумента: имя используемой модели GPT (в данном случае «gpt-3.5-turbo») и список сообщений, которыми обменивались пользователь и виртуальный помощник. Это важно, потому что GPT сохраняет весь контекст разговора, чтобы ответить на вопросы, что является ключевым аспектом того, почему он работает так хорошо. Когда вы вызываете функцию, она генерирует ответ на самое последнее сообщение от пользователя, доступ к которому вы можете получить с помощью атрибута bot.choices[0].text.

Воспроизведение ответа вслух

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

def say(text):
    p = multiprocessing.Process(target=pyttsx3.speak, args=(text,))
    p.start()
    while p.is_alive():
        if keyboard.is_pressed('enter'):
            p.terminate()
        else:
            continue
    p.join()

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

Важность использования многопроцессорной обработки для эффективного воспроизведения звука

Если ответ GPT особенно длинный, вам может понадобиться способ остановить воспроизведение на полпути. Вот тут-то и появляются возможности многопоточности Python.

В Python multiprocessing позволяет запускать несколько потоков одновременно, что позволяет выполнять несколько действий одновременно. В функции say мы используем ее для воспроизведения речевого аудиофайла и одновременного прослушивания пользовательского ввода.

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

Создание консольной программы

Прежде чем перейти к браузерному приложению, вы можете начать с создания интерактивной консольной программы, которую вы можете запустить на своем локальном компьютере. Это позволит вам быстро тестировать и повторять работу вашего виртуального помощника без необходимости использования веб-сервера или браузера.

Используя строительные блоки, описанные выше, вот как выглядит мой помощник:

import openai
import myapikeys
from text_speech_utils import *

openai.api_key = myapikeys.OPENAI_KEY
input_audio_filename = 'input.wav'
messages = [{"role": "system", "content": "You are a helpful assistant."}]
def main():
    while True:
        record_audio_manual(input_audio_filename)
        transcription = transcribe_audio(input_audio_filename)             
        messages.append({"role": "user", "content": transcription['text']})
        print(f"\n- Me: {transcription['text']}")
        bot = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages)
        
        response = bot.choices[0].message.content
        print(f"- ChatGPT: {response}")
        print("\n***   Press enter to interrupt assistant and ask a new question   ***\n")
        say(response)

if __name__ == '__main__':
    main()

В этом примере мы определяем основной цикл нашей программы, используя цикл while, который прослушивает ввод пользователя. Внутри цикла мы просто записываем, расшифровываем (или переводим), отправляем текст в openAI и проигрываем ответ.

И вот оно! Всего за 50 строк кода мы создали полнофункционального голосового помощника, с помощью которого можно узнавать о новых темах, вдохновляться новыми кулинарными рецептами или планировать подробные тренировки, соответствующие вашим собственным целям.

Создание браузерного приложения с помощью Streamlit

В дополнение к консольной программе вы также можете создать небольшое веб-приложение с помощью Streamlit. Streamlit — это библиотека Python, которая позволяет создавать интерактивные веб-приложения всего несколькими строками кода.

Вот снимок того, как выглядит мое маленькое приложение:

И это код, который его генерирует:

import streamlit as st
import pandas as pd
import openai
import myapikeys
from text_speech_utils import *

openai.api_key = myapikeys.OPENAI_KEY
input_audio_filename = 'input.wav'
output_audio_filename = 'chatgpt_response.wav'
output_conversation_filename = 'ChatGPT_conversation.txt'
# Initialize app
if 'messages' not in st.session_state:
    st.session_state['messages'] = [{"role": "system", "content": "You are a helpful assistant."}]
st.title("My awesome personal assistant")
sec = st.slider("Select number of seconds of recording", min_value=2, max_value=8, value=5)
# Record audio + transcribe with Whisper + get GPT3 response
if st.button('Record audio'):
    st.write("Recording...")
    record_audio(input_audio_filename, sec)
    transcription = transcribe_audio(input_audio_filename)
    st.write(f"Me: {transcription['text']}")
    st.session_state['messages'].append({"role": "user", "content": transcription['text']})
    bot = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=st.session_state['messages'])
    response = bot.choices[0].message.content
    st.write(f"GPT: {response}")
    save_text_as_audio(response, output_audio_filename)
    play_audio(output_audio_filename)
    st.session_state['messages'].append({"role": "assistant", "content": response})

st.download_button(label="Download conversation", 
                   data = pd.DataFrame(st.session_state['messages']).to_csv(index=False).encode('utf-8'), 
                   file_name=output_conversation_filename)

Где я добавил ползунок для определения количества секунд, которые вы хотите записать, и возможность загрузки полного разговора в конце. Кроме того, я использовал несколько других функций, чем в примере выше: save_text_as_audio и play_audio. Причина просто в том, что я не мог заставить функцию say работать в приложении Streamlit, вероятно, из-за чего-то, связанного с многопроцессорностью.

Весь код вы можете найти здесь.

Заключение

В этом сообщении блога я показал вам, как создать виртуального помощника с помощью API OpenAI GPT и Whisper. Я провел вас через этапы создания интерактивной консольной программы и браузерного приложения с использованием Streamlit.

Возможным следующим шагом может быть развертывание приложения в Интернете, возможно, на Streamlit, Heroku, AWS или GCP. В случае, если вы собираетесь на это, держите меня в курсе! Буду рад узнать, что это может быть кому-то полезно.

Удачного строительства!

Оригинальный пост был опубликован на TypethePipe.