4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

個人開発エンジニア応援 - 個人開発の成果や知見を共有しよう!-

ローカルLLMを用いて霧雨魔理沙とおしゃべりできるlinebotを作った話②linebot編

Last updated at Posted at 2023-09-23

宣伝

「おしゃべり魔理沙AI」という霧雨魔理沙とおしゃべりできるline-botを作りました。
よかったら遊んでみてください。

S_gainfriends_2dbarcodes_GW.png

作者のお財布事情とlinebotとの兼ね合いにより、通算で月200回しか使えないです。
「動かないな」と思ったら、そういうことです。
赤字垂れ流しなので許してください。

output.gif

概要

ローカルLLMをファインチューニングして、東方projectというゲームに出てくる霧雨魔理沙とおしゃべりできるlinebotを作りました。
Qiitaの記事としては「①モデル編」と「②linebot編」の2つになります。

まず最初に「①モデル編」からよむことをおすすめします

「②linebot編」では「①モデル編」でつくった「おしゃべり魔理沙モデル」をどうlinebotに組み込んだのかについて話をしていきます。

詳細

全体像について

image.png

全体像は上の画像を御覧ください。
AWSのlambdaを中心にlinebotを作りました。

  • linebot
  • lambda
  • dynamoDB

のそれぞれについて軽く説明していきます。

linebotについて

linebotとlambdaを組み合わせる手法については、すでにわかりやすい既存の記事がいくつか出ているため、説明を省略します。
簡単に説明しますと、line上にユーザーからの投稿があると、webhookを通じてlambdaが起動します。
次にlambdaでapiを叩くことで、lineにbotが返信を投稿します。

lambdaについて

lambdaとはイベント(今回はlineの投稿)が起こったときに、特定のプログラム(今回はモデル推論とlineの返信)をサーバーレスで行ってくれるサービスです。

モデルファイルの参照方法

今回はlambdaでモデルを推論させるため、lambda上でモデルを読み込めるようにする必要があります。
lambda上でファイルを参照するためには下表の手法があります。

手法 サイズ上限 lambda以外の料金
zipファイルを直接アップロード 250MB なし
ECR経由でdocker環境を反映 10GB ECRの利用料
EFSなどにファイルをあげ、モデル読み込みのたびにそこを参照 なし EFSの利用料

今回は、この中でECRを用いる手法を選びました。
「zipファイルを直接アップロード」は250MBしかアップロードできないのでLLMは当然動きません。
「EFSなどにファイルをあげ、モデル読み込みのたびにそこを参照」はサイズ制限はないものの、ファイルの読み書きごとに課金されるため、lambdaがコールドスタートする度に数GB分の課金がなされます。
そのため、利用を見送りました。
(最初はそこに気づかず2000円くらい溶かした)

10GBにどう抑えたか

「ECR経由でdocker環境を反映」を選んだ場合、docker自体のサイズを10GBに抑える必要があります。
japanese-novel-gpt-j-6bのファイルサイズを確認してみましょう
11GBです。
残念ながらこのままでは、どう頑張ってもdockerのサイズが10GBを超過します。

ファイルサイズを抑える手法として

  • CTranslate2
  • インストールするpytorchをcpuのみにする

の2つを行いました。

CTranslate2

CTranslate2とは既存の巨大モデルを量子化&CPUに最適化することで、コンパクト&高速に推論できるようにするライブラリです。
これを用いて「おしゃべり魔理沙モデル」をint8に変換したところ11GBが6GBになりました。
(ただ、これを施すと精度が落ち、返答が印象として無愛想になるので、できれば使いたくない)

インストールするpytorchをcpuのみにする

上記のことをしても、まだ10GBを超過していました。
理由としては、Pytorchのライブラリの巨大さです。
デフォルトのPytorchのインストールでは、CPU推論用のコードとGPU推論用のコードの両方が入っています。
lambdaではCPU推論しかできないため、GPU推論用のコードは余分です。
なので、インストールしないようにすることで容量の削減をしました。

やり方としては
requirements.txtのtorchを

torch==1.13.1+cpu

のように書けばOKです。
これだけで数GBの容量を節約できます。

コールドスタート問題

awsのlambdaにはコールドスタートとウォームスタートの二種類のスタート方法があります。
コールドスタートとは新しく環境自体をたちあげるスタート方法ことで、ウォームスタートはすでにある環境から実行関数を実施するスタート方法です。
lambdaは自動的に環境が落ちるため、基本的には「しばらく放置するとコールドスタート」「直近の利用があるとウォームスタート」と考えていいでしょう。

CTranslate2を導入したこともあり、モデルの推論は自体は数秒で終わります。
しかしながら、モデルをメモリに載せる(モデルの読み込み)のところで数分の処理時間がかかります。
そのため、lambdaがコールドスタートするとlineの応答が数分かかる自体になってしまいます。
linebotで返信が数分待ちはなかなかしんどいところがあるので、何か対策を考えたいものです。

コールドスタートの問題をマシにする手法として以下の3つの手法が挙げられます。

  • Provisioned Concurrencyを使う
  • snapstartを使う
  • 定期的にlambdaを実行する

それぞれについて説明していきます

Provisioned Concurrency

Provisioned Concurrencyとはlambda環境を常にウォームスタート状態にする設定項目のことです。
これを使うのが一番正統派な解決方法だと思います。
しかし、通常のLambdaの利用料金に加え、追加で時間あたりでコストがかかります。
そこそこの額がかかるため、今回は利用を見送りました。

snapstartを使う

環境自体をキャッシュにして保存することで、コールドスタートの時間を短くしてくれるオプションです。
無料でつかえるみたいなのですが、まだjavaでしか使えないようです。
残念。

定期的にlambdaを実行する

定期的にlambda関数を実行してあげることで、コールドスタートになるずらくします。
この方法は確実性がなく、5分に一度起動していても1時間に1回くらい落ちます。
しかし、Provisioned Concurrencyよりもは価格はかからなそうでした。

なので今回はeventbrifgeをlambdaと組み合わせることで、定期的にlambdaを読み出して、コールドスタートを防ぐ手法を採用しました。

dynamoDBについて

魔理沙の発言を推論させるに当たり、過去の会話ログをプロンプトに入れたほうが精度が良くなります。
具体的に言うと、過去の会話ログをプロンプトに含めると

ユーザー: 好きな食べ物は?
魔理沙: 肉だ
ユーザー: それのどんなところが好き?
魔理沙: 味だな

のような会話ができるようになります。

そのため、過去の会話ログを記録するデータベースと紐づけました。

まとめ

linebotに既存の言語モデルをどう組み込むかについて説明しました。
みなさんもお気に入りのキャラクターを公開してみてはいかがでしょうか。

4
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?