はじめに
みなさん、LLMOpsは何で構築していますか。
Azure系のサービスやLangSmithなど様々な回答があると思いますし、自作のLLMOps環境を構築している方々の少なくないと思います。
今回はLLMOps構築の一つの選択肢として、MLflowを紹介したいと思います。
MLflowとは
MLflowはLLMOpsのみならず、MLOpsを構築できるオープンソースプラットフォームです。
LLMOpsに求められる基本的な実験の記録や評価を実施できますし、セルフホストで実行可能という特徴があります。
MLflowを使ってみる
環境構築
まずは必要なライブラリをインストールします。
(venv) % pip install mlflow==2.14.0rc0
(venv) % pip install langchain==0.2.1 langchain-openai==0.1.8 langchain-community==0.2.1 tiktoken==0.7.0
Azure OpenAIをLangChain経由で使うため、LangChain系のライブラリをインストールしています。
次にLLMを用意します。筆者はAzure OpenAIを使うので、事前にAzure AI Serviceを作り、モデルをデプロイします。
そしてプログラムでAzure OpenAIを使うためにAPIキーとエンドポイントを環境変数に追加します。
% export AZURE_OPENAI_API_KEY={}
% export AZURE_OPENAI_ENDPOINT={}
MLflowの立ち上げ
MLflowの立ち上げは簡単で、MLflowをインストールした環境で以下のコマンドを実行してください。
(venv) % mlflow ui --port 9000 --backend-store-uri sqlite:///mlruns.db
--port
でMLflowのポート番号を指定できます。
--backend-store-uri
でMLflowのログや設定情報を保存するDBを指定します。事前にDBを作成する必要はなく、初回は自動で作成してくれます。
ちなみにDBを指定しない場合はmlrunsディレクトリが自動で作成され、mlruns配下に情報が格納されます。(DBの指定の仕方は他にも環境変数 MLFLOW_TRACKING_URI
を設定する方法があります。)
正常に実行が完了している場合は、http://127.0.0.1:9000/ にアクセスすると、以下のような画面が出てきます。
MLflowの使い方1:オートログ
LangChainを使う場合は、MLflowに対して自動で実験を記録する設定を導入することができます。以下サンプルコードです。
from langchain_openai import AzureChatOpenAI
import mlflow
mlflow.set_tracking_uri("http://localhost:9000")
mlflow.set_experiment("Test0001")
mlflow.langchain.autolog()
llm = AzureChatOpenAI(
openai_api_version="2024-05-01-preview",#自身のAPI versionを入力してください。
azure_deployment="gpt-35-turbo",#モデルデプロイ名を入力してください。
model_version="0301"#自身のモデルversionを入力してください。
)
output = llm.invoke("Say, Hello.")
上記プログラムを実行すると、画面左側のUIのExperimentsにTest0001が追加され、Traceに情報が保存されています。
ここでReqeust IDをクリックするとリクエストの詳細を確認できます。
LangChainで複数の処理をチェインする場合は、各処理の入出力や経過時間を確認できます。
プログラムを少し解説します。
mlflow.set_experiment("Test001")
上記のmlflow.set_experiment
で実験を設定します。引数で設定した名前の実験がなければ、新たに実験を作成できます。
mlflow.langchain.autolog()
上記のmlflow.langchain.autolog()
でLangChainでの実行を自動でロギングすることができます。
詳細は以下ドキュメントをご覧ください。
MLflowの使い方2:デコレータを使う方法
上記で説明したmlflow.langchain.autolog()
を使わない場合は、デコレータを使って以下のように記述できます。
from langchain_openai import AzureChatOpenAI
import mlflow
mlflow.set_tracking_uri("http://localhost:9000")
mlflow.set_experiment("Test0002")
llm = AzureChatOpenAI(
openai_api_version="2024-05-01-preview",
azure_deployment="gpt-35-turbo",
model_version="0301"
)
@mlflow.trace(span_type="func")
def run(llm, text):
return llm.invoke(text)
output = run(llm, "Say, Hello.")
上記のようにプログラムを実行すると、先ほどと同様に結果を記録できます。
また以下のように関数を独立させて記述することもできます。
from langchain_openai import AzureChatOpenAI
import mlflow
mlflow.set_tracking_uri("http://localhost:9000")
mlflow.set_experiment("Test0003")
llm = AzureChatOpenAI(
openai_api_version="2024-05-01-preview",
azure_deployment="gpt-35-turbo",
model_version="0301"
)
@mlflow.trace(span_type="func")
def llm_run(llm, text):
return llm.invoke(text)
@mlflow.trace(span_type="func")
def run(llm, text):
return llm_run(llm,text)
output = run(llm, "Say, Hello.")
上記のように記述すると、それぞれの関数の処理を区別してMLflowに記録することができます。このように記述することで、(今後関数を増やす場合においても)複数の関数の入出力をMLflowで記録できます。
mlflow.trace()
のドキュメントを以下に載せておきます。今回は解説していないですが、with
を使って記述することも可能です。
各処理を関数化している場合はwithを使うよりもデコレータを使った方が楽に記述できるはずです。
おわりに
いかがだったでしょうか。
MLflowをLLMOpsとして使うという日本語記事が少なかったので、記事を投稿してみました。
好評であれば、評価の部分も記事執筆したいと思います。
また筆者はまだまだMLflowを熟知しているわけではないので、誤っている点等あればコメントいただけると大変助かります。
おまけ
MLflowのほかにLLMOps関連で筆者が知っているものは以下です。適宜追加していきます。