LINE+Assistants API+VOICEVOXで、LINEから送信するとカスタマイズされたChatGPTの回答を読み上げてくれるシステムを作ってみた
LINEにてユーザーがメッセージを送信すると、OpenAIのAssistants APIからの回答をVOICEVOXで音声に変換し、LINEのボイスメモで返すというシステムを作成しました。
システムの構成などをご紹介します。
AWS関連
Lambda
ユーザーがLINEにメッセージを送信したのをトリガーに実行されます。
Assistants APIとのやり取り、音声データへの変換、S3へのアップロードなど中核を担う部分です。
EFS
Elastic File Systemの略。
伸縮自在なファイルストレージサービスです。
今回のシステムでは音声変換処理にVOICEVOXを使用しています。
VOICEVOXのライブラリはすべて合わせると250Mバイト以上あり、LambdaLayersでの管理ができません。
そのため必要なライブラリをEFSに格納し、そこからライブラリを呼び出しています。
EFSにライブラリをインストールする方法
EFSにライブラリをインストールするためにはEFSにsshで接続する必要があります。
EC2インスタンスからEFSをマウントしsshで接続できるようにします。
- EFSファイルシステムとアクセスポイントを作成します
- EC2インスタンスを起動します
(ライブラリインストール時にOut Of Memoryが発生するため、4GB以上のメモリが必要)
※ライブラリのインストールが終わりLambdaから接続できることが確認できたら、EC2インスタンスは削除しても問題ありません。
EC2インスタンスにssh接続後、以下のコマンドを実行してライブラリをインストールします。
# EFSマウント
sudo yum install -y amazon-efs-utils
sudo mkdir /mnt/efs
sudo mount -t efs [EFSのファイルシステムID]:/ /mnt/efs
# Lambdaで使用できるPythonのバージョンが3.12なので、それに合わせてEC2インスタンスにPython3.12インストール
sudo yum install -y gcc openssl11 openssl11-devel bzip2-devel libffi-devel
cd /usr/local/src/
sudo wget https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz
sudo tar xzf Python-3.12.1.tgz
cd Python-3.12.1/
sudo ./configure --enable-optimizations
sudo make altinstall
# 権限変更
sudo chown ec2-user:ec2-user /mnt/efs
# ライブラリインストール
pip3.12 install -t /mnt/efs/lib https://github.com/VOICEVOX/voicevox_core/releases/download/0.14.5/voicevox_core-0.14.5+cpu-cp38-abi3-linux_x86_64.whl numpy fastapi==0.99 requests tqdm openai
# VOICEVOX実行に必要なデータのダウンロード
# (libonnxruntime.soとOpen JTalkの辞書データ)
cd /mnt/efs
curl -sSfL https://github.com/VOICEVOX/voicevox_core/releases/latest/download/download.sh | bash -s
# 不要データ削除(EFSの料金を少しでも減らすため)
rm -r /mnt/efs/voicevox_core/{model,VERSION,*voicevox_core*}
Lambda環境変数設定
Lambdaの環境変数で PYTHONPATH:/mnt/efs/lib
を設定します。
VOICEVOXのコード
基本的にこちらの記事の書き方で実行できますが、ハマりそうなポイントに絞って説明します。
from ctypes import CDLL
from pathlib import Path
CDLL(str(Path("/mnt/efs/voicevox_core/libonnxruntime.so.1.13.1").resolve(strict=True)))
from voicevox_core import VoicevoxCore
VOICEVOX実行の際に使用するlibonnxruntime.soファイルは実行場所に配置します。
Lambdaであればroot直下ですが、ここに配置するとファイルのサイズが大きすぎるということでLambda上でコードの修正ができなくなってしまいます。
それを解決するために、EFS内に libonnxruntime.soを配置しました。
そして、「libonnxruntime.soファイルを実行場所に配置する」というルールを回避するための方法が上記コードです。
voicevox_coreのライブラリをimportする前に書く必要があります。
core = VoicevoxCore(open_jtalk_dict_dir=Path("/mnt/efs/voicevox_core/open_jtalk_dic_utf_8-1.11"))
Open JTalkの辞書データをEFSの中に配置したので、配置場所を指定しています。
Lambdaのファイルシステムでローカルマウントパスを/mnt/efs
としているためその場所からのパスを書いています。
S3
LINEでボイスメモとして送信する場合、音声ファイルのURLが必要になります。
そのために音声ファイルの格納先として使用しています。
もちろん閲覧権限がなければ再生できませんので、権限を空けておきます。
音声データをS3にアップロードするときのコード
# S3へのアップロード処理
s3_client = boto3.client('s3')
s3_client.put_object(Key="S3のオブジェクト名にしたい名前(.wav)", Bucket='バケット名', Body=音声バイナリデータ)
ネットワーク関係
LambdaとEFSを接続する場合、VPC内にLambdaを入れる必要があります。
ただ、VPC内に入れるとプライベートネットワークになってしまうため外部インターネットに接続ができず、Assistants APIへの送信やLINEへの返信ができなくなります。
その解決策としてはNATGatewayが有名ですが、料金を抑えたいという理由で今回はElastic Network Interfaceに直接Elastic IPを設定するという方法で行いました。
- 先にElastic IPを1つ作成しておきます
- EC2のサイドメニューからネットワークインターフェースを開きます
- LambdaでVPCの設定を行っている場合、LambdaのElastic Network Interfaceが作られているはずなので、右クリック→アドレスの関連付けから作成したElastic IPを紐づけます
AWS以外
LINE
LINE公式アカウントのMessagingAPIを使用しています。
MessagingAPIのURLの設定をLambdaのURLに設定するだけです。
ボイスメッセージとして返信するときのコード
import json
import requests
post_message_url = 'https://api.line.me/v2/bot/message/reply'
# リクエストヘッダ
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + [LINEチャンネルのアクセストークン]
}
# リクエストボディ
bodys = {
'replyToken': [LINEからのリクエストの中に入っているreplyToken]
'messages': [{'type': 'audio', 'originalContentUrl': audio_url, 'duration': [音声データの長さ(ミリ秒)]}]
}
# 送信
response = requests.post(post_message_url, headers=headers, data=json.dumps(bodys))
Assistants API
OpenAIのAPIです。
カスタマイズされたChatGPTを作成することができ、APIから呼び出せます。
基本的にはこちらの記事に書いている通りに実装していますが、AssistantはLambda内で作成せず、残しておいたAssistantを呼び出すという形で実行しています。
Assistant IDの確認や設定の確認はこちらからできます。
おわりに
今回はLINEとAssistants APIとVOICEVOXを組み合わせたシステムについてご紹介しました。
LambdaからEFSへの接続やVPC Lambdaから外部インターネットへの接続など、今まで行ったことのないものもあり色々と勉強になりました。
今回作成したLINE公式アカウントのURLを公開します。
以下の規約をお読みの上ご使用ください。
- 予告なく公開を終了することがあります
- 常識の範囲内でのご使用をお願いします
- OpenAIの利用規約を遵守してください
- メモリ不足等の原因で返信が無いことがありますがご了承ください(Assistants APIからの回答の文章が長くなっている可能性がありますので、短い文章になるように送信し直してください)
ブルーミーちゃんURL(公開終了しました)