背景
RAGって、難しくないですか?
データを取り込むときのチャンクのサイズや意味をベクトルで表現するために必要なembedding model、回答を生成するLLMなどなど、考慮すべき点は多くあります。それらを毎回全部検証していたら、いつまで経ってもビジネスに生成AIを生かすことなんて、はるか先の未来になってしまいます。
そこで、IBMから、それらの変数を自動で試し、RAGASなどの数値でRAGの結果を表せる指標を用いて、最適な結果を出してくれるAutoAI RAGのSDKがベータ版として出てきたので、試してみました。
AutoAI RAGの簡単な説明
サボりやガチ勢の私はIBMさんのドキュメントをそのまま引用させていただきます。
AutoAI RAG を使用して実験を実行すると、Tree Parzen Estimator (TPE) と呼ばれる超パラメータ最適化アルゴリズムを使用することで、すべての RAG 設定オプションのテストを回避できます (たとえば、グリッド検索を回避できます)。 以下の図は、16のRAGパターンから選択できるRAGコンフィギュレーション検索空間のサブセットを示している。 実験がそれらすべてを評価した場合、1~16のランク付けが行われ、最高ランクの3つのコンフィギュレーションがベストパフォーマンスとしてタグ付けされる。 TPEアルゴリズムは、どのRAGパターンのサブセットを評価するかを決定し、灰色で示されている他のパターンの処理を停止する。 この処理により、指数関数的な探索空間の探索を回避しつつ、よりパフォーマンスの高いRAGパターンを実際に選択することができる。
なるほど、良さそうには見える。もし可能なら設定できる変数を自分で決めたりできるといいですね。あと、まだembedding model自体は日本語対応していないですね。今後BYOMできると最高ですね。
まぁ、どんなもんか試してみますか。
AutoAI RAGのSDKを試す
せっかくなので、IBMさんのwatsonx.ai studio(旧watson studio)で試してみます。
諸々の設定
WMLの連携とか諸々をしていきます。
その後、アセットの新規資産から「PythonまたはR notebookでのデータおよびモデルの処理」を選択して、こちらをローカル・ファイルから参照してください。
あとは、Pythonに記載している通りに進めていきます。
まずは、必要なモジュールをインストールしていきます。
!pip install -U wget | tail -n 1
!pip install -U 'ibm-watsonx-ai[rag]>=1.1.11' | tail -n 1
その後、WMLインスタンスがあるアカウントのAPIキーを取得&入力します。
import getpass
from ibm_watsonx_ai import Credentials
credentials = Credentials(
url="https://us-south.ml.cloud.ibm.com",
api_key=getpass.getpass("Please enter your WML api key (hit enter): "),
)
RAGのサンプルデータを取り込みます
今回は、ibm_watsonx_ai Python SDK の zip ファイルを GitHub からダウンロードして使用します。
import wget, zipfile, os
filename = "watsonx-ai-python-sdk"
filename_zip = "watsonx-ai-python-sdk.zip"
if not os.path.isfile(filename_zip):
wget.download("https://github.com/IBM/watsonx-ai-python-sdk/archive/refs/heads/gh-pages.zip", out=filename_zip)
with zipfile.ZipFile(filename_zip, "r") as zip_ref:
zip_ref.extractall(filename)
from ibm_watsonx_ai.helpers import DataConnection, ContainerLocation
container_location_path = "ibm_watsonx_ai_sdk_docs"
container_data_connection = DataConnection(ContainerLocation(path=f"{container_location_path}/"))
container_data_connection.set_client(client)
html_docs_files = []
for root, dirs, files in os.walk(filename):
if root == f"{filename}/watsonx-ai-python-sdk-gh-pages":
for file in files:
if file.endswith('.html'):
file_path = os.path.join(root, file)
html_docs_files.append(file_path)
import sys
for ind, html_docs_file in enumerate(html_docs_files):
container_data_connection.write(html_docs_file, remote_name = html_docs_file.split("/")[-1])
sys.stdout.write(f"\rProgress: {'✓' * (ind+1)}{'.' * (len(html_docs_files)-ind-1)}\r")
sys.stdout.flush()
ICOSに接続します。
datasource_name = 'bluemixcloudobjectstorage'
bucketname = container_data_connection.location.bucket
cos_credentials = client.spaces.get_details(space_id=space_id)['entity']['storage']['properties']
conn_meta_props= {
client.connections.ConfigurationMetaNames.NAME: f"Connection to Database - {datasource_name} ",
client.connections.ConfigurationMetaNames.DATASOURCE_TYPE: client.connections.get_datasource_type_id_by_name(datasource_name),
client.connections.ConfigurationMetaNames.DESCRIPTION: "Connection to external Database",
client.connections.ConfigurationMetaNames.PROPERTIES: {
'bucket': bucketname,
'access_key': cos_credentials['credentials']['editor']['access_key_id'],
'secret_key': cos_credentials['credentials']['editor']['secret_access_key'],
'iam_url': 'https://iam.cloud.ibm.com/identity/token',
'url': cos_credentials['endpoint_url']
}
}
conn_details = client.connections.create(meta_props=conn_meta_props)
connection_id = client.connections.get_id(conn_details)
connectionを作成します。
from ibm_watsonx_ai.helpers import DataConnection, S3Location
input_data_references = [DataConnection(
connection_asset_id=connection_id,
location=S3Location(bucket=bucketname,
path=container_location_path))]
input_data_references[0].set_client(client)
ベンチマークに使用する json ファイルを COS にアップロードし、このファイルへの接続を定義します。
この例では、ibm_watsonx_ai SDK ドキュメントの内容を使用しています。
benchmarking_data_IBM_page_content = [
{
"question": "How to install ibm-watsonx-ai library?",
"correct_answer": "pip install ibm-watsonx-ai",
"correct_answer_document_ids": [
"install.html"
]
},
{
"question": "What is Credentails class parameters?",
"correct_answer": "url, api_key, name, iam_serviceid_crn, token, projects_token, username, password, instance_id, version, bedrock_url, proxies, verify",
"correct_answer_document_ids": [
"base.html"
]
},
{
"question": "How to get AutoAI pipeline with number 3?",
"correct_answer": "get_pipeline(pipeline_name='Pipeline_3')",
"correct_answer_document_ids": [
"autoai_working_with_class_and_optimizer.html"
]
},
{
"question": "How to get list of Embedding Models?",
"correct_answer": "client.foundation_models.EmbeddingModels",
"correct_answer_document_ids": [
"fm_embeddings.html"
]
},
{
"question": "How to retrieve the list of model lifecycle data?",
"correct_answer": "get_model_lifecycle(url='https://us-south.ml.cloud.ibm.com', model_id='ibm/granite-13b-instruct-v2')",
"correct_answer_document_ids": [
"fm_helpers.html"
]
},
{
"question": "What is path to ModelInference class?",
"correct_answer": "ibm_watsonx_ai.foundation_models.inference.ModelInference",
"correct_answer_document_ids": [
"fm_model_inference.html"
]
},
{
"question": "What is method for get model inferance details?",
"correct_answer": "get_details()",
"correct_answer_document_ids": [
"fm_model_inference.html"
]
}
]
その後、Jsonファイルとしてアップロードします。
import json
test_filename = "benchmarking_data_ibm_watson_ai.json"
if not os.path.isfile(test_filename):
with open(test_filename, "w") as json_file:
json.dump(benchmarking_data_IBM_page_content, json_file, indent=4)
test_asset_details = client.data_assets.create(name=test_filename, file_path=test_filename)
test_asset_id = client.data_assets.get_id(test_asset_details)
test_asset_id
テストデータへの接続情報のコネクションを作成
from ibm_watsonx_ai.helpers import DataConnection
test_data_references = [DataConnection(data_asset_id=test_asset_id)]
Milvusへの接続情報を作成する
import os
import getpass
milvus_connection_id = input("Provide connection asset ID in your space. Skip this, if you wish to type credentials by hand and hit enter: ") or None
if milvus_connection_id is None:
try:
username = os.environ["USERNAME"]
except KeyError:
username = input("Please enter your Milvus user name and hit enter: ")
try:
password = os.environ["PASSWORD"]
except KeyError:
password = getpass.getpass("Please enter your Milvus password and hit enter: ")
try:
host = os.environ["HOST"]
except KeyError:
host = input("Please enter your Milvus hostname and hit enter: ")
try:
port = os.environ["PORT"]
except KeyError:
port = input("Please enter your Milvus port number and hit enter: ")
try:
ssl = os.environ["SSL"]
except:
ssl = bool(input("Please enter ('y'/anything) if your Milvus instance has SSL enabled. Skip if it is not: "))
# Create connection
milvus_data_source_type_id = client.connections.get_datasource_type_uid_by_name(
"milvus"
)
details = client.connections.create(
{
client.connections.ConfigurationMetaNames.NAME: "Milvus Connection",
client.connections.ConfigurationMetaNames.DESCRIPTION: "Connection created by the sample notebook",
client.connections.ConfigurationMetaNames.DATASOURCE_TYPE: milvus_data_source_type_id,
client.connections.ConfigurationMetaNames.PROPERTIES: {
"host": host,
"port": port,
"username": username,
"password": password,
"ssl": ssl,
},
}
)
milvus_connection_id = client.connections.get_id(details)
hostには、watsonx.data MilvusのGRPCホスト
portには、watsonx.data Milvuのポート番号
usernameには、ibmlhapikey
passwordには、watsonx.data MilvusのインスタンスがあるアカウントのAPIキー
SSLは"y"(YES)
を入力してください。
接続情報を作成します。
vector_store_references = [DataConnection(connection_asset_id=milvus_connection_id)]
さてさて、長くなりましたが、やっとAutoAI RAGを試せます。
AutoAI RAGを実行
AutoAI RAGオプティマイザの入力情報を指定していきます。
name - 実験名
description - 実験の説明
max_number_of_rag_patterns - 作成するRAGパターンの最大数
optimization_metrics - 目標とする最適化メトリクス
今回は、以下のように設定しました。
from ibm_watsonx_ai.experiment import AutoAI
experiment = AutoAI(credentials, space_id=space_id)
rag_optimizer = experiment.rag_optimizer(
name='AutoAI RAG ibm-watsonx-ai SDK documentation',
description="AutoAI RAG experiemnt trainded on ibm-watsonx-ai SDK documentataion",
max_number_of_rag_patterns=6,
optimization_metrics=[AutoAI.RAGMetrics.ANSWER_CORRECTNESS]
)
実行します。
run_details = rag_optimizer.run(
input_data_references=input_data_references,
test_data_references=test_data_references,
vector_store_references=vector_store_references,
background_mode=False
)
以下を実行して、'completed'と出れば成功です。
rag_optimizer.get_run_status()
さて、結果をPandas DataFrameの形で一覧することができるので、見てみましょう。
summary = rag_optimizer.summary()
summary
RAGASの指標の結果とともに、使用したembedding model、チャンクサイズなどの結果が出てきました。
じゃあ、一番いいのなんなの?ということで以下のコマンドで教えてもらいました。
best_pattern_name = summary.index.values[0]
print('Best pattern is:', best_pattern_name)
best_pattern = rag_optimizer.get_pattern()
Best pattern is: Pattern4
だそうです。
感想
GUIで、簡単にできるようになるらしいので、それが出てくるのが楽しみですね。あとはやっぱり、変数をもっと自由に設定できると個人的には嬉しいかな。