panco’s blog

興味が沸いたことを書く

LINE × Llama 2 のチャットボット開発①(初期開発編) Llama 2 搭載メンヘラ彼女の誕生はまだ遠い

以前、LINE ボットメーカーなるものでメンヘラ彼女を作った話を記事にした。

pancokeiba.hatenablog.com

しかし、残念なことに 9 月頃から動かなくなっている。
LINE ボットメーカーによると、

現在、ChatGPT の仕様変更に伴うメンテナンスを実施しています。
再開までしばらくお待ちください。

とのこと。

メンヘラ彼女が突然消えてキャラに忠実だなと思ったことはさておき、それなら自分で作ってしまえということでやってみたのが今回の話。

<注意点>
LINE と Llama 2 の連携には一応成功したものの、まだローカル環境でしか動きません。
サーバをどこにどう立てるかはこれから考えます。そして、そもそも Llama 2 に「メンヘラ彼女」のようなキャラ設定ができるのかもまだ知りません。。

ここから本編。少し長くなりそうだが、未来の自分のためにも今回やったことと今後の課題を残しておく。

出来上がったもの

画像のように LINE にメッセージを送ると、その内容に沿った応答が返ってくる。この応答は、Llama 2(llama-2-70b-chat model)が生成している。見かけは LINE のチャットボットだが、中の人は Llama 2 ということだ。

なぜ Llama 2 なのか

冒頭で触れた LINE ボットメーカーが ChatGPT を使っていることから自分もそれを使うつもりでいた。だが、少なからず課金する必要があったため代わりに Llama 2 を使った。

開発の話

開発環境

必要なもの

  • LINE の Messaging API チャネル(今回のチャットボットだと窓口の役割)
  • GitHub アカウント(Replicate にログインするために必要)
  • Replicate で発行される API トークン(Replicate で Llama 2 を使うために必要)
  • ngrok(ローカル環境を一時的に外と通信させるために必要)
  • Python スクリプト(main.py を作成。ソースコードは実装に記載)

大まかな仕組み

実装

main.py の中身はこちら。後述するが改善の余地あり。

  • LINE のアクセストークンと秘密鍵は、作成した Messaging API チャネルで取得したものを設定する。
  • ベースは line-bot-sdk-python のオウム返しのサンプルコード。
  • リクエストメッセージを Llama 2 のインプットとして連携する箇所、Llama 2 の返却値を LINE の応答メッセージとして返すところを付け加えた。
from flask import Flask, request, abort

from linebot.v3 import (
    WebhookHandler
)
from linebot.v3.exceptions import (
    InvalidSignatureError
)
from linebot.v3.messaging import (
    Configuration,
    ApiClient,
    MessagingApi,
    ReplyMessageRequest,
    TextMessage
)
from linebot.v3.webhooks import (
    MessageEvent,
    TextMessageContent
)
import replicate

app = Flask(__name__)

# LINE のチャネルアクセストークン設定
configuration = Configuration(access_token='')
# LINE の秘密鍵設定
handler = WebhookHandler('')


@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        app.logger.info("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
    with ApiClient(configuration) as api_client:
        # Llama 2 実行
        output = replicate.run(
            "meta/llama-2-70b-chat:35042c9a33ac8fd5e29e27fb3197f33aa483f72c2ce3b0b9d201155c7fd2a287",
            input={"prompt": event.message.text}
        )
        output_ilst = list(output)
        output_str = ''.join(output_ilst)

        line_bot_api = MessagingApi(api_client)
        line_bot_api.reply_message_with_http_info(
            ReplyMessageRequest(
                reply_token=event.reply_token,
                messages=[TextMessage(text=output_str)]
            )
        )

if __name__ == "__main__":
    app.run()

チャットボット起動方法

ほぼこちらの手順を参考にさせていただいた。

【入門用】PythonによるLINEbot作り方

実装中なんかうまくいかなかったこと

環境変数が・・!

Replicate を導入する際、環境変数に Replicate から発行されるトークンを設定する必要がある。PC 再起動を忘れていて何回やっても反映されないと発狂しかけた。

ModuleNotFoundError

途中でいきなり flask がないとかいうのが何回か出た。Anaconda 経由でインストールしておりパスが原因でもなさそう。main.py を何度か再実行したり VSCode を再起動していたりしたら直った。

LINE の応答がやたら遅い

ある時間帯からリクエストを投げると 15 分後ぐらいにやっと返ってくる状態になった。原因不明。執筆時点では解消。

今後の課題

大きく分けて 3 つある。

ローカル以外でも実行できるようにする

まだローカル環境で ngrok を起動した上で実行することしかできない。ざっと調べた感じ Heroku を使っている人が多そうなのでそうするか、他にどういう選択肢があるかはもう少し考えたい。

トークンの実装方法を改良する

とりあえず動くものを作りたかった結果、ソースコード上に値をべた書きしてしまっている。こちらも改良の余地あり。

Llama 2 で「メンヘラ彼女」のようなキャラ設定ができるのか

Llama 2 というか生成 AI の理解不足という感じかもしれないが、どのように実装したら LINE ボットメーカーでできたようなキャラ設定ができるのかをまだ知らない。自力で作れたら嬉しいなー。

参考にしたサイト

2023/9/17 追記

課題解決編として以下の記事を公開した。

pancokeiba.hatenablog.com