LLMは、学習時に存在していなかった情報については、それ自身では答えることができません。
そこで登場するのがLlamaIndexです。LlamaIndexは、LLMが学習していない情報を答えさせるためのライブラリです。
LlamaIndexでは、LLMが学習していない情報をドキュメントとして用意し、LLMへの問い合わせ(プロンプト)をそのドキュメントを使って拡張します。
ユーザが与えたプロンプトに、ドキュメントに含まれる情報を付け加えて新たなプロンプトを作成し、それをLLMに与えて回答させることで、あたかもLLM自身がその情報を知っているかのように振舞わせるわけです。
例えですが、株式会社が行う株主総会って、いろいろな質問にうまく回答できるように、事前に膨大な「想定問答集」を作るんですね。そして、総会当日は質問が来ると、その質問に対応する想定問答をスタッフが提示し、それを使って役員が回答します。まあカンニングペーパーシステムです。
それと同じように、LLMにカンニングペーパーシステムを与えてくれるのがLlamaIndexです。
以下の記事を見て、LlamaIndexを実際に動かしてみました。
ChatGPTのAPI(OpenAIのAPI)は、以前にもちょっと動かしていました。その時はLlamaIndexはあまりちゃんと触っていなかったので、今回はその続きのようなものです。
上記の記事はGCLを使っていますが、私は手元のVM(Ubuntu)で動かしてみました。また、カンニングさせる情報の例題として、7月に発行された「令和5年度情報通信白書」を使ってみました。
まず情報通信白書(PDF版)をダウンロードしておきます。
mkdir openai-joho-whitepaper
cd openai-joho-whitepaper/
mkdir data
cd data
wget https://www.soumu.go.jp/johotsusintokei/whitepaper/ja/r05/pdf/00zentai.pdf
cd ..
そしてPythonの仮想環境を作り、必要なパッケージをインストールします。
python -m venv VENV
source ./VENV/bin/activate
pip install llama-index==0.8.59
pip install pypdf
(注:上記の記事の最後のほうにPDFの読み込み方について解説がありますが、それとは別のやり方をしています。これでも一応動くみたいです。)
まず、情報通信白書を検索可能な形式に変換(インデックス化)します。
import os
os.environ["OPENAI_API_KEY"] = "(Place your API key here)"
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)
from llama_index import SimpleDirectoryReader
documents = SimpleDirectoryReader("data").load_data()
from llama_index import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist()
これで準備ができました。質問するのは、JupyterNotebookを使いましょう。
pip install Jupyter
pip install jupyterlab
VENV/bin/jupyter-lab --ip='0.0.0.0'
これでブラウザが立ち上がり、JupyterNotebookが使えるようになりますので、以降はそちらでPythonを実行します。
まず先ほど作成したインデックスをロードします。
import os
os.environ["OPENAI_API_KEY"] = "(Place your API key here)"
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)
from llama_index import VectorStoreIndex
from llama_index import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
query_engine = index.as_query_engine()
では質問タイムです。質問してみます。
print(query_engine.query("5G, 6Gの動向を要約してください。"))
こんな回答が返ってきました。
5Gは現在、商用サービスとして広く使用されており、2020年からは5Gの商用サービスが開始され、普及が進んでいます。一方、6GはBeyond 5Gとして位置付けられており、2030年代に実現が期待されています。6Gは、有線・無線や陸・海・空・宇宙などを包含したネットワーク全体として捉えられ、革新的な高速大容量・低遅延・高信頼・低消費電力の次世代通信インフラを実現することを目指しています。現在、海外の主要企業が5G基地局の市場シェアを占めており、日本企業の国際競争力は低い状況です。そのため、諸外国ではBeyond 5G(6G)における技術優位性を確保するための研究開発投資や計画が進められています。
なるほど、悪くはないですが切り貼り感はありますね。
最後のところなんか、「日本企業の競争力が低い(そのため)諸外国では研究開発投資や計画が進められている」となっていて論理展開が変です。
でもまあ元がお役所の文書ですから、こんなものでしょうか。
もう一つ質問してみます。
print(query_engine.query("生成AIに関してはどのような動きがありますか。"))
生成AIに関しては、検討や議論が各国や国際会議の場で始まっているとのことです。また、AIサービスを提供する事業者側では利用にあたっての規約を定めていますが、利用者自身の活用モラルの向上が必要とされています。さらに、日本では日本人にとって使いやすい生成AIの利用環境の構築や、国民がAI等のデジタルツールを巧みに活用する能力の習得に向けた取組が必要とされています。
ふむふむ。
他のドキュメントとして、Raspberry Pi Picoのマニュアルを食べさせてみたりしましたが、英語のドキュメントについて英語で質問するのが、やっぱり一番、実のある結果が得られる感じがしました。もっとも、これはLlamaIndexが内部で使っているプロンプトテンプレートが英語だからかもしれません。上記の記事には、日本語のテンプレートを設定する方法も解説されています。
LlamaIndexでは、ドキュメントを細切れの「コンテキスト」にして、与えられた質問と関連が深そうなコンテキストを(複数)検索し、プロンプトを拡張します。そのため、コンテキストを検索しやすいようなドキュメントと質問で威力を発揮すると思われます。逆に言うと、論理がしっかりしていて内容が分かりやすい文章を用意しておくことが、結構重要なポイントなのかもしれない、と思いました。
コメント