--- Title: ChatGPTを使った文書の学習システムをサーバーレスで作ってみる Author: sinofseven Web: 'https://mimemo.io/m/M2rKBGzb53GD0Em' --- ## 自己紹介 - 夏目 祐樹 (ナツメ ユウタ) - クラスメソッド株式会社 - CX事業本部 Delivery部 サーバーサイドチーム - 自称 サーバーレスエンジニア - 好きなAWSサービス - Lambda, DynamoDB, SQS, Glue - 最近やってるゲーム - FF14 (極ゴルベーザ討滅戦、勝てない) - 崩壊スターレイル (均衡レベル5になったけど、育成素材が足りない) ## [自己紹介] 夏目 祐樹 (ナツメ ユウタ) - クラスメソッド株式会社 - CX事業本部 製造ビジネステクノロジー部 - 自称 サーバーレスエンジニア - 好きなAWSサービス - Lambda, DynamoDB, SQS, Glue - 最近やってること - FF14 (06/28から始まる7.0に向けての準備を加速しないと) - 崩壊スターレイル (黄泉引けたけど育成やPT構築が進まない) - 個人開発 (複数, ReactとServerlessで作ることが多い) ## LlamaIndexについて (1) - https://gpt-index.readthedocs.io/en/latest/ - https://github.com/jerryjliu/llama_index - LLMは大量の公開情報で学習されている - LLMをプライベートデータで強化するためのFrameworkがLlamaIndex - OpenAIのLLMを使用することもできる - 既存のデータソースとデータ形式を取り込むためのコネクタ - データ(インデックス、グラフ)を簡単に使用保存するための方法 ## LlamaIndexについて (2) ![[9005514175731682] スクリーンショット 2023-05-26 14.29.42](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/9614b200-81d6-4743-9712-2e2e35666fe8.png) ## 作りたいもの - Developers IOの記事を収集する仕組みを作ったので、学習させる仕組みも実装したい ![[9005514175400231] luciferous-devio-index(1)](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/e51613aa-ca9d-4f21-8ff2-7de038f39545.png) ## 完成してません ## 言い訳 (1) - Developers IOの記事を約40,500件を仕組みとは別に学習させようとしてみた - エラーが色々出てうまく動かなかった 1. EC2上でしてみた -> 学習開始から3日後、文字列を解釈するライブラリでエラー 1. GlueのPython Shell Jobでやってみた -> 学習開始から2日後、学習したデータをzip圧縮しようとしたらメモリ超過でエラー 1. GlueのPython Shell Jobでやってみた -> 学習開始の翌日、学習したデータをJSON化しようとしたらメモリ超過でエラー ## 言い訳 (2) - 家のGaming PCにWSL2の環境を構築し、メモリ26GBを使えるようにして学習させた - 2日で学習は完了した - 完了したが吐き出されたデータは約6.5GBあった - これをサーバーレスで扱うには色々考慮する必要がある ## どう学習させていくか - Indexのファイルを維持する - GlueのPython Shell Job (もともと使う予定だったやつ) - Fargate - Indexのファイルを諦める - ローカル以外の場所をLlamaIndexのストレージとして利用する ## GlueのPython Shell Job - AWSのサーバーレスなコンピュートリソースの一つ - Glue JobではPython Shell Jobの他にSpark Jobもある - 計算能力は1DPUもしくは0.0625DPU (1/4 DPU) - 1DPU = 4つのvCPUと16GBのメモリ - Python Shell JobではPython3.6かPython 3.9のどちらかを使用できる - タイムアウトは多分青天井 - 100年を設定してみたら何故かJob DetailのUpdateができてしまった - なんで? ## Python Shell Jobで使えるライブラリ - ある程度のライブラリははじめからインストールされている - Python 3.9 - ライブラリセット: 分析 (一部抜粋) - `awscli==1.23.5`, `botocore==1.23.5`, `boto3==1.22.5`, `awswrangler==2.15.1`, `pandas==1.4.2` - ライブラリセット: なし (ここに書いたライブラリのみ) - `awscli==1.23.5`, `botocore==1.23.5` ## Python Shell Jobでライブラリを追加したい場合 - `--additional-python-modules`というJobパラメータを追加すれば実行時にインストールしてくれる - 例) ``` --additional-python-modules boto3==1.26.133 botocore==1.29.133 awscli==1.27.133 llama-index==0.6.6 ``` ## Python Shell Jobに独自のコードを追加したい場合 (1) - 外部ライブラリの他に、自分で書いた複数のコードを使いたいことはよくある - `.whl`ファイルとしてパッケージングしてS3 Bucketに保存し、Jobパラメータ `—extra-py-files`にS3 URIを記述してあげれば使える ## Python Shell Jobに独自のコードを追加したい場合 (2) 公式のドキュメントに書いてある方法 ![[9005514170306939] スクリーンショット 2023-05-26 16.00.03](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/96cd970c-b949-40bc-9d5e-0426c30806bf.png) ## Python Shell Jobに独自のコードを追加したい場合 (3) ![[9005514170190088] スクリーンショット 2023-05-26 16.02.17](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/611d0f1d-2425-4d05-90e3-19f5e3ee870e.png) ## Python Shell Jobに独自のコードを追加したい場合 (4) - setup.pyを書くのはちょっと面倒 - 依存ライブラリはどう書くの? - ということで自分はpoetryというPythonのツールを使った ## poetryって何? - pythonのパッケージ管理ツール - pipenvとほぼ同等の機能を持つ - pipenvとは異なり、パッケージのbuildやpublishもできる - pipenvとpoetryの違い等はここに詳しく書いてある - [pipとpipenvとpoetryの技術的・歴史的背景とその展望 - Stimulator](https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715) ## poetryでPythonのパッケージを作る (1) 依存ライブラリとして`llama-index==0.6.11`を追加する。 ``` $ poetry new test_package --src $ cd test-package $ poetry add llama-index==0.6.11 $ echo << EOS >> src/test_package/__init__.py >def test(): > print('test') >EOS $ poetry build ``` ## poetryでPythonのパッケージを作る (2) ``` $ find . | sort . ./README.md ./dist ./dist/test_package-0.1.0-py3-none-any.whl ./dist/test_package-0.1.0.tar.gz ./poetry.lock ./pyproject.toml ./src ./src/test_package ./src/test_package/__init__.py ./tests ./tests/__init__.py ``` ## poetryでPythonのパッケージを作る (3) ``` $ cat pyproject.toml [tool.poetry] name = "test-package" version = "0.1.0" description = "" authors = ["sinofseven "] readme = "README.md" packages = [{include = "test_package", from = "src"}] [tool.poetry.dependencies] python = "^3.9" llama-index = "0.6.11" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" ``` ## Fargateを使う場合 - 現時点でIndexのサイズが6.5GBもある - GlueのPython Shell Jobではメモリが足りなくなることもあり得る - その場合はFargateを使うしかなくなる - マネージドのContainer実行環境 ![[9005514168993351] スクリーンショット 2023-05-26 16.21.53](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/4e512ef5-330c-404c-a2be-248fb194f27e.png) ## Fargateを使うには - ECS上でECS Taskとして動かすかAWS Batchで動かすしかない - ただ、検討だけで何も作ってないからこれ以上何も言えない - 実行状況を管理する上ではECS Taskの方が都合よさそう ## IndexをJSONとして保存することを諦める ## llama-indexのStorageの話 (1) - llama-indexでは色々とin-memoryのストレージの他にデータを保持させるストレージを構築できる - llama-indexのストレージでは3つのstoreを設定する - docstore: 文書を生で保存する - index_store: indexの情報を保存する - vector_store: 文書をvector化したデータを保存する ## llama-indexのStorageの話 (2) - デフォルトではそれぞれ、SimpleDocumentStore, SimpleIndexStore, SimpleVectorStoreが使用される - in-memoryのStore - JSONやdictでの出力ができる - つまりKey-Valueで保存している - SimpleDocumentStore, SimpleIndexStoreは内部的にKVStoreを使用している - 内部的には`Dict[str, Dict[str, dict]]`でデータを保持してる - SimpleVectorStoreも `Dict[str, List[float]]`と`Dict[str, str]`で保持してる ## llama-indexのStorageの話 (3) - Key-Value Storeで保存しているということは、DynamoDBやS3を使用することができる - 実際、MongoDBは既に実装されていた - 失敗したDevIOの記事の学習中に色々試してみた - DynamoDB, S3をdocstoreやindex_storeに使う実装もできた - index_storeはDynamoDBよりS3の方が向いてそうなのもわかった - といってたら、S3をKV StoreにするPRが出ててmainにmergeされてた - [Add S3 KV store by sourabhdesai · Pull Request #3379 · jerryjliu/llama_index](https://github.com/jerryjliu/llama_index/pull/3379) ## DynamoDBをStorageに使うPRを出した [Add DynamoDB Store by sinofseven · Pull Request #3765 · jerryjliu/llama_index](https://github.com/jerryjliu/llama_index/pull/3765) mergeされて、v0.6.11のリリースで使えるようになった! ![[9005514167566974] スクリーンショット 2023-05-26 16.45.57](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/0c592bd2-caaf-42fb-a6e6-3bc8ad7c927a.png) ## 今後進めること - GlueのPython Shell Jobで6.5GBのindexを扱えるか試す - DynamoDBをdocstoreとvector_store, S3をindex_storeにして学習させてみる - VectorStoreは色々とサービスがあるのでそっちの利用も考える - PineconeとかWeaviateとか色々ある ## そんなことを考えてたら (1) [高精度な生成系 AI アプリケーションを Amazon Kendra、LangChain、大規模言語モデルを使って作る | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/quickly-build-high-accuracy-generative-ai-applications-on-enterprise-data-using-amazon-kendra-langchain-and-large-language-models/) ![[9005514166728294] ML-13807-image011](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/a081b863-b5a1-4890-9f35-6be46252ddba.png) ## そんなことを考えてたら (2) - 何をやっているか - 文書はKendraに突っ込む - LangChainはKendraから必要そうな文書だけを取得する - LLMは最小限の文書だけが渡される - 実行環境は非常に軽量にできる - 実際Lambdaで動いているらしい ## そんなことを考えてたら (3) - ただ、Kendraは高い - 月額800ドル以上 (従量課金) - 役目は文書のフィルタリングだからOpenSearch (ElasticSearch)で代用できるかもしれない ![[9005514166077727] スクリーンショット 2023-05-26 17.10.50](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/e44f43e8-16f6-4dde-a8b0-3f7afcd1d2d4.png) ## 今後やること - KendraやOpenSearchを使った文書検索システムの検証 <- ***new*** - GlueのPython Shell Jobで6.5GBのindexを扱えるか試す - DynamoDBをdocstoreとvector_store, S3をindex_storeにして学習させてみる - VectorStoreは色々とサービスがあるのでそっちの利用も考える - PineconeとかWeaviateとか色々ある