まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:ibm

前回の続きです:

0:準備編
1:Jupyter Notebook 編
2:LangChain 編 (今回はここ)


最終回の今回は前回までに用意した環境や情報を使って、LangChain と呼ばれる LLM アプリケーション開発フレームワークを watsonx.ai の LLM で実装する方法を紹介します。 なお、ここで紹介した内容とその結果は 2024/12/31 時点でのものである点に留意ください。


【LangChain とは? エージェントとは?】
LangChain とは LLM を使った大規模アプリケーションの作成を簡易化するために用意されたオープンソースのオーケストレーション・フレームワークの1つです。

LLM はその名前(Large Language Model)が指し示すように大規模な言語データによってトレーニングされたモデルで、一般的な文脈の問い合わせには慣れていますが、(トレーニングデータに含まれていない)特定分野に関する情報や最新データに関する文脈への問い合わせは苦手としています。

LangChain はそのような LLM が比較的苦手とするコンテキストに対する問い合わせを補完するものです。様々な機能を持つ AI コンポーネントを「チェーン」と呼ばれる形でつなぎ合わせて最終的な答を導きだす機能を有しています。

そして、この LangChain は多くの場合で「エージェント」と呼ばれる機能とセットで使われます。「エージェント」はその名前が示すように「LLM 実行時に渡されたコンポーネントを用いて、『次にどのようなアクションを取ればよいかを判断し、選択し、実行して、目的を完了するまで繰り返す」という役割を担っています。

例えば次のような問い合わせを行いたいとします:
 「千葉県で一番高い山の高さの平方根の値はいくつですか?」

この問い合わせは(単体の)LLM だけではかなり難題に分類されるものだと想像できます。まず「千葉県で一番高い山(の高さ)」は LLM 作成時のトレーニングデータに含まれていれば答えられるかもしれませんが、含まれていなかった場合は答えられないし、場合によってはここでハルシネーションを起こしてしまいかねない質問です。 またその数値が分かったとして「平方根の値」を求める方法もトレーニング時に含まれていないと計算もできないはずです。そこまで都合よく LLM がトレーニングされているとは限らないわけで、LLM だけで正しい答を導くのは難しいはずなのです。

一方、この答を人間的な考え方で導こうとすると、多くの場合は
(1)まず千葉県で一番高い山を特定し(検索する)、 
(2)その山の高さを求め、
(3)最後にその高さの数値の平方根を計算(数値計算)する

という順序で考えて調べていくことで正解にたどり着こうとするのではないかと思います。

LangChain のエージェントはまさにこの「正解にたどり着くための順序を考える」部分を実施するライブラリです。「検索と数値計算を使って『千葉県で1番高い山の高さの平方根の値はいくつですか?』という問題の正解にたどりつくにはどうすればよいか?」を考え、(1)から(3)の順に実行する、というライブラリです。 

今回はこの LangChain のエージェント機能を watsonx.ai で使う例を紹介します。


【Jupyter Notebook で watsonx.ai の LangChain とエージェント機能を利用する】
前回同様に IBM Cloud 環境に用意した Jupyter Notebook 機能にアクセスし、編集状態にします。

まず最初に、これは私自身が色々試した範囲内での体感的な感想ではあるのですが、この LangChain やエージェントを実行する段階においては LLM として llama ベースのものを使うのが期待通りの結果になることが多い印象があります。というわけで、先頭セルの内容を編集し、利用する LLM を "meta-llama/llama-3-2-11b-vision-instruct" と変更します※:
2024123117

MODEL_ID の値を "ibm/granite-8b-japanese" から "meta-llama/llama-3-2-11b-vision-instruct" に変更します


なお、この状態で(MODEL_ID の値を変えた状態で)前回のコードを使ってこの質問を LLM にそのまま問い合わせた時の結果はこちらです。質問の意味を理解できていないかのような回答が最大トークンぶん繰り返されていたような結果になりました。やはり素の LLM には難問のようでした:
2025010300



改めて、次に前回までに作成した内容の下に1つセルを追加し、以下の内容を記載します(ここでは1行だけです):
pip install google-search-results

この1行は、この下のセルで初回に紹介したウェブ検索 API である SerpAPI を使うのですが、そのためのライブラリをインストールするコマンドです。

続けて更にセルを追加し、以下の内容を記載します。まずは最初のセルで初期化した変数 SERPAPI_API_KEY を使って、この値を環境変数化しています。そして前回作成した言語モデル custom_llm に対して、「ウェブ検索と数値演算を併用」してプロンプトに対する答を自律的に考えて求めるよう指示しています(具体的な検索方法や計算アルゴリズムは一切指示していない点に注目してください):
# LangChain Agent で watsonx.ai を使った問い合わせ
from langchain.agents import AgentType, initialize_agent
from langchain_community.agent_toolkits.load_tools import load_tools

import os
os.environ["SERPAPI_API_KEY"] = SERPAPI_API_KEY

# 2つ上で定義した custom_llm を使う
# custom_llm = WatsonxLLM(model=model)

# LLM(watsonx.ai)と serpapi(ウェブ検索)と llm-math(数値演算)を使って問い合わせの答を求める
tools = load_tools( ["serpapi", "llm-math" ], llm = custom_llm )
agent = initialize_agent( tools, custom_llm, agent = AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose = True, handle_parsing_errors = True )

r = agent.invoke( "千葉県で一番高い山の高さの平方根の値はいくつですか?" )
print( r )

2024123118
(↑この2つのセルとその内容を追加します)


ここで追加した内容は前回までに実装した custom_llm というモデルと、ウェブ検索ライブラリ("serpapi")と、数値計算ライブラリ("llm-math")を使って、「千葉県で一番高い山の高さの平方根の値はいくつですか?」という問い合わせを行う内容が記載されています。内容を見て分かるとおり、具体的にどのような思考順序で答えるべきか、といった情報はコード内には一切書かれておらず、そのあたりがエージェントに任されて、ただ問い合わせ内容だけが記載されていることがわかると思います。

では実際にこのコードを実行します。変数定義からやり直す必要があるので前回作った一番上のセルから順にセルを実行していきます(新たに指定した言語モデルで custom_llm 変数がインスタンス化されます)。

前回最後に実行したセルまで実行できたら、次は今回入力した新しい部分を実行します。まずは "pip install google-search-results" だけの行を実行します。以下のような "google-search-results" ライブラリがインストールされていく様子が出力されていきます:
2024123113


では最後のセルも実行します。実行すると元の質問文の内容をどのように解釈して、どのような順序で回答を求めていくかの様子も含めて出力されていくのがわかります:
2024123115


この質問に答えるには、まず千葉県で最も高い山を調べる必要があり、(ここで SerpAPI の検索 API を使って)それが愛宕山の 408m であることがわかり、その上でこの値の平方根を(llm-math という数値演算ライブラリを使って)求めて、、という経過を経ていることがわかりますね。


2024123116


最後は出力が途中で切れてしまいましたが、上図の青枠部分を見ると問い合わせに対する回答である 20.396.. という数字を得ることができています。こういった「どのようなライブラリや API を使う準備ができているのかを理解した上で、最終的に求められている答を求めるためのアプローチ方法から LLM が調べていく、、というより人間的な方法で問い合わせに対する回答を得ることができました。これがLLM の(LangChain の)エージェント機能と呼ばれるものです。

watsonx.ai でも無事に LangChain やエージェント機能を利用できることが確認できました。






前回の続きです:

0:準備編
1:Jupyter Notebook 編 (今回はここ)
2:LangChain 編


IBM が提供する LLM である watsonx.ai を使って LangChain やエージェントを実装する手順を紹介しています。前回は環境構築を含めた必要な情報の取得を一通り行いました。今回から Jupyter Notebook を使ってプログラミングを行います。 なお、ここで紹介した内容とその結果は 2024/12/31 時点でのものである点に留意ください。

まず、前回までの内容で取得した以下の情報が全て揃っていることを確認してください。取得方法は全て前回のコンテンツ内に含まれています(赤字は今回のブログで実際に使います):
・watsonx.ai プログラミング時に必要な4つの値
 ・URL
 ・モデル ID
 ・プロジェクト ID
 ・API キー値
・Jupyter Notebook の利用環境
・LangChain プログラミング時に必要な外部キー
 ・Serp API キー


【Jupyter Notebook にアクセス】
自分の PC に Python などを導入して、自分のローカル環境で Python を使って実行する人はその方法でも構いません。が、このブログでは事前にオンラインに用意した Jupyter Notebook ランタイム環境を使ってプログラミングを実施します。

まずは前回作成した Jupyter Notebook 環境にアクセスします。IBM Cloud にログインし、リソース・リスト内「AI/機械学習」カテゴリーから "Watson Machine Learning" インスタンスを選択します:


"Watson Machine Learning" インスタンス画面において、「起動」右側の矢印 - 「IBM Cloud Pak for Data」を選択します:
2024123100


以下のような画面になったら(プロジェクトは前回作成済みなので)「キャンセル」をクリックします(プロジェクトを新規に作成する場合は、前回の内容を参考に「新規プロジェクト」から作成してください):
2024123101


IBM Cloud Pak for Data の起動直後の画面に移動します。ここで画面下部の「プロジェクト」から作成済みのプロジェクトを選択します:
2024123102


選択したプロジェクトの「資産」タブ内に、これも前回作成済みの Jupyter Notebook 資産が存在しています。再度利用したいので、該当する資産の右側のメニューから「編集」を選択します:
2024123103


少し待つとランタイムがロードされて起動し、Jupyter Notebook の編集画面に移ります。これで Jupyter Notebook が利用できるようになりました:
2024123104


【Jupyter Notebook で watsonx.ai の LLM を利用する】
IBM Cloud の Jupyter Notebook は最低限の pip パッケージが導入済みということもあって、すぐに Python コードを書き始めることができます(必要であれば "pip install xxxxx" で追加することももちろん可能です。このシリーズでも最後に使う予定です)。まずは以下の内容を Jupyter Notebook 内に記述(またはコピー&ペースト)してください。内容は前回の手順でそろえた5つの値を全て変数化する、というだけのものです。赤字部分はコメントなので入力時には無視して、自分で実際に取得した値をそのまま文字列として入力するようにしてください。なお最後の SERPAPI_API_KEY は今回使いませんが、定義だけここで済ませておきます:
# 変数の事前定義
MODEL_ID = "ibm/granite-8b-japanese" (LLM 言語モデルのID)
ML_URL = "https://jp-tok.ml.cloud.ibm.com" (watsonx.ai の URL)
API_KEY = "(API キーの値)"
PROJECT_ID = "(プロジェクト IDの値)"
SERPAPI_API_KEY = "(SerpAPI キーの値)"

2024123105



続けて新しいセルを追加します。画面内左上、左から2番目のアイコン("Insert a cell below")をクリックします:
2024123106


新しいセルが下に追加されます:
2024123107


追加されたセル内に以下のコードを入力(またはコピー&ペースト)します:
# watsonx.ai を LangChain から使った問い合わせ
from ibm_watson_machine_learning.foundation_models import Model
from ibm_watson_machine_learning.metanames import GenTextParamsMetaNames as GenParams
from ibm_watson_machine_learning.foundation_models.extensions.langchain import WatsonxLLM

credentials = {
    "url": ML_URL,
    "apikey": API_KEY
}
project_id = PROJECT_ID

# 使用するLLMのパラメータ
generate_params = {
    GenParams.MAX_NEW_TOKENS: 500,
    GenParams.MIN_NEW_TOKENS: 0,
    GenParams.DECODING_METHOD: "greedy",
    GenParams.REPETITION_PENALTY: 1
}

# モデルの初期化
model = Model(
    model_id=MODEL_ID,
    credentials=credentials,
    params=generate_params,
    project_id=project_id
)

# LangChainで使うllm
custom_llm = WatsonxLLM(model=model)

r = custom_llm.invoke( "IBM Db2 on Cloud の特徴は?" )
print( r )

この時点では(実質的には) LangChain を使っているわけではないのですが、LangChain を使う想定で LLM のモデルを初期化し、最後に "IBM Db2 on Cloud の特徴は?" という問い合わせを実行しています。LangChain を使う準備も兼ねた実験的な問い合わせのような内容※だと理解ください。

※もう少し細かな内容まで説明すると、generate_params という変数の中で LLM を利用する上での変数値を調整しています。具体的には最大トークン数 = 500、デコーディング手法はいわゆる「貪欲法(greedy)」と呼ばれるシンプルな計算法、既に生成された単語や文脈が繰り返し使われることを抑制するための Repetition Penalty を有効に設定した上で言語モデルを初期化しています。この辺り、ある程度内容を理解できている場合は調整いただいて構いません。

では入力した内容を Jupyter Notebook 内で実行してみます。Jupyter Notebook を編集状態で開き、最初に変数定義を入力したセルにカーソルを合わせます(選択されているセルの左側に青い帯が表示されます)。そしてアイコンメニューの左から6番目、"Run this cell and advance(Shift + Enter)" をクリックするか、Shift キーを押しながら Enter キーを押してこのセルを実行します:
2024123109


最初のセルは変数の値を代入しているだけなので出力結果は何もありません(実行しても何もなかったかのような結果になります)。ただ選択されているセルが1つ下に移動しているはずです。この状態で(最初のセルの実行結果が有効になった状態で)2番目のセルを同じアイコンまたは Shift + Enter で実行します:
2024123110


すると(2024/12/31 時点では)画面のような警告メッセージも表示されますが、最終的には(プログラム内に書かれていた「IBM Db2 on Cloud の特徴は?」という問い合わせに対する回答が表示されます:
2024123111


Jupyter Notebook を使って watsonx.ai の LLM 言語エンジン(今回の例だと "granite-8b-japanese")に対するシンプルな問い合わせのプログラミングサンプルを入力し、実際に動く様子が確認できました。


【ここまでのまとめ】
今回紹介した内容で、watsonx.ai の LLM モデルを使った Python コーディングのサンプルを実際に動かす、具体的なコーディング内容/方法を紹介しました。

次回は今回紹介した内容を応用して、LangChain やエージェントと呼ばれる LLM アプリケーション開発手法を watsonx.ai の LLM で実現・実装する方法を紹介する予定です。


この1年はここ数年と比べても LLM への取り組み時間が長い1年だったと思います。普段は普通に OpenAI とかも使ってるんですが(笑)、今回は WatsonX.AI で LangChain やエージェントを使う方法を自分なりに調べた結果を数回に分けて紹介します。 初回である今回は次回以降で実際に watsonx.ai を活用するための準備部分を一通り紹介します。

最初は準備というか、IBM Cloud の Watsonx.AI でプロンプトや Jupyter Notebook を使えるようになるまでの準備作業を紹介します。この辺り、事情が分かっていたり、既に完了している人は飛ばしていただいて構いません。

0:準備編 (今回はここ)
1:Jupyter Notebook 編
2:LangChain 編


IBM Cloud で Watsonx.AI の生成 AI や Cloud Pak for Data の Jupyter Notebook を使うためにはそのための準備がいくつか必要となります。実際にコードを書いたりするのは次回以降からとして、今回は次回以降でコーディングするために必要な一通りの準備を行っておきます。


【IBM Cloud 内に必要なサービスを作る】
最初に IBM Cloud 内に必要なサービスのインスタンスを作成します。先に結論を言うと、以下3つのサービスインスタンスを作っておく必要があります(作成済みであればここは飛ばしていただいて構いません):
IBM Cloud Object Storage
Watsonx.AI Studio
Watson Machine Learning

一番上の Cloud Object Storage は 25GB までの無料枠があり、またそれ以外の2つは無料版が提供されていて、この無料枠内で試すだけであれば実質的な料金をかけることなく試すことができるものです。

では上から順に作成していきます。IBM Cloud にログイン後、画面左にあるメニューの上から3番目(リソース・リスト)を選択して、現在までに作成したサービスインスタンスの一覧を表示します。IBM Cloud Object Storage が作成済みの場合は「ストレージ」カテゴリ内に表示されるので、何か表示されている人はそのインスタンスを使うことで(新たには作成しなくても)代用できます。新規に作成する場合は画面右上の「リソースの作成」ボタンをクリックします:
2024123001


カタログ画面に切り替わるので、検索バーに "object storage" と入力すると "Object Storage" サービスが見つかるので、これを選択します:
2024123002


"Cloud Object Storage" インスタンス作成画面に切り替わります。ここでインフラストラクチャーとしてはデフォルトの "IBM Cloud" が選択されていることを確認して、下にスクロールします:
2024123003


料金プランは "Standard" を選択します(25 GB の無料枠があります)。更にそのまま下にスクロール:
2024123004


リソース名とリソースグループを適当に指定(デフォルトのままでもOK)して、最後に画面右下の「作成」ボタンをクリックしてインスタンスを作成します:
2024123005


少し待つと指定した名前でインスタンスが作成されます。これで Cloud Object Storage インスタンスは作成できました:
2024123006


画面左上のハンバーガーメニュー(横三本線)から「リソース・リスト」を選択して、インスタンス一覧の画面に戻ります:
2024123007


上で作成した Cloud Object Storage のインスタンスが「ストレージ」カテゴリー内に追加されていることが確認できます。これで Cloud Object Storage は準備できました:
2024123008


続けて同様に Watsonx.AI Studio インスタンスを作成します。この画面内右上の「リソースの作成」ボタンをクリックします:
2024123009


カタログ画面では今度は "watsonx" と入力し、候補に出てくるサービス一覧の中から "watsonx.ai Studio" を選択します:
2024123010


"watsonx.ai Studio" インスタンス作成画面に切り替わります。ここでロケーションとして「東京」を選択してください(後述しますが、日本語対応 LLM を使える唯一のロケーションです)。また料金プランは「ライト」を選択すると一定の枠内であれば無料です(もちろん有料の Standard プランを選択いただいても構いません):
2024123011


画面を下にスクロールして、リソース名、リソースグループ(どちらもデフォルトのままで構いません)を指定し、画面右の要約部に表示されている料金を確認した上で、画面右下の同意ボックスにチェックを入れて「作成」します:
2024123012


少し待つと指定した名称のインスタンスが作成されます。これで "watsonx.ai Studio" インスタンスも準備できました。 先ほどと同じ方法(画面左上のハンバーガーメニューからリソースリスト)でもいいのでせすが、この画面の左上にある「リソース・リスト」をクリックした場合でも同じ画面に戻ることができます:
2024123013


リソースリスト内の「AI/機械学習」カテゴリに watsonx.ai Studio のインスタンスが追加されていることを確認します。 必要なインスタンスの追加としては最後に "Watson Machine Learning" インスタンスを作成します。画面右上の「リソースの作成」をクリックします:
2024123014


カタログ画面において "watson ma" くらいまで入力すると、検索候補に "Watson Machine Learning" が表示されるので、これを選択します:
2024123015


"watsonx.ai Studio" の時と同様にロケーションは「東京」を選択し、料金プランは「ライト」にすると無料枠内で利用できます:
2024123016


下にスクロールして、リソースの名称とリソース・グループ(デフォルトのままで構いません)を選択して、画面右上の要約部で料金を確認して、画面右下の同意ボックスにチェックを入れて「作成」します:
2024123017


少し待つと指定した名前のインスタンスが作成されます。ここでも画面左上の「リソース・リスト」をクリックしてリソース一覧画面に戻ります:
2024123018


リソース・リスト画面内において、「ストレージ」カテゴリー内に Cloud Object Storage インスタンスが、「AI/機械学習」カテゴリー内に "watsonx.ai Studio" インスタンスと "Watson Machine Learning" インスタンスがそれぞれ存在していることを確認します:
2024123019


この3つのインスタンスが揃っていれば次に進むことができます。


【プロンプトを実行できるようプロジェクトを準備する】
Watsonx.AI でいわゆる「プロンプト」を実行できるようにするための準備を行います。初回のみ必要な準備や設定があるので、その内容を中心に紹介します。

まずはリソースリストから作成済みの Watson Machine Learning インスタンスを選択します。選択後の画面内に「起動」と書かれているボタン右側の矢印をクリックするとメニューが表示されるので、"IBM Watsonx" を選択します。なお、ここで紹介する初回準備が完了した後はこの "IBM Watsonx" を選択することでプロンプト画面へ遷移することができるようになります:
2024123020


以下のようなダイアログが表示されたらチェックボックスにチェックをいれます。オンラインツアーガイドは不要であれば画面右上の×印をクリックしてダイアログを閉じます:
2024123021


すると以下のような画面になります。必要な準備が完了していると、ここから直接プロンプト画面に遷移できるのですが、そのためには「プロジェクト」と呼ばれる項目が作成されている必要があります(のちのち Python で LangChain やエージェントを使う際に、このプロジェクトの ID が必要になります)。プロジェクト作成済みであればそのプロジェクトを使ってもいいのですが、初回はまだ作成されていないのでこのタイミングで1つ作成しておきます。画面下部の「プロジェクト」と書かれたリンクをクリックします:
2024123022


プロジェクトの一覧画面に遷移します。まだプロジェクトが1つも作成されていないと以下のような画面になるはずです。ここで「新規プロジェクト」ボタンをクリックします:
2024123023


プロジェクトの名前(下図では "project-20241230")を適当に指定し、ストレージ欄には作成済みの Cloud Object Storage を選択します(1つだけ作られている場合ははじめから選択済みのはずです)。プロジェクトで使うストレージまで指定できたら「作成」ボタンをクリックします:
2024123024


指定した名前のプロジェクトが作成され、そのプロジェクトの画面に移動します。このプロジェクト内でどの程度のリソース(CPU やトークン数など)を使ったか、といった概要はここで確認できます:
2024123025


続けてプロジェクトと Watson Machine Learning インスタンスを紐づけします。画面内の「管理」タブから「サービスおよび統合」メニューを選択し、「サービスの関連付け」ボタンをクリックします:
2024123026


「サービスの関連付け」画面内で自分が作成した Watson Machine Learning インスタンスを選択(チェック)して「アソシエイト」ボタンをクリックします:
2024123027


1つ前の画面に戻り、「サービスおよび統合」画面内に選択した Watson Machine Learning インスタンスが関連付けされていることを確認します。これでプロンプトを実行するための準備は整いました:
2024123028


【watsonx.ai のプロンプトを実行する】
では実際に watsonx.ai のプロンプトを実行し、この後の作業で必要になるプロジェクト ID などの値を取り出すところまでを実施します。

上の作業を実行した直後の場合は、元の画面に戻るために画面左上のハンバーガーメニューから「ホーム」を選択します:
2024123029


元の("IBM watsonx.ai" を選択した時の)画面に戻ります。必要な準備が全て完了しているので「Prompt Lab を開く」リンクが有効になっています。ここをクリックします:
2024123030


「プロンプト・ラボへようこそ」というダイアログが表示されたら、全てにチェックを入れて先に進みます(オンラインツアーが不要であれば「ツアーをスキップ」をクリックしてください):
2024123031


以下のような画面が表示されれば、ここからプロンプトを指定して問い合わせを実施することができます:
2024123032


が、実際に問い合わせを行う前に利用する LLM のモデルを変更/指定する手順を理解しておきましょう。画面右上のモデル部(下図では「モデル granite-3-8b-instruct」と表示されている部分)をクリックします:
2024123033


「すべての基盤モデルを表示する」というメニューが表示されるので、この部分をクリックします:
2024123034


すると watsonx.ai で利用可能な LLM 基盤モデルの一覧が表示されます(ここで表示される内容は今後更新される可能性があるので、下図のものとは異なっている可能性があります)。この中から特徴などに合わせて利用する LLM 基盤モデルを選択します。なお Watson Machine Learning インスタンスを作成した時に東京リージョンを選択していると、この中に "granite-8b-japanese" という日本語特化型基盤モデルが選択可能になります。ここではこの "granite-8b-japanese" モデルを選択します(Watson Machine Learning インスタンスを作成した時の料金プランによっては選択できるモデルとできないモデルがあることに注意してください):
2024123035


選択した基盤モデル(ここでは "granite-8b-japanese")の説明が表示されます。これでよければ「モデルの選択」ボタンをクリックして確定します:
2024123036


1つ前のプロンプト画面に戻り、利用基盤モデルが選択したもの(下図の例では "granite-8b-japanese")に切り替わったことを確認します:
2024123037


基盤モデルが確定したところで、改めてプロンプトの問い合わせを実施してみます。「フリーフォーム」が選択されていることを確認して、LLM 基盤モデルに問い合わせしたい内容(下図では「IBM Cloud の特徴を完結に教えてください。」)を入力して、最後に右下の「生成」ボタンをクリックします:
2024123038


すると入力した内容を選択した LLM に問い合わせ、その結果が問い合わせ内容の下に表示されていきます(この結果は選択した LLM 基盤モデルによっても変わります)。とりあえずプロンプトの実施ができることを確認します:
2024123039


【プログラミング時に必要な情報を取り出す】
ここまでの内容で IBM Cloud で watsonx.ai の LLM を使ってプロンプトを実施するまでの手順を紹介しました。 単にプロンプトを使うだけであればここまでの内容でも充分なのですが、本ブログの目的は単なるプロンプト実行ではなく、Python (Jupyter Notebook)のプログラミングで LangChain を実現したり、エージェント処理を実現することです。この「プログラミングによって LLM を利用する」上で必要になる情報を取得する手順を紹介します。

プロンプト問い合わせ後に画面右上のメニュー右から2番目の「コードの表示」アイコンをクリックして、この問い合わせを実施した時のプログラミングコードを確認してみます:
2024123040


「コードの表示」と書かれたダイアログが表示されます。この画面内でどのようなコードを書くと、今と同じ処理を実現できるか、という内容を、Curl/Node.js/Python で確認することができます。

この Curl の画面の中で curl 実行時のパラメーターの中で指定されている model_id と project_id の値はプロングラミング時に必要になるため、メモしておいてください。model_id は LLM の基盤モデルを示す ID で、今回の例だと "granite-8b-japanese" という基盤モデルを示す ID の値(="ibm/granite-8b-japanese")が表示されています。project_id はこのプロンプトを実行している時に使うプロジェクトの ID で、この値は自分以外の人に知られないようにしましょう。

加えて "curl" の直後にある URL のホスト値(下図の場合は "https://jp-tok.ml.cloud.ibm.com")もプロングラミング時に必要な情報です:
2024123041


プログラミングによって watsonx.ai を利用する際に必要な情報がもう1つあります。それは API Key と呼ばれるもので、プログラミングによって実行される処理を実行する人(=要するにあなた)の権限を特定するための値です。API Key を取得するには IBM Cloud 画面から画面↑の「管理」と書かれている部分をクリックし、「アクセス(IAM)」を選択します:
2024123042


管理画面左にある「API キー」を選択すると、これまでに作成された API Key の一覧が表示されます(初めて作成する場合は何も表示されません)。ここで新しい API Key を作成するには表示の内容が「自分の IBM Cloud API キー」になっていることを確認してから「作成」ボタンをクリックします:
2024123043


「IBM Cloud API キーの作成」というダイアログが表示されます。ここで名前(下図では "IBM Cloud API Key - 20241230")を適当に指定し、Leaked action(この値が外部に漏れた場合の処置方法)や Session creation (この API Key でセッションの作成が必要か)を指定します(よく分からない場合はデフォルトのままでも構いません)。最後に「作成」ボタンをクリックします:
2024123054


すると新しい API キーが作成されます。この値は作成した人(=あなた)がプログラミングで自分の LLM を使うことを許可するための値であるため、絶対に他の人に知られないようにしてください(知られた場合、その人はあなたのふりをして、あなたの権限で LLM を使うことができるようになります)。API キー値は最初は表示されていませんが、目のアイコンをクリックすると表示することができます。また JSON ファイルとしてダウンロードすることもできます。ダウンロードせずにこの画面を消してしまったら2度と表示することはできない(その場合は削除して再作成)ことに注意してください:
2024123045


ダウンロードした JSON ファイルをテキストエディタで開くと以下のようになり、"apikey" という属性値として API キーが含まれています。ダウンロード後に API キーを確認する場合はこの値を使ってください:
2024123046


ここまでの手順で、watsonx.ai の LLM をプログラミングから使う上で必要な、4つの値
URL(東京リソースで作成した場合は "https://jp-tok.ml.cloud.ibm.com")
モデル ID(使う基盤モデルを変更する場合は変更後の値を再度確認する必要があります)
プロジェクト ID
API キー値
が全て揃いました。


【Jupyter Notebook を使えるようにする】
ここまでの手順で URL/モデル ID/プロジェクト ID/API キー値 の4つが揃いました。これでプログラミングから watsonx.ai の LLM (のプロンプト)を使うことができるようになりました。

自分の PC に Python などをインストールしてローカルで実行する場合はこの4つだけで始めることもできますが、IBM Cloud を利用していれば、Jupyter Notebook と呼ばれるプログラミング言語などのインストールも不要なオンラインの実行環境を利用することができます(無料インスタンスを使っている場合はその無料枠内で利用できます)。この Jupyter Notebook を使えるようにするための準備も行っておきましょう。

改めて IBM Cloud にログインし、リソース・リストから "Watson Machine Learning" のインスタンスを選択します:
2024123047


"Watson Machine Learning" インスタンス画面内の「起動」ボタン右側の矢印をクリックし、2つのメニューアイテムが表示されたら "IBM Cloud Pak for Data" を選択します:
2024123048


初回は以下のような画面が表示されます。この "IBM Cloud Pak for Data" でもプロジェクト単位で利用コンテンツを管理するのですが、初回はプロジェクトが1つも存在していません。この画面が表示されたら、最初のプロジェクトを新規に作成するため、「新規プロジェクト」を選択してから「次へ」ボタンをクリックします(プロジェクト作成済みでこの画面になった場合は右上の×印で画面を消して構いません):
2024123049


「プロジェクトの作成」画面に移動するので、プロジェクトの名称(下図では "CP4D project")を適当に入力します。またこのプロジェクトで利用するストレージとして作成済みの Cloud Object Storage インスタンスを選択します。最後に「作成」ボタンをクリックします:
2024123050


指定した名前(下図では "CP4D project")でプロジェクトが作成されます。このプロジェクトの構成要素の1つとして Jupyter Notebook を使うことができます。 実際に1つ作成してみます。「Python または R notebooks でのデータおよびモデルの管理」と書かれたボックスをクリックします:
2024123051


作成する Jupyter Notebook の名前と、構成スペックを指定します。名前は適当に(下図では "Jupyter Notebook - 20241230")指定し、構成スペックは最も小さなもの(2024/12/30 時点では "Runtime 24.1 on Python 3.11 XXS( 1 vCPU 4GB RAM )")を選択します。最後に「作成」ボタンをクリックします:
2024123052


すると以下のような Jupyter Notebook の画面になり、オンラインから Python コードを入力して実行することができるようになります:
2024123053


一度作成した Jupyter Notebook はプロジェクト内の「資産」として管理されます。作成後に再度利用する場合はプロジェクト選択後の画面で「資産」タブをクリックすると、指定した名称の Jupyter Notebook 資産が選択できます:
2024123055


再度編集状態にするには画面右のメニューから「編集」を選択すると Jupyter Notebook のランタイムが再度インスタンス化されて、編集ができるようになります:
2024123056


(編集可能になった後の画面)
2024123057


【SerpAPI の API キーを取得する】
本シリーズの最後に LangChain でエージェントを使う際に、検索エンジンと LLM を組み合わせた問い合わせ処理を実施する予定です。そこで利用する機能の1つ SerpAPI の API キーを取得(無料アカウントの場合は月 100 回の検索が可能)しておきましょう。

SerpAPI の API キー取得方法はまず公式サイトへ行き、右上の "Register" からアカウントを登録します:
https://serpapi.com/


アカウント登録後にサインインし、"API Key" メニューから(無料アカウントの場合は1つ)API キーを作成することができます。この API キーも(無料ですが、流出してしまうと、他の誰かに 100 回使われたらその月はもう使えなくなってしまうので)自分以外の人には教えないようにしましょう:
2024123058


【ここまでのまとめ】
以上、今回紹介したここまでの作業で以下の値が全て揃いました:
・watsonx.ai プログラミング時に必要な4つの値
 ・URL
 ・モデル ID
 ・プロジェクト ID
 ・API キー値
・Jupyter Notebook の利用環境
・LangChain プログラミング時に必要な外部キー
 ・Serp API キー


次回からはこれらの値や環境を使って、実際に watsonx.ai の LLM 基盤モデルを使って LangChain やエージェントを実装していきます。




先日、「Watsonx.AI の LLM をチューニングする」というブログを公開しました。IBM Cloud から提供されている IBM の生成 AI である WatsonX.AI の標準 LLM を、独自に与えるテキストデータによってチューニングを施した新しい LLM を作る、という内容を、その実行例を交えて紹介したものでした。

紹介した方法で作られた新しい LLM を REST API で使う方法についても紹介ページに含まれているのですが、API プログラミングが求められるとなると、まだ少しハードル高いですよね。となると、チューニング済み LLM は WatsonX.AI のプロンプトラボという機能/UIを使って使うことになる・・・ というのではあまりにも寂しいです。

そんなわけで、本日のブログエントリでは「チューニング済み WatsonX.AI LLM を Node-RED で使う」手順を紹介します。Node-RED はフローエディタを使った、いわゆるノーコード/ローコード開発ツールの代表的な1つです。この Node-RED であればプログラミングにあまり自信がない人でもデータの流れを理解していれば WatsonX.AI プログラミングができるようになる、かも、という狙いです。


【Node-RED の用意】
まず何はともあれ Node-RED 環境が必要です。既に Node-RED を使える環境がある場合はその環境を使ってください。環境がない場合はなんらかの方法で Node-RED 環境を用意する必要があります。

比較的一般的な方法は「手元のローカル PC に Node-RED をインストール」する方法です。Windows, Mac, ラズベリーパイなどに対応していて、管理者権限があればインストールすることができます:
https://nodered.jp/docs/getting-started/local

または「IBM Cloud の Code Engine を使ってインストールする」方法もあります。こちらはリソースの使い方によっては有料となってしまいますが、比較的安価にコンテナアプリケーションを実行することができる環境です。この環境で DockerHub 内の nodered/node-red を動かす、という方法です。

Code Engine を使う場合はアプリケーションの登録時に以下の設定をしてください。まず Code の種類は "Use an existing container image" を選択し、イメージ名は "nodered/node-red" と入力します:
2024092701


下にスクロールします。次にこの1アプリに使うリソース量を指定します。まず CPU とストレージは最小のものでいいと思います(多いほど値段が上がります)。注意が必要なのはその下の Autoscalling 設定です。この Max 値は 1 固定でいいのですが、問題は Min 値です。ここを 1 にするとアプリケーションは(最小インスタンス数=1、最大インスタンス数=1になるので)1つ起動しっぱなしになります。常に稼働しているため料金はそれなりにかかりますが、常に使える状態で待機していることになります。 一方、ここを 0 にすると(最小インスタンス数=0、最大インスタンス数=1になるので)アクセスがない時は消え、アクセスがあるとその場で1つ動き出します。アクセスのない時間帯の料金は(0インスタンスなので)かかりませんが、アクセスから実際にアプリケーションが動き出すまでのタイムラグがあり、また一度保存した状態があっても、アクセスがなく 0 インスタンスになってしまうと、次にアクセスした時には保存状態が残りません。いつでも使える状態がいいか、アクセスしない時間のコストをセーブするのがいいか、優先順位に合わせて選んでいただきたいのですが、以下の機能を試す間だけでも 1 に設定してインスタンスが落ちないようにしておくのがいいと思いました:
2024092702


そしてドメインマッピングの設定は "Public" を選択し、最後に "Create" ボタンで作成します:
2024092703


1~2分でアプリケーション(=Node-RED)が起動します。ステータスが "Ready" になったら "Test application" から "Application URL" を選択すると実際のアプリケーション(=Node-RED)にアクセスできます:
2024092705


アクセスに成功するとこんな感じの画面になり、ここから Node-RED が使えます:
2024092706


ここでは2つの方法を紹介しましたが、これ以外の方法(普通にパブリッククラウドにデプロイするとか・・)でももちろん構いません。何らかの方法で Node-RED が使えるようになっているという前提で以下の説明を続けます。


【watsonx.ai ノードのインストール】
Node-RED から Watsonx.AI を使えるようにするため、用意した Node-RED に拙作の watsonx.ai ノードを追加します:
2024093001


追加手順は以下です。まず Node-RED の右上のメニューから "Manage Pallete(パレットの管理)" を選択します:
2024092802


パレットの管理画面が表示されます。ここで "Install" タブに切り替え、検索ボックスに "watsonx" と入力します。すると(2024-09-28 時点では他の候補は見つからないのですが) "node-red-contrib-dotnsf-watsonx" という名前の公開ノードが見つかるはずです(2024-09-30 時点では最新バージョン 0.2.3 を公開しています)。この "Install" ボタンをクリックします:
2024092803


「インストールしていいか?という確認画面が表示されたら "Install" を押してください:
2024092804


インストールに成功すると、このような画面が表示されます:
2024092805


ダイアログをクローズして元の画面に戻ると、ノード一覧の function カテゴリ内に "watsonx.ai" と書かれたノードが追加されているはずです。これで Node-RED から比較的簡単な方法で watsonx.ai の生成 AI が使えるようになりました:
2024092806


【watsonx.ai 側のパラメータを確認】
準備の最後に、この後実際に Node-RED から Watsonx.AI を使う際にあたふたしないよう、watsonx.ai ノードに指定する各種パラメータの値をあらかじめまとめて調べておくことにします。

まず watsonx.ai ノードを左のパレット一覧から右のフロー部分にドラッグ&ドロップし、その後ダブルクリックしてください:
2024092807


すると以下のようなダイアログが表示されます。これが watsonx.ai ノードに指定するパラメータです:
2024092808


これらに指定するパラメータを確認しましょう。まずは watsonx.ai のプロンプトラボ画面を表示し、そこで指定するモデルをチューニングで作成したもの(下図では "kkimura-foreign-exchange-llm-v1")に設定します:
2024092809


まず画面右の "View Code" というボタンをクリックすると、このプロンプトで実行する問い合わせを Curl で実行する時の指定内容が表示されます。この中に Location と Deployment ID の情報が含まれています:
2024092811


例えば curl で指定する URL が以下のような値の場合、、
curl "https://jp-tok.ml.cloud.ibm.com/ml/v1/deployments/(deployment_id)/text/generation?version=2023-05-29"

青字の ".ml.cloud.ibm.com" の前にある文字列 "jp-tok" が Location の値です。また "deployments/" と "/text" の間にある赤字の部分にある文字列が Deployment ID です。

なお API Key は IBM Cloud ダッシュボードで作る API Key の値です。またチューニング LLM を使う場合、Project ID と Model ID はともに指定不要です(指定されたままでも構いませんが、Deployment ID が指定されている場合は無視されます)。

これらの値を先ほどのダイアログ内に指定し、最後に "Done" ボタンをクリックします:
2024092812


これでパラメータの準備も完了しました。


【Node-RED から watsonx.ai のチューニング済み LLM にアクセスする】

Node-RED のフローを完成させましょう。watsonx.ai ノードの左側に inject ノードを、右側に debug ノードを配置し、これらを繋げます:
2024092813


inject ノードをダブルクリックしてダイアログを開き、"msg.payload" の種類を文字列に(図で az と書かれている指定)、文字列の内容を "与えられた質問に対する答を計算して簡潔に答えてください。\\\\n\\\\n1 ドルは 144.3 円です。 10 ドルは何円ですか?" と入力して、Done をクリックします(msg.topic は使いません。×をクリックして削除しても構いません):
2024092814


ここまで準備できたら、Node-RED 画面右上の "Deploy" ボタンをクリックして、このフローをデプロイします:
2024092815


そして inject ノード左のボタンをクリックすると指定した文字列が watsonx.ai ノードに渡され、Deployment ID で指定されたチューニング済み LLM で処理され、その結果が debug ノードに渡されます。debug ノードに渡った結果は画面右の debug ペイン(虫のマーク)で確認することができます:
2024093000

 
まだチューニングが充分ではないので、期待していたような出力結果ではありませんが、Watsonx.AI のチューニング済み LLM を Node-RED からも使うことができる、ということが確認できました。

というわけで改めて、WatsonX.AI 用 Node-RED カスタムノードがチューニング済み LLM にも対応できましたので、よかったら使ってください:
2024093001



IBM Cloud から提供されている生成 AI である Watsonx.AI の LLM をチューニングする機会があったので、その内容や手順、そして気になるチューニングのコストなどをまとめました。あくまで一つの例ですが、参考になればと思っています。


【Watsonx.AI の LLM チューニング】
本記事で後述する内容は 2024-09-25 時点のものです。この時点では Watsonx.AI の LLM チューニングはいわゆる「プロンプト・チューニング」のみ可能です。

LLM の基になる非構造テキストデータを大量に再学習、するようなチューニングではなく、あくまで「プロンプトエンジニアリングをベースとしたチューニング」です。詳しくは後述しますが、ベースとなる LLM に対して、入力例と出力例を複数与えてプロンプトに出力の方向性を指示するような改良を LLM に加える、というものです。プロンプトエンジニアリングで与えるサンプル部分のトークン数が多くなって1回の問い合わせコストが高くなってしまうことを防ぐことがメリットとなるものです。


【どんなチューニングをするか】
当然ですが、「チューニング前の LLM では期待した返答にならないような問い合わせ」をチューニングして改良することを試みます。というわけで、まずはチューニング前の granite-13b-instruct-v2 モデルを使って、フリーフォームで以下のプロンプトを試してみました(2024-09-25 時点での試行結果です):

「1 ドルは 140.1 円です。 10 ドルは何円ですか?」
2024092501


このプロンプトに対して「生成」ボタンで問い合わせすると「140.1 円です。」という返答が返ってきました。うーん、価格を問い合わせていることは理解できているようですが、こちらが期待した計算結果にはなっていませんでした:
2024092502


そこで計算方法含めてプロンプトでガイドしてみます。「フリーフォーム」から「構造化」に変えます(この時に LLM モデルが切り替わることがあるので、改めて granite-13b-instruct-v2 モデルを選びます)。そして "例" と書かれた箇所を「新規テスト+」ボタンで行を増やしながら以下のように3行入力します。与えられた情報を使って、答を計算して返答するような例をいくつか指示してみました:
入力出力
11 ドルは 140 円です。 10 ドルは何円ですか?1 ドルが 140 円なので、 10 ドルは約 140 * 10 = 1400 円です。
21 ドルは 140.1 円です。 20 ドルは何円ですか?1 ドルが 140.1 円なので、 20 ドルは約 140.1 * 20 = 2802 円です。
31 ドルは 140.3 円です。 30 ドルは何円ですか?1 ドルが 140.3 円なので、 30 ドルは約 140.3 * 30 = 4209 円です。

2024092503


そして "試行" の入力欄に以下を入力し、テキストを生成させます:
1 ドルは 139.1 円です。 10 ドルは何円ですか?
2024092504


これで「1 ドルが 139.1 円なので、 10 ドルは約 139.1 * 10 = 1391 円です。」と答えてくれることを期待していました。が、結果は・・・ 計算や数値は期待通りなのですが、"Thornton" って何?? ともあれ、数字を計算して答えることや、その計算方法は理解してもらえている・・・と思います:
2024092505


というわけで、この方向で為替計算を教えるような LLM チューニングを試みてみます。


【プロジェクトと Tuning Studio の準備】
改めて、ここからが LLM チューニングの紹介内容です。

まずは LLM チューニングを行うための準備といえる作業をいくつか実行します。その1つが「プロジェクトの準備」です。既に Watsonx.AI のプロジェクトを作成済みの人もいると思いますが、もし環境的に問題なければ新しいプロジェクトを1つ作ってから LLM チューニングを行うことを推奨します(そうすると後述で紹介するチューニングコストを確認しやすいため)。もちろん既存プロジェクトを選択してチューニングしても構いません。

プロジェクトを新規に作成する前に現在の環境で作成されているプロジェクトの一覧を確認します。 Watsonx.AI の画面左上のハンバーガーメニューをクリックします:
2024092506


このメニューから「すべてのプロジェクトの表示」を選択します:
2024092507


現在までに作成されたプロジェクトの一覧が表示されます。ここから1つ選択して、そのプロジェクト内でチューニングを実行することも可能です。 プロジェクトを新規に作成するには右上の「新規プロジェクト」ボタンをクリックします:
2024092508


新規に作成するプロジェクトの情報を入力します。まずはプロジェクトの名前を入力します:
2024092509


このプロジェクトで利用するストレージサービス(Cloud Object Storage)のインスタンスを選択します。1つ選ぶか、新規に作成して指定します。最後に「作成」ボタンが有効化されたら「作成」します:
2024092510


既存プロジェクトを選択した場合はそのプロジェクトが、プロジェクトを新規作成した場合は作成されたプロジェクトが開きます。この画面内でプロジェクト内で使ったリソース量が表示されます。新規作成した場合はこの時点ではゼロになっているので、この後のチューニング作業でどの程度増えているか確認しやすいと思っています:
2024092511



【Tuning Studio によるチューニングの手順】
Watsonx.AI では LLM をチューニングするためのオンラインツール "Tuning Studio" を利用することができます。このオンラインツールを使って、チューニング元の LLM モデルに自分で与えた学習データを使ったチューニングを施した、新しい LLM モデルを作ることができます。

では以下に実際に Tuning Studio を使って LLM をチューニングしていく手順を紹介します。

プロジェクト画面を開きます(作ったばかりなせいか、リソース消費量の表示がおかしくなっています。この時点では実際は全てゼロのはず)。ここから実際にプロンプト問い合わせを実行するプロンプト・ラボにも移動できますが、今回は LLM モデルのチューニングを行う「ラベル付きデータを使用したファウンデーション・モデルの調整」を選択します:
2024092512


最初にチューニングそのものに適当な名称、説明、タグを付与し「作成」ボタンをクリックします:
2024092513


するとチューニングのアセットが作られ、そのチューニング内容を指定する画面になります。まずはチューニング元になる LLM (言語モデル)を選択します。「基礎モデルの選択」ボタンをクリックします:
2024092514


ここで選択できる LLM の一覧が表示されます。2024-09-25 時点ではここで選択できる LLM は "fran-t5-xl-3b" か "granite-13b-instruct-v2" のいずれかでした(これを知っていたので、上述のプロンプトでも granite-13b-instruct-v2 を使ってプロンプトを試していました)。ここから1つ選んでチューニングするわけですが、今回は IBM の "granite-13b-instruct-v2" を選択しました:
2024092515

※実際のチューニングではここでベースとなる LLM を何にするかによってもチューニングの結果は異なることになります。一般的にはここで選択する LLM は「プロンプトエンジニアリングを試した時点で相性の良さそうな LLM を選ぶ」のが良いとされています。


選択した LLM の説明文が表示されます。これで問題なければ「選択」をクリックします:
2024091209


チューニング元 LLM の選択ができました。すると画面右に「トレーニング・データの追加」と書かれたファイルアップロード画面が表示されます。ここで追加用チューニングデータを指定してチューニングを行うことができます。追加用チューニングデータのフォーマットが分からない場合は(青枠の)「テンプレートのプレビュー」ボタンをクリックします:
2024092516


「テンプレートのプレビュー」をクリックし、"JSON" タブを選択すると以下のような画面が表示されます。"input" と "output" の要素を含む JSON が配列になっていて、この input にプロンプト例、output に問い合わせ結果例が含まれているようなデータを作る、ということのようでした(最大で 10000 サンプル、200MB。これ以外に配列の "[" , "]" を抜いた JSONL 型のデータも使えるようです):
2024092517


このようなフォーマットでチューニング用データを集めて指定してチューニング、、を行うことになります。今回は為替計算を正しく行ってもらうことが目的なので、以下のようなデータを用意してみました:
[
  {
    "input": "1 ドルは 140 円です。 10 ドルは何円ですか?",
    "output": "1 ドルが 140 円なので、 10 ドルは約 140 * 10 = 1400 円です。"
  },
  {
    "input": "1 ドルは 140 円です。 20 ドルは何円ですか?",
    "output": "1 ドルが 140 円なので、 20 ドルは約 140 * 20 = 2800 円です。"
  },
  {
    "input": "1 ドルは 140 円です。 30 ドルは何円ですか?",
    "output": "1 ドルが 140 円なので、 30 ドルは約 140 * 30 = 4200 円です。"
  },
  :
  :

為替のレートを与えた時の「〇〇ドルは何円ですか?」という質問に答えられるようにするためのインプットとアウトプットのペアを大量に用意してチューニングし、実際のレートと質問を与えた時に(プロンプトで工夫しなくても)正しく答えることができるようにするための JSON 配列型の学習データを用意しました(実際には異なる計算もできるような例が含まれています。興味ある方は全部見てください)。

この架空のデータファイル(training-fx.json)をトレーニングデータとして公開することにします。LLM チューニングを体験する目的で、直接ダウンロードして使っていただいても構いません:
https://raw.githubusercontent.com/dotnsf/watsonx.ai-tuning/refs/heads/main/training-fx.json

そして Tuning Studio 画面の「参照」ボタンから、用意した training-fx.json ファイルを指定してアップロードします:
2024092518


アップロードが完了すると「トレーニングデータの追加」の準備はできたことになります:
2024092519


必要であれば「パラメーターの構成」ボタンをクリックして、チューニング時のパラメータを変更します:
2024092520


パラメータを調整する画面が表示されます。必要に応じてパラメータを調整して「保存」します(必要なければ「キャンセル」します):
2024092521


最後にプロンプトの初期化内容を指示します。今回の場合は「与えられた条件から計算して額を答えてほしい」ことが分かっているので、初期化方法に「テキスト」、その内容には「以下は入力された質問に対する出力のサンプルです。サンプルと同様に与えられた質問に対する答を計算して簡潔に答えてください。」と入力します:
2024092522


更に下にスクロールするとタスクの種類を指定する箇所があります。今回の例では「計算して答える」という「プロンプトに含まれない情報を生成する」ものなので、「生成」を選択します。 ここまで選択すると画面右下の「チューニングの開始」ボタンが有効になります。 ここをクリックしてチューニングを開始します:
2024092523


このような画面になってチューニングが開始されます。ここからはチューニングが完了するまで、ひたすら待ちます:
2024092524


チューニングが完了すると以下のような画面になります(先ほどのデータでは 16 分でした)。一般的には(表示されている)損失関数は右肩下がりになるのがいいと言われていますが、ちょっと
2024092525


このチューニングした LLM を実際に使えるようにするにはデプロイする必要があります。画面下部(見えない場合は下にスクロール)の「新規デプロイメント」をクリックします:
2024092526


名前(必須)と説明等を入力します。続きがあるので下にスクロールします:
2024092527


展開コンテナは「このプロジェクト」を選択し、デプロイメント・サービス提供社名を(適当に)入力します。最後に「作成」ボタンをクリックしてデプロイを開始します:
2024092528


少し待つと以下のような画面に切り替わります。このデプロイメントのリンクをクリックします:
2024092529


デプロイメントの様子が分かります。デプロイメントが完了するまで少し時間がかかります。ステータスが「進行中」から「デプロイ済み」になるまで待ちます:
2024092530


「デプロイ済み」になれば、チューニングした LLM はデプロイされ、実際に使える状態になったことを意味します:
2024092531


【チューニング済み LLM を使う】
チューニングされた LLM がデプロイ済みになっていれば、外部からの API 呼び出しや、プロンプトラボなどから実際に使うことができます。先ほどのページの「API リファレンス」タブにはエンドポイント URL や cURL コマンドなどで使う場合のコマンドが表示されています。 ここではプロンプトラボから試す方法を紹介します。といっても「Prompt Lab で開く」ボタンをクリックするだけです:
2024092532


するとプロンプトラボの画面が表示されます。この時、LLM は自分がチューニングしたモデルになっていることを確認します:
2024092533

基盤モデルの一覧を表示した場合でも、このチューニング済みモデルが表示され、選択可能になっていることを確認してください:
2024092534


改めてプロンプトラボを「フリーフォーム」で、LLM は自分がチューニングしてデプロイしたモデルを選択した状態にします:
2024092535


そしてプロンプトとして以下のように入力します(このブログを書いている最中の実際のドル円相場の数字です):
与えられた質問に対する答を計算して簡潔に答えてください。

1 ドルは 144.3 円です。 10 ドルは何円ですか?
2024092536


もともとは何も計算してくれなかったプロンプトです。これを「生成」します:
2024092537


・・・うーん、まだ 100 点とはいえないか。想定していた答とは違いますが、とりあえず計算はしてくれるようになりました。このプロンプトはチューニング前だと正しい数値を返すこともなかったものなので、いくらかの進展はあったと言えるんじゃないかと思いますが、うーん。。。

まあ、今回のチューニングデータは説明目的でサイズもまだまだ小さく、サンプルとしては不十分であった可能性は高いものです。もうちょっと色んなパターンに対応したり、数を増やしたりすることで制度上がるんだろうか? この辺りはまだ未検証です。 ただ Watsonx.AI の LLM チューニングがどういったものなのか、そのための Tuning Studio をどう使うのか、という点ではある程度理解しやすいものではなかったか、と思っています。


【チューニングのコスト】
Watsonx.ai の LLM を Tuningu Studio でチューニングする際のコストも気になるところです。チューニングコストは与えるサンプルデータ量によっても変わるので事前に具体的なコストを予測計算するのは難しいのですが、以下にチューニングコストの考え方・計算方法についてまとめておきます。 

なお、以下の説明に使っている数字部分は 2024 年 9 月 25 日時点のものであることに注意してください。実際にコストを見積もる際には自分の契約しているプランや為替レートを含めた最新情報・最新価格を参照して再度計算するべきであることに留意ください。

まず覚えておいていただきたいことは「LLM チューニングの価格は CUH(Capacity Unit / Hour : 容量単位時間)によって決まる」ということです。

要は、
 1 どのようなスペックのサーバーを
 2 どのくらいの時間使って
チューニングしたか、という計算能力と計算量によって計算で決まる、という意味です。

どのようなスペックのサーバーを使って LLM チューニングしているか、という情報はこちらを参照して調べます:
https://dataplatform.cloud.ibm.com/docs/content/wsj/getting-started/wml-plans.html?context=wx&audience=wdp#cuh-metering


この中の「資産タイプ別 CUH 消費率」という項目内の「基礎モデルの調整実験(watsonxのみ)」と書かれた所が LLM チューニング時に使われるサーバーで、その CUH は(2024/09/25 時点で)43 となっています:
2024091211


この 43 というのが(1時間の)チューニング時に利用されるサーバーのスペックを表す数字だと思ってください。この数字だけだとどんなスペックか想像しにくいですが、他の数字よりもかなり大きめの数字になっているので、それなりのサーバーが使われる、という理解でいいと思います。 ただあくまで1時間の数字です。チューニングに必要な時間が 30 分ならこの半分に、2時間ならこの倍になります。

そして、1 CUH あたりでいくらかかるのか、というのは Watsonx.AI 作成時の Watson Machine Learning サービスインスタンスのプランによって変わります。例えば Essential Plan の場合、1CUH あたりの額は(2024/09/25 時点で)75.7146 円となっています:
2024091201


これらの数値より、仮にチューニングにかかる時間が1時間であったとすると、そのチューニングコス
  1(H) * 43(CUH) * 75.7146 (JPY) = 3255.7278 (円)
ということになります。 あくまで 2024/09/25 時点の Essential Plan での価格および為替レートに基づいた1時間あたりの数字なので、実際の価格は自分のプラン、チューニングデータ量に合わせて再度計算が必要になる点に注意してください。

そして、では今回の(上述のチューニングデータを使っての)チューニングでどれだけの CUH を消費したか、という数値はチューニング後のプロジェクト画面に反映されています。私が実際に上記データを使ってチューニングした結果は以下のようになっていました:
2024092538


11.8 CUH とのことでした(あくまで私が試した時の結果です)。これはつまり、
 11.8(CUH) * 75.7146 (JPY) = 893.43228(円)
ということになりました。 実際、このチューニングでは不十分だったと思っているので、あまり参考にならない数字かもしれませんが、「試しに1回軽くチューニングすると千円くらい」というのが1つの目安に・・・なりますかね? 繰り返しますが、あくまで目安の数字であることに注意してください。


【まとめ】
今の時点でまだあまり外部情報のない Tuningu Studio を使ってみました。2024-09-25 現在ではプロンプト・チューニングだけが提供されている状況で、「膨大なトークン数を消費してコストがかさむのを防ぐためのチューニング」が主目的になるものと考えられます。 こういうコスト削減方法もあるんですねー。




このページのトップヘ