[初心者向け] Amazon Polly を使って ChatGPT を体感してみる

2023.03.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、森田です。

本記事では、今話題の ChatGPT についてちょっと触ってみたいと思います。

やりたいこと

皆さんもご存知のように、ChatGPT は、自然に会話ができるAIとなっております。

また、OpenAI社は上記の ChatGPT 以外にも 音声認識を行うことができる Whisper も提供しております。

せっかくなので、これら2つを手っ取り早く体験できないかなと考え、 実際にユーザの話した音声を Whisper で認識して、ChatGPT で回答文を作成することにしてみました。

さらに、この回答文も、Amazon Polly を使って、読ませてみたいと思います。

構成

以下のような構成で作成します。

事前準備

OpenAI社のAPIを利用しますので、まずは、APIの発行まで済ませておきましょう。

https://platform.openai.com/signup

実行環境

以下の環境で実行させます。

  • Intel Mac
  • Python 3.8.5
boto3==1.21.42
playsound==1.3.0
SpeechRecognition==3.10.0
openai==0.27.2

コードの準備

以下のような Python スクリプトを作成します。

APIKEYには、発行したAPIキーを記載してください。

import boto3
import playsound
import speech_recognition as sr
import openai
from contextlib import closing

APIKEY = ""
openai.api_key = APIKEY

r = sr.Recognizer()
polly = boto3.client("polly")

def voice_to_text():
    with sr.Microphone() as source:
        print(">なにか話してください")
        audio = r.listen(source)
    return r.recognize_whisper_api(audio, api_key=APIKEY)

def create_text(messages):
    print("考え中...")
    result = openai.ChatCompletion.create(
        model='gpt-3.5-turbo',
        messages=messages
    )
    response_text = result['choices'][0]['message']['content']
    return response_text

def text_to_voice(text):
    mp3_path = "./speech.mp3"
    response = polly.synthesize_speech(
        Engine='neural',
        Text = text,
        OutputFormat = "mp3",
        VoiceId = "Tomoko"
    )
    audio_stream = response.get("AudioStream")
    if audio_stream :
        with closing(audio_stream) as stream:
            with open(mp3_path, "wb") as file:
                file.write(stream.read())
    playsound.playsound(mp3_path)

messages = []
while True:
    text = voice_to_text()
    if text == "":
        continue
    print("you:", text)
    messages.append(
            {'role': 'user', 'content': text}
    )
    response_text = create_text(messages)
    print("ChatGPT:",response_text)
    messages.append(
        {'role': 'assistant', 'content': response_text}
    )
    text_to_voice(response_text)

voice_to_text関数

voice_to_text関数では、SpeechRecognitionを使用して、マイクからの音声取得、音声認識を行います。

SpeechRecognitionでは、Whisper API とのやりとりもやってくれるので簡単に実装できます。

def voice_to_text():
    with sr.Microphone() as source:
        print(">なにか話してください")
        audio = r.listen(source)
    return r.recognize_whisper_api(audio, api_key=APIKEY)

create_text関数

create_text関数では、openai の ChatCompletion を使用して回答文の作成を行います。

ChatCompletionの引数は以下のようになっています。

  • model
    • モデル名
  • messages
    • モデルへ入力するメッセージ

今回は、会話を行うだけの用途なので、汎用的な モデルであるgpt-3.5-turbo を使います。

def create_text(messages):
    print("考え中...")
    result = openai.ChatCompletion.create(
        model='gpt-3.5-turbo',
        messages=messages
    )
    response_text = result['choices'][0]['message']['content']
    return response_text

text_to_voice関数

text_to_voice関数では、テキストの読み上げを行います。

boto3 から polly にリクエストして音声データを取得して、playsound で読み上げます。

def text_to_voice(text):
    mp3_path = "./speech.mp3"
    response = polly.synthesize_speech(
        Engine='neural',
        Text = text,
        OutputFormat = "mp3",
        VoiceId = "Tomoko"
    )
    audio_stream = response.get("AudioStream")
    if audio_stream :
        with closing(audio_stream) as stream:
            with open(mp3_path, "wb") as file:
                file.write(stream.read())
    playsound.playsound(mp3_path)

while文

上記の関数をwhile文の中で読み出してあげれば完成です。

messages = []
while True:
    text = voice_to_text()
    if text == "":
        continue
    print("you:", text)
    messages.append(
            {'role': 'user', 'content': text}
    )
    response_text = create_text(messages)
    print("ChatGPT:",response_text)
    messages.append(
        {'role': 'assistant', 'content': response_text}
    )
    read_voice(response_text)

試してみる

試してみた様子がこちらです。

いい感じに音声を認識して、返答してくれています。

最後に

60行くらいのコードで AI との会話ができるので、すごい時代になったなぁと感じました。

SpeechRecognition が Whisper API を対応するようになったので音声認識周りを楽に実装することができました!

コードがちょっとわかるって人は、すぐに試せると思うので、ぜひ皆さんもやってみてください。