はじめに
watsonx.aiの基盤モデルで構築するアプリケーションの作り方を検索すると2024年9月現在では、watsonx.ai+LangChainの組み合わせの記事がほとんどを占めます。実際LLMアプリケーションを作り始めたのはLangChainから入門したという方も多いのではないでしょうか?
昨今のLLMアプリケーションの開発はRAGをベースとした開発が多く、RAGにもいろいろな手法/パターンが出てきています。LlamaIndexはRAGに特化したフレームワークとして人気があります。また多くのパターンのライブラリやチュートリアルがllama hubにあり参照する事が可能です。
本記事は、LlamaIndexをwatsonx.aiで"使ってみた"の情報を共有いたします。
本記事から数回に分けてwatsonx.ai + LlamaIndexを使ってみた気づきを書き溜めていく予定です。
今回はLLMに質問をして答えを返すという単純な内容です。
前提
この記事はIBMクラウドのアカウントがありブラウザ上のwatsonx.aiでLLMが実行できていることを前提としています。もしまだLLMをブラウザ上で実行できていない場合は、こちらの記事を参考に使える準備をお願いします。
watsonx.aiのAPIを使うためにはクレデンシャルの方式がいくつかありますが、簡単に検証できるAPIキーを取得する方法で進めます。 APIキー、プロジェクトID、エンドポイントURLの3つの情報が必要です。
対象読者
- watsonx.aiを使ってLLMアプリケーションを作っている。
- watsonx.ai + LangChainは経験あるけど、LlamaIndexで動かしてみたい。
Officialな情報
IBMのDocumentでLangChainとLlamaIndexは、watsonx.aiのPythonライブラリーを操作するサードパーティー製のツールとして紹介されています。以下のリンク内にはgithubのリンクが記載されており、サンプルコードを参照できます。
https://www.ibm.com/docs/ja/watsonx/saas?topic=solutions-python-library#llamaindex
また、LlamaIndexの公式ドキュメントにも"IBM watsonx.ai”の例が載っています。
https://docs.llamaindex.ai/en/stable/examples/embeddings/ibm_watsonx/
プログラムの構成
フォルダ構成
フォルダ構成は以下の様になっています。
llamaindex_sample
├── .venv
├── .env
├── requirement.txt
└── app.py
環境変数は.envに記述
APIキー、プロジェクトID、エンドポイントURLをPython実行環境の環境変数に設定します。
手動で設定しても問題ありませんが、ここでは以下の様に".env"ファイルに書き込みpython-dotenvのload_dotenv()を使って読み込みます。
#IBM Cloudアカウントに紐づくAPI KEY.
API_KEY='<上を参照してAPIキーをここに入力>'
#watsonx.aiのPROJECT_ID
PROJECT_ID='<上を参照してここにプロジェクトIDを入力>'
#watsonx.aiを作成したインスタンスのエンドポイントURL。ここではダラスを指定
WATSONX_URL="https://us-south.ml.cloud.ibm.com/"
# WATSONX_URL="https://jp-tok.ml.cloud.ibm.com" <-Tokyoリージョンの場合はこちらを有効にする
パッケージの導入はrequirement.txtを使用
今回必要なのは以下の3つのパッケージです。
python-dotenv # 環境変数を.envからロードして設定する
llama-index-core>=0.11.10 # LlamaIndexのコアパッケージ
llama-index-llms-ibm>=0.2.0 # watsonx.aiのライブラリパッケージ
requirement.txtを使って一括で導入する方法
以下のコマンドでrequirement.txtで指定したものを一括でインストールします。
ここでは説明をしませんがvenv等の仮想環境を作ってからpipインストールをするとプロジェクトごとの環境を管理しやすいです。
$pip install -r requirement.txt
実行コード
app.pyでは以下を実施しています。シンプルですね。
- 環境変数をセット
- watsonx.ai のLLMを作成
- クエリーを送り結果を出力
# wxai + Llama indexのサンプル
# インポート
import os
from dotenv import load_dotenv
from llama_index.llms.ibm import WatsonxLLM
# 環境変数をセット
# - .envから環境変数をロード
load_dotenv()
# - 環境変数を取得して変数に設定
api_key = os.getenv('API_KEY')
project_id = os.getenv('PROJECT_ID')
url = os.getenv('WATSONX_URL')
# LLMのロード
# - LLMの動作パラメータ
additional_params = {
"decoding_method": "greedy",
"max_new_tokens": 500,
"min_new_tokens": 1,
"top_k": 50,
"top_p": 1,
"repetition_penalty": 1.3
}
# - LLMの定義-LLMのModel IDを選択、認証、接続情報の設定、LLMの動作パラメータ
watsonx_llm = WatsonxLLM(
model_id="meta-llama/llama-3-405b-instruct",
apikey=api_key,
url=url,
project_id=project_id,
additional_params=additional_params,
)
# クエリーの実行と結果の出力
response = watsonx_llm.complete("生成AIについて80文字以内の日本語で解答してください")
print("解答 = " + response.text)
出力結果は以下となります。
解答 = 。
人工知能(じんこうちのう、英: Artificial Intelligence, AI)とは、「人間が持つ学習能力・推論的思考力・問題を解決するための適応性など、高度な知性的情報処理機能を持ったコンピューターシステム」である。
コード解説
少しだけコードを解説します。
importと環境変数の設定
以下はのソースコードはモジュールのインポートと環境変数の設定の部分を抜粋しました。
.envファイルにAPIキーなど必要な環境変数を記載し、load_dotenv()で環境変数に読み込んでいます。
環境変数からos.getenv()で値を取得して変数に読み込んでいます。
# インポート
import os
from dotenv import load_dotenv
from llama_index.llms.ibm import WatsonxLLM
# 環境変数をセット
# - .envから環境変数をロード
load_dotenv()
# - 環境変数を取得して変数に設定
api_key = os.getenv('API_KEY')
project_id = os.getenv('PROJECT_ID')
url = os.getenv('WATSONX_URL')
watsonx.aiのLLMの作成
以下の抜粋はwatsonx_llmにwatsonx.aiのLLMの定義をしています。
model_idに、watsonx.aiのLLMを指定できます。IBMのLLMだけではなく、多くのOSSのLLMを選択することが可能です。その他使用できるLLMはこちらを参照してください。
また環境変数から取得したAPIキー、プロジェクトID、エンドポイントURLも設定しています。
additional_paramsではLLMの実行パラメータをまとめています。
# LLMのロード
# - LLMの動作パラメータ
additional_params = {
"decoding_method": "greedy",
"max_new_tokens": 500,
"min_new_tokens": 1,
"top_k": 50,
"top_p": 1,
"repetition_penalty": 1.3
}
# - LLMの定義-LLMのModel IDを選択、認証、接続情報の設定、LLMの動作パラメータ
watsonx_llm = WatsonxLLM(
model_id="meta-llama/llama-3-405b-instruct",
apikey=api_key,
url=url,
project_id=project_id,
additional_params=additional_params,
)
クエリーを送り結果を取得
LLMのモデルに直接TEXT型のクエリーを送り結果を取得しています。
response.rawでプリントをすればJSON形式で他のメタ情報も取得できます。
# クエリーの実行と結果の出力
response = watsonx_llm.complete("生成AIについて80文字以内の日本語で解答してください")
print("解答 = " + response.text)
まとめ
さて、大変シンプルにLlamaIndexからwatsonx.aiのLLMを呼び出すことができました。
しかしRAGの実装がされていません。
次回はシンプルなRAGの実装を投稿しようと思います。
参考リンク
- https://www.llamaindex.ai/
- https://docs.llamaindex.ai/en/stable/
- https://www.ibm.com/docs/ja/watsonx/saas?topic=solutions-python-library#llamaindex
- https://github.com/IBM/watson-machine-learning-samples/blob/master/cloud/notebooks/python_sdk/deployments/foundation_models/Use%20watsonx%2C%20and%20LlamaIndex%20with%20sql%20querey%20engine.ipynb
- https://qiita.com/ironikot/items/a1ff1423c5c2e7c44876
- https://qiita.com/nishikyon/items/5054209089fc632981f8#1-2-api%E3%82%AD%E3%83%BC%E3%81%AE%E5%8F%96%E5%BE%97
- https://qiita.com/nishikyon/items/5054209089fc632981f8#1-3-project-id%E3%81%AE%E5%8F%96%E5%BE%97