はじめに
ChatGPTとVOICEVOXを用いて、気象データから天気予報テキストを自動生成し、それをキャラクター"ずんだもん"のユニークな声で読み上げる仕組みを構築した。
今回の取り組みの概要
- ChatGPTに気象データ取得の機能を追加する
- 気象データを元にChatGPTに天気予報テキストを自動生成させる
- "ずんだもん"に天気予報テキストを読み上げさせる
ChatGPT x ずんだもん による天気予報の読み上げ結果
今回の取り組みで ずんだもん に天気予報の読み上げさせた結果を示す
天気を問い合わせた場合
天気以外を問い合わせた場合
ChatGPTに気象データを取得させる
ChatGPTは2021年までの情報に基づいてトレーニングされており、最新のデータやリアルタイムの情報にはアクセスできない。つまり最新の気象データに基づく天気予報テキストを生成したければ、その情報を何らかの手段でChatGPTに与える必要がある。
ChatGPTにはすでに天気情報にアクセス可能なプラグインが複数存在している。それらのプラグインをLangchainから利用するのが最も簡単だろう。
ところがlangchainからChatGPTのプラグインを利用した場合、途中で処理が終了してしまう事が発生してなかなか上手く行かなかった。まだまだこの辺りは安定していないのかもしれない。
そこで今回は、ChatGPTのAPIのアップデートで追加された関数呼び出し機能を用いる。気象に関する問い合わせがあった場合にはChatGPTが自作の関数を用いて気象データを取得する。
気象データ取得サイト
気象データは次のような形式で取得される
{
"latitude": 52.52,
"longitude": 13.419998,
"generationtime_ms": 0.2809762954711914,
"utc_offset_seconds": 32400,
"timezone": "Asia/Tokyo",
"timezone_abbreviation": "JST",
"elevation": 38.0,
"current_weather": {
"temperature": 14.6,
"windspeed": 9.8,
"winddirection": 287.0,
"weathercode": 2,
"is_day": 1,
"time": "2023-06-24T13:00"
},
"daily_units": {
"time": "iso8601",
"weathercode": "wmo code",
"temperature_2m_max": "°C",
"temperature_2m_min": "°C"
},
"daily": {
"time": [
"2023-06-24",
"2023-06-25",
"2023-06-26",
"2023-06-27",
"2023-06-28",
"2023-06-29",
"2023-06-30"
],
"weathercode": [
61,
3,
80,
80,
61,
61,
61
],
"temperature_2m_max": [
23.3,
25.7,
29.7,
23.1,
20.9,
19.3,
22.4
],
"temperature_2m_min": [
14.6,
16.6,
17.8,
13.2,
13.7,
17.8,
13.3
]
}
}
実装方法
weather_function
の description
にChatGPTに呼び出させるget_weather_info
関数を登録する。ChatGPTは説明文と入力文を突き合わせて必要に応じて get_weather_info
を呼び出すか、ChatGPT自身で回答するかを決める。
weather_function = {
"name": "get_weather_info",
"description": "緯度と経度の情報から現在の天気を取得します",
"parameters": {
"type": "object",
"properties": {
"latitude": {
"type": "string",
"description": "緯度の情報",
},
"longitude": {
"type": "string",
"description": "経度の情報",
},
},
"required": ["latitude", "longitude"],
},
}
def get_weather_info(latitude, longitude):
base_url = "https://api.open-meteo.com/v1/forecast"
parameters = {
"latitude": latitude,
"longitude": longitude,
# "current_weather": "true",
"hourly": "temperature_2m,relativehumidity_2m",
"timezone": "Asia/Tokyo"
}
response = requests.get(base_url, params=parameters)
if response.status_code == 200:
data = response.json()
return json.dumps(data)
else:
return None
作成したプログラムのテストとして次のようなprompt1
とprompt2
をChatGPTに入力した結果を示す。ChatGPTからの回答を同期的に受け取る方法とストリーミングで受け取る場合の2種類を実行した。
天気に関する入力の場合にはget_weather_info
を呼び出し気象データをChatGPTに渡した上で回答を作成する。天気に関する入力でない場合には通常通りChatGPTが直接回答する。
question1 = "横浜の今日の天気を詳しく教えてください"
prompt1 = f'''
あなたは天気を説明するアナウンサーです
次の条件に従って入力文に回答してください
#条件:
温度19度や湿度20%といった数字はできるだけ使わず、暑苦しい、肌寒い、など感覚的な回答を行う
雨の可能性があれば傘をもって出かけるべきだと回答する
10文字以内で答えよ
#入力文:
{question1}
'''
question2 = "織田信長について答えよ"
prompt2 = f'''
10文字以内で答えよ
#入力文:
{question2}
'''
$ python3 ./openai_chat.py
2023-06-24 11:22:00,323 - INFO:root - chatstart
2023-06-24 11:22:01,696 - INFO:root - message: {
"content": null,
"function_call": {
"arguments": "{\n \"latitude\": \"35.4437\",\n \"longitude\": \"139.6380\"\n}",
"name": "get_weather_info"
},
"role": "assistant"
}
2023-06-24 11:22:01,697 - INFO:root - 選択された関数を呼び出す: get_weather_info
2023-06-24 11:22:02,506 - INFO:root - 選択された関数に最適な prompt を選ぶ
2023-06-24 11:22:02,506 - INFO:root - 関数の回答:{"latitude": 35.45, "longitude": 139.625, "generationtime_ms": 0.15997886657714844, "utc_offset_seco...
{'response': '横浜の今日の天気は、肌寒いです。気温は21度で、湿度は96%です。雨の可能性があるため、傘を持って出かけることをおすすめします。', 'finish_reason': 'stop'}
2023-06-24 11:22:06,607 - INFO:root -
2023-06-24 11:22:06,608 - INFO:root - chatstart
2023-06-24 11:22:08,397 - INFO:root - 選択された関数を呼び出す: get_weather_info
2023-06-24 11:22:09,635 - INFO:root - 選択された関数に最適な prompt を選ぶ
2023-06-24 11:22:09,636 - INFO:root - 関数の回答:{"latitude": 35.45, "longitude": 139.625, "generationtime_ms": 0.19502639770507812, "utc_offset_seco...
2023-06-24 11:22:10,394 - INFO:root - response:{"response": "", "finish_reason": ""}
2023-06-24 11:22:10,394 - INFO:root - response:{"response": "\u6a2a", "finish_reason": ""}
... (省略)
2023-06-24 11:22:11,913 - INFO:root - response:{"response": "\u3002", "finish_reason": ""}
2023-06-24 11:22:11,936 - INFO:root - response:{"response": "", "finish_reason": "stop"}
{'response': '横浜の今日の天気は、肌寒いです。気温は21.7℃で、湿度は97%です。雨の可能性があるため、傘を持って出かけることをおすすめします。', 'finish_reason': 'stop'}
2023-06-24 11:22:11,937 - INFO:root -
2023-06-24 11:22:11,937 - INFO:root - chatstart
2023-06-24 11:22:12,666 - INFO:root - message: {
"content": "\u6b66\u5c06",
"role": "assistant"
}
{'response': '武将', 'finish_reason': 'stop'}
2023-06-24 11:22:12,667 - INFO:root -
2023-06-24 11:22:12,668 - INFO:root - chatstart
2023-06-24 11:22:13,157 - INFO:root - response:{"response": "", "finish_reason": ""}
2023-06-24 11:22:13,158 - INFO:root - response:{"response": "\u5929", "finish_reason": ""}
... (省略)
2023-06-24 11:22:13,336 - INFO:root - response:{"response": "\u5bb6", "finish_reason": ""}
2023-06-24 11:22:13,347 - INFO:root - response:{"response": "", "finish_reason": "stop"}
{'response': '天才的な軍略家', 'finish_reason': 'stop'}
質問 | 回答1 | 回答2 |
---|---|---|
横浜の今日の天気を詳しく教えてください | 横浜の今日の天気は、肌寒いです。気温は21度で、湿度は96%です。雨の可能性があるため、傘を持って出かけることをおすすめします。 | 横浜の今日の天気は、肌寒いです。気温は21.7℃で、湿度は97%です。雨の可能性があるため、傘を持って出かけることをおすすめします。 |
織田信長について答えよ | 武将 | 天才的な軍略家 |
VOICEVOXを使った読み上げ
VOICEVOXは音声合成エンジン。特にその中でもずんだもんの声は、そのユーモラスで個性的な発音が人気を博している。このずんだもんの声を用いて、ChatGPTから生成される天気予報の文章を読み上げる。
VOICEVOXを音声合成サーバーとして利用する
- VOICEVOXのアプリをインストール
- VOICEVOXのアプリを実行 (ローカルWebサーバーが立ち上がる)
- VOICEVOXのローカルWebサーバーに対して問い合わせを行う
VOICEVOXのローカルWebサーバーの利用方法
$ echo -n "こんにちは、音声合成の世界へようこそ" >text.txt
$ curl -s \
-X POST \
"127.0.0.1:50021/audio_query?speaker=1"\
--get --data-urlencode text@text.txt \
> query.json
$ curl -s \
-H "Content-Type: application/json" \
-X POST \
-d @query.json \
"127.0.0.1:50021/synthesis?speaker=1" \
> audio.wav
ずんだもん に読み上げさせる
ずんだもん
にテキストデータを読み上げされるには次の2つのプロセスが必要だ。
それぞれの処理にそれなりの時間がかかるため、リアルタイム処理で音声合成を利用したい場合には音声読み上げ中に音声合成処理を裏で進めておきたい。
- テキストデータから音声合成用のクエリを作成する
- 音声合成用のクエリから音声合成する
次のプログラムではテキストデータを与えた順にクエリ作成・音声合成を非同期で進め、同期的に読み上げを行う。つまり、"ハロー”、”ワールド”を引数にplayAudioByVoiceVox()
を順に呼び出すと、"ハロー" と "ワールド" のクエリ作成・音声合成は並列に実行されつつ、その処理の終了した順ではなく、playAudioByVoiceVox()
を呼び出した順に"ハロー"、"ワールド"と読み上げる。
利用規約
VOICEVOX
とずんだもん
の利用規約について情報をまとめておく
VOICEVOXの利用規約
- ずんだもんの音声ライブラリを用いて生成した音声は、「VOICEVOX:ずんだもん」とクレジットを記載すれば、商用・非商用で利用可能です。
- 玄野武宏の音声ライブラリを用いて生成した音声は、「VOICEVOX:玄野武宏」とクレジットを記載すれば、商用・非商用で利用可能です。
東北ずん子プロジェクト キャラクター利用の手引き
Q : 技術紹介でWebページや書籍に使いたい
A : この場合は例外的に商用利用はOKです
プログラミングや3Dなどの利用方法を解説するといった目的で、東北ずん子をWebページや書籍で使うことは例外的に商用利用が可能です。
(東北ずん子の使い方を広げる目的に合致するからです)
クレジット
VOICEVOX
- VOICEVOX:ずんだもん
- VOICEVOX:玄野武宏
Big Buck Bunney
オリジナルURL:https://peach.blender.org/
新しいリリース(4k、HFR、3D)Sunflower version:
古いバージョン:https://download.blender.org/peach/bigbuckbunny_movies/
The movie is licensed under CC-BY, read more about what that means
Big Buck Bunny Copyright (C) 2008 Blender Foundation | peach.blender.org Some Rights Reserved.
Creative Commons Attribution 3.0 license. https://peach.blender.org/
Stereoscopic / 4K / 60 fps / HDRI changes Copyright (C) 2013 Janus B. Kristensen Some Rights Reserved.
Creative Commons Attribution 3.0 license.
参考資料