GPT Index でのHuggingFaceの埋め込みモデルの利用
「GPT Index」でのHuggingFaceの埋め込みモデルの利用方法をまとめました。
前回
1. sbert-jsnli-luke-japanese-base-lite
「GPT Index」のデフォルトの埋め込みモデルは「text-embedding-ada-002」です。これは有料なので、無料のHuggingFaceの埋め込みモデルに切り替えようと思います。
oshizoさんが埋め込みモデルを公開してくれたので、これを使わせてもらいました。
2. ドキュメントの準備
はじめに、チャットボットに教える専門知識を記述したドキュメントを用意します。
今回は、マンガペディアの「ぼっち・ざ・ろっく!」のあらすじのドキュメントを用意しました。
・bocchi.txt
3. Colabでの実行
Google Colabでの実行手順は、次のとおりです。
(1) パッケージのインストール。
# パッケージのインストール
!pip install gpt-index
!pip install sentence_transformers
(2) 環境変数の準備。
以下のコードの <OpenAI_APIのトークン> にはOpenAI APIのトークンを指定します。(有料)
import os
os.environ["OPENAI_API_KEY"] = "<OpenAI_APIのトークン>"
(3) Colabにdataフォルダを作成してドキュメントを配置。
左端のフォルダアイコンでファイル一覧を表示し、右クリック「新しいフォルダ」でフォルダを作成し、ドキュメントをドラッグ&ドロップします。
(4) 埋め込みモデルの準備。
from langchain.embeddings import HuggingFaceEmbeddings
from gpt_index import LangchainEmbedding
# 埋め込みモデルの準備
embed_model = LangchainEmbedding(HuggingFaceEmbeddings(
model_name="oshizo/sbert-jsnli-luke-japanese-base-lite"
))
(5) インデックスの生成。
from gpt_index import GPTSimpleVectorIndex, SimpleDirectoryReader
from gpt_index.indices.prompt_helper import PromptHelper
# ドキュメントの読み込み
documents = SimpleDirectoryReader('data').load_data()
# インデックスの生成
index = GPTSimpleVectorIndex(
documents=documents,
prompt_helper=PromptHelper(
max_input_size=4000, # LLM入力の最大トークン数
num_output=256, # LLM出力のトークン数
chunk_size_limit=2000, # チャンクのトークン数
max_chunk_overlap=0, # チャンクオーバーラップの最大トークン数
separator="。" # セパレータ
),
embed_model=embed_model, # 埋め込みモデル
verbose=True
)
> Adding chunk: 結束バンド
後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、中学時代にテレビのイ...
> Adding chunk: ひねくれ者なヨヨコは、結束バンドをライバル視しながらも、彼女たちにアドバイスを送り、ファンたち...
> Adding chunk: 姉の伊地知星歌の影響で、バンド活動にあこがれるようになり、「結束バンド」を結成する。バンドでは...
> Adding chunk: 山田リョウを慕っており、彼女に近づくためギターが弾けるとウソをついて、結束バンドに加入した。し...
> Adding chunk: 日本のアニメや漫画が大好きで、「コミマ」に参加するために3年前に来日し、音楽活動を始めた。ギタ...
> Adding chunk: 向上心は旺盛であるため、努力して現在の地位にまで上り詰めたが、未だにライブ前は緊張して眠れなく...
> Adding chunk: 映像制作の勉強をしているため、結束バンドがMVを制作する際に伊地知虹夏から依頼され、1号と共に...
> Adding chunk: ひとりは完熟マンゴー仮面がない場合は、ゴミ箱やトランクを代用品としてかぶってひきこもろうとする...
> [build_index_from_documents] Total LLM token usage: 0 tokens
> [build_index_from_documents] Total embedding token usage: 14600 tokens
8個のチャンクに分割されたことがわかります。
(6) 質問応答の実験1
最初のあらすじの文章を抽出して回答。正解。
print(index.query(
"ひとりちゃんの得意な楽器は?",
verbose=True
))
> Top 1 nodes:
> [Node 12c27073-5129-4217-bba3-c26c52a63206] 結束バンド
後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、中学時代にテレビのインタビューを見て、陰キャでもバンドを組んでいれば人気者になれると聞き、ギターの練習を始める。ひとりは...
> Searching in chunk: 結束バンド
後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、中学時代にテレビのイ...
> Initial response:
後藤ひとりちゃんの得意な楽器はギターです。中学時代にテレビのインタビューを見て、陰キャでもバンドを組んでいれば人気者になれると聞き、ギターの練習を始めたということから、ギターが得意な楽器であることがわかります。
> [query] Total LLM token usage: 2173 tokens
> [query] Total embedding token usage: 25 tokens
後藤ひとりちゃんの得意な楽器はギターです。中学時代にテレビのインタビューを見て、陰キャでもバンドを組んでいれば人気者になれると聞き、ギターの練習を始めたということから、ギターが得意な楽器であることがわかります。
(7) 質問応答の実験2
「ひねくれ者なヨヨコ?」は怪しみましたが、同じチャンク内にひとりちゃんのプロフィールがありました。正解。
print(index.query(
"文化祭で何が起きた?",
verbose=True
))
Top 1 nodes:
> [Node 167b5518-9cc0-4809-9913-d9847abffe76] ひねくれ者なヨヨコは、結束バンドをライバル視しながらも、彼女たちにアドバイスを送り、ファンたちの助けもあってMVを完成させる。デモ審査の結果が出るのを待つばかりとなり、新たな春を迎える。ひとりた...
> Searching in chunk: ひねくれ者なヨヨコは、結束バンドをライバル視しながらも、彼女たちにアドバイスを送り、ファンたち...
> Initial response:
文化祭で、結束バンドは機材トラブルというアクシデントに見舞われながらも、アドリブでボトルネック奏法を行い、ライブを成功に導いた。後藤ひとりは、文化祭で父親から借りたギターを壊してしまった。
> [query] Total LLM token usage: 2195 tokens
> [query] Total embedding token usage: 19 tokens
文化祭で、結束バンドは機材トラブルというアクシデントに見舞われながらも、アドリブでボトルネック奏法を行い、ライブを成功に導いた。後藤ひとりは、文化祭で父親から借りたギターを壊してしまった。
(8) 質問応答の実験3
「山田リョウを慕って…」は怪しみましたが、同じチャンク内にきくりさんのプロフィールもありました。正解。
print(index.query(
"ベースのうまい人は?",
verbose=True
))
> Top 1 nodes:
> [Node c2a3b54e-d007-4c09-9682-5a974115ec7e] 山田リョウを慕っており、彼女に近づくためギターが弾けるとウソをついて、結束バンドに加入した。しかし、土壇場で怖くなって逃げ出しており、そのまま音信不通になっていた。ひとりがギターを弾いている姿を...
> Searching in chunk: 山田リョウを慕っており、彼女に近づくためギターが弾けるとウソをついて、結束バンドに加入した。し...
> Initial response:
ベースをうまく弾ける人は廣井きくりです。
> [query] Total LLM token usage: 2081 tokens
> [query] Total embedding token usage: 12 tokens
ベースをうまく弾ける人は廣井きくりです。
4. インデックスの保存
現状版 (0.2.7) では、インデックス保存でエラーが発生しました。
対応方法は以下の記事が参考になります。