スライド/ChatGPTを使った文書の学習システムをサーバーレスで作ってみる version 40
:追加された部分
:削除された部分
(差分が大きい場合、文字単位では表示しません)
スライド/ChatGPTを使った文書の学習システムをサーバーレスで作ってみる
## 自己紹介
- 夏目 祐樹 (ナツメ ユウタ)
- クラスメソッド株式会社
- CX事業本部 Delivery部
- 自称 サーバーレスエンジニア
- 好きなAWSサービス
- Lambda, DynamoDB, SQS, Glue
- 最近やってるゲーム
- FF14 (極ゴルベーザ討滅戦、勝てない)
- 崩壊スターレイル (均衡レベル5になったけど、育成素材が足りない)
## 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もできる
## 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 <em.s.00001@gmail.com>"]
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)で代用できるかもしれない
![[9005514166218114] スクリーンショット 2023-05-26 17.08.27](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/59d44011-99ae-444f-9333-0dd17ef7dbcc.png)
![[9005514166077727] スクリーンショット 2023-05-26 17.10.50](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/e44f43e8-16f6-4dde-a8b0-3f7afcd1d2d4.png)
自己紹介
- 夏目 祐樹 (ナツメ ユウタ)
- クラスメソッド株式会社
- CX事業本部 Delivery部
- 自称 サーバーレスエンジニア
- 好きなAWSサービス
- Lambda, DynamoDB, SQS, Glue
- 最近やってるゲーム
- FF14 (極ゴルベーザ討滅戦、勝てない)
- 崩壊スターレイル (均衡レベル5になったけど、育成素材が足りない)
LlamaIndexについて (1)
- https://gpt-index.readthedocs.io/en/latest/
- https://github.com/jerryjliu/llama_index
- LLMは大量の公開情報で学習されている
- LLMをプライベートデータで強化するためのFrameworkがLlamaIndex
- OpenAIのLLMを使用することもできる
- 既存のデータソースとデータ形式を取り込むためのコネクタ
- データ(インデックス、グラフ)を簡単に使用保存するための方法
LlamaIndexについて (2)
作りたいもの
- Developers IOの記事を収集する仕組みを作ったので、学習させる仕組みも実装したい
完成してません
言い訳 (1)
- Developers IOの記事を約40,500件を仕組みとは別に学習させようとしてみた
- エラーが色々出てうまく動かなかった
- EC2上でしてみた -> 学習開始から3日後、文字列を解釈するライブラリでエラー
- GlueのPython Shell Jobでやってみた -> 学習開始から2日後、学習したデータをzip圧縮しようとしたらメモリ超過でエラー
- 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ができてしまった
- なんで?
- 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)
公式のドキュメントに書いてある方法
Python Shell Jobに独自のコードを追加したい場合 (3)
Python Shell Jobに独自のコードを追加したい場合 (4)
- setup.pyを書くのはちょっと面倒
- 依存ライブラリはどう書くの?
- ということで自分はpoetryというPythonのツールを使った
poetryって何?
- pythonのパッケージ管理ツール
- pipenvとほぼ同等の機能を持つ
- pipenvとは異なり、パッケージのbuildやpublishもできる
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 <em.s.00001@gmail.com>"]
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実行環境
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されてた
DynamoDBをStorageに使うPRを出した
Add DynamoDB Store by sinofseven · Pull Request #3765 · jerryjliu/llama_index
mergeされて、v0.6.11のリリースで使えるようになった!
以上を踏まえて今後進めること
- 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 ブログ
そんなことを考えてたら (2)
- 何をやっているか
- 文書はKendraに突っ込む
- LangChainはKendraから必要そうな文書だけを取得する
- LLMは最小限の文書だけが渡される
- 実行環境は非常に軽量にできる
- 実際Lambdaで動いているらしい
そんなことを考えてたら (3)
- ただ、Kendraは高い
- 月額800ドル以上 (従量課金)
- 役目は文書のフィルタリングだからOpenSearch (ElasticSearch)で代用できるかもしれない