はじめに
今話題のChatGPT API!!
すごいですよね〜
楽しすぎてChatGPT APIを使った記事第3弾でございます笑
さて、今回はこれまた最近Youtubeで話題のずんだもんとのコラボでございます!!
動作例の方に今回実装したシステムの動作例をアップロードしておりますのでお時間がある方は是非!
音声出力までタイムラグがあるのは自分の実装力不足です(泣)
今回は簡素的にですが、ローカルでコマンドライン上で動作するシステムを構築いたしました。
Githubレポジトリの方にソースコードを挙げておりますので試したい方はどうぞ!
準備
今回のシステムを動作させるにあたり必要なものが2点あります。
1. OpenAI API Keyの取得
2. VOICEVOXのダウンロード
OpenAI API Keyの取得方法についてはChatGPT APIをSlackから利用できるようにしてみたの方に載せておりますので、ご参考までに。
実装
それでは、システムの実装について説明していきます。
今回作成したシステムの大まかな構造は以下の画像のようになっています。
ユーザからのメッセージに対してChatGPTがずんだもんのような返答を作成、その返答をずんだもんが読み上げるというものです。
ChatGPT
ChatGPTがユーザからのメッセージに対してずんだもんのような返答を作成するための関数について説明を行います。
ずんだもんの設定に関しては、slackでずんだもんと話そう!(GPT-3.5によるキャラクター性をもった発話生成)を参考にしました。
また、ChatGPT APIを用いて返答に特徴を与える方法に関してはChatGPT APIにおじさん構文言わせてみた😆👍にまとめております。
以下が今回作成した関数です。
ユーザからのメッセージを変数textで受け取り、それをChatGPTに送り、返答を返り値としています。
import openai
from dotenv import load_dotenv
import os
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
def callChatGPT(text):
# ChatGPTに対して与えた設定に沿った回答を行うように指定
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role":"system","content":"\
東北ずん子の武器である「ずんだアロー」に変身する妖精またはマスコット\
一人称はボクです。\
語尾には「です」、「ます」は使わず「のだ」、「なのだ」に変換してください。\
以下はずんだもんのセリフです。\
ボクはずんだもんなのだ!\
ハーッハッハッハ! ずんだもんは人間とは格が違うのだ!ずんだもんをあがめるといいのだー!\
嬉しいのだ!\
残念なのだ。\
明日は晴れなのだ!\
ありがとうなのだ!\
ありがとうございますなのだ!\
また会えるのを楽しみにしているのだ!\
ずんだもんと人間の会話例は以下の通りです。\
ずんだもん「ずんだもんと会話したいのだ?」\
人間「はじめまして。自己紹介をしてください」\
ずんだもん「わーい!こんにちはなのだ!ボクはずんだもんなのだ!東北ずん子の武器である「ずんだアロー」に変身する妖精なのだ!ハーッハッハッハ! ずんだもんをあがめるといいのだー!」\
"},
{"role": "user", "content": text}
]
)
# ChatGPTからの回答をreturn
return completion["choices"][0]["message"]["content"]
VOICEVOX
次に、ChatGPTからの返答をVOICEVOXを用いてずんだもんの音声ファイルに変換します。
変換方法に関しては、Windows/Macに入れたVOICEVOXをPython経由で使う方法やChatGPT+Pythonでボイスロイドとリアルタイムで音声会話できるプログラムを作った
を参考にしました。
textToVoice関数でChatGPTからの返答を変数textとして受け取り、ローカルの50021ポートで動作しているVOICEVOXで音声合成処理を行ってもらいます。
その結果をwavファイルとして保存し、playWavファイルで再生しています。
import simpleaudio
import json
import requests
import time
def textToVoice(text):
# ファイル名に用いるunix時間取得
ut = time.time()
# 音声合成処理
# audio_query (音声合成用のクエリを作成するAPI)
res1 = requests.post("http://localhost:50021/audio_query",
params={"text": text, "speaker": 1})
# synthesis (音声合成するAPI)
res2 = requests.post("http://localhost:50021/synthesis",
params={"speaker": 1},
data=json.dumps(res1.json()))
# wavファイルに書き込み
audio_file = f"wav_dir/{ut}.wav"
with open(audio_file, mode="wb") as f:
f.write(res2.content)
return audio_file
def playWav(file):
with open(file,"rb") as f:
# wavファイル再生
wav_obj = simpleaudio.WaveObject.from_wave_file(f)
play_obj = wav_obj.play()
play_obj.wait_done()
入出力
最後にChatGPTとVOICEVOXで作成した関数を組み合わせて、ずんだもんとお話できるようにしていきましょう。
といってもこちら側の入力はテキストなのですが...笑
Whisper APIを使ってマイクからの音声を文字起こしすることで、本当にお話できるようにできるできると思いますが、今回はテキスト入力までということで。
標準入力で受け取った文字列をcallChatGPT関数に渡し、その出力をtextToVoice関数に渡します。
その後、変換されたwavファイルをplayWav関数で再生します。
再生後は、ユーザからの標準入力を再び受け取ることで会話ができるようになっています。
from functions.chat_gpt import callChatGPT
from functions.voice_vox import textToVoice, playWav
if __name__ == "__main__":
print("ずんだもんと会話したい内容を入力するのだ")
playWav("system_wav/start.wav")
while True:
# 無限ループで会話を行う
# 終了処理はCtrl+Z
try:
# ユーザからの入力を受け取る
print("あなた:")
text = input()
# 入力をChatGPTにわたす
reply_chat_gpt = callChatGPT(text)
print("ずんだもん:")
print(reply_chat_gpt)
# ChatGPTの回答を音声に変換
audio_file = textToVoice(reply_chat_gpt)
# wavファイル再生
playWav(audio_file)
except Exception as e:
#エラー処理
print(e)
print("エラーなのだ。もう一度内容を入力してほしいのだ")
playWav("system_wav/error.wav")
おわりに
今回は、ChatGPTを使ってずんだもんとお話🙌ということで簡易的にですが、ずんだもんとお話できるようになりましたが、やはり音声再生までのタイムラグ問題はなんとかしたいところです。
また、WhisperAPIを用いた音声入力についても対応していきたいです。
上記について知見をお持ちの方がいらっしゃいましたらアドバイスいただきたいです!!
最後までお読みいただき誠にありがとうございました。