ChatGPTを使った文書の学習システムをサーバーレスで作ってみる

自己紹介

  • 夏目 祐樹 (ナツメ ユウタ)
  • クラスメソッド株式会社
    • 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

作りたいもの

  • Developers IOの記事を収集する仕組みを作ったので、学習させる仕組みも実装したい

[9005514175400231] luciferous-devio-index(1)

完成してません

言い訳 (1)

  • Developers IOの記事を約40,500件を仕組みとは別に学習させようとしてみた
  • エラーが色々出てうまく動かなかった
    1. EC2上でしてみた -> 学習開始から3日後、文字列を解釈するライブラリでエラー
    2. GlueのPython Shell Jobでやってみた -> 学習開始から2日後、学習したデータをzip圧縮しようとしたらメモリ超過でエラー
    3. 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

Python Shell Jobに独自のコードを追加したい場合 (3)

[9005514170190088] スクリーンショット 2023-05-26 16.02.17

Python Shell Jobに独自のコードを追加したい場合 (4)

  • setup.pyを書くのはちょっと面倒
    • 依存ライブラリはどう書くの?
  • ということで自分はpoetryというPythonのツールを使った

poetryって何?

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

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のリリースで使えるようになった!

[9005514167566974] スクリーンショット 2023-05-26 16.45.57

今後進めること

  • 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 ブログ

[9005514166728294] ML-13807-image011

そんなことを考えてたら (2)

  • 何をやっているか
    • 文書はKendraに突っ込む
    • LangChainはKendraから必要そうな文書だけを取得する
    • LLMは最小限の文書だけが渡される
  • 実行環境は非常に軽量にできる
    • 実際Lambdaで動いているらしい

そんなことを考えてたら (3)

  • ただ、Kendraは高い
    • 月額800ドル以上 (従量課金)
    • 役目は文書のフィルタリングだからOpenSearch (ElasticSearch)で代用できるかもしれない

[9005514166077727] スクリーンショット 2023-05-26 17.10.50

今後やること

  • KendraやOpenSearchを使った文書検索システムの検証 <- new
  • GlueのPython Shell Jobで6.5GBのindexを扱えるか試す
  • DynamoDBをdocstoreとvector_store, S3をindex_storeにして学習させてみる
  • VectorStoreは色々とサービスがあるのでそっちの利用も考える
    • PineconeとかWeaviateとか色々ある

END

Close