Tutorial: Getting Started with ChatModelの翻訳です。
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
MLflowのChatModelクラスは、プロダクションレディの会話型AIモデルを作成するための標準化された手段を提供します。結果として得られるモデルは、MLflowのトラッキング、評価、ライフサイクル管理機能と完全にインテグレーションされます。これらは、MLflowモデルレジストリで他の人と共有したり、REST APIとしてデプロイしたり、インタラクティブに使うためにノートブックにロードすることができます。さらに、これらは広く導入されているOpenAI chat APIの仕様に互換性があるので、他のAIシステムやツールとの連携が容易になります。
すでにPythonModelに慣れているのであれば、なぜChatModelが必要なのかと不思議に思うかもしれません。生成AIアプリケーションはどんどん複雑になっており、カスタムのPythonModel
を用いた入出力、パラメーターのマッピングは困難になることがあります。ChatModel
は、会話型AIモデルのために、構造化され、OpenAIと互換性のあるスキーマを提供することで、これをシンプルにします。
ChatModel | PythonModel | |
---|---|---|
使用するケース | OpenAIの仕様と互換性のある標準チャットスキーマで会話型モデルを開発、デプロイする際に使用。 | モデルのインタフェースに対するフルコントロールを必要とする、あるいはモデルの挙動の全ての側面をカスタマイズしたい際に使用。 |
インタフェース | OpenAIのチャットスキーマに固定。 | モデルの入出力スキーマに対するフルコントロール。 |
セットアップ | クイック。定義済みのモデルシグネチャと入力例を用いて、会話型のアプリケーションですぐに利用可能。 | カスタム。自分でモデルのシグネチャと入力サンプルを定義する必要がありる。 |
複雑度 | 低い。標準化されたインタフェースがモデルのデプロイとインテグレーションをシンプルに。 | 高い。カスタムのPythonModelのデプロイとインテグレーションはわかりにくくなる場合がある。例えば、MLflowがPythonModelに入力データを渡す前に、入力データをPandasデータフレームに変換するので、モデルはPandasデータフレームを取り扱う必要がある。 |
学ぶこと
このガイドでは、カスタムの会話型AIモデルを定義するための基本的なChatModel APIの使い方をウォークスルーします。特に、以下のことを学びます:
- あなたのアプリケーションロジックを
ChatModel
の入力/出力スキーマにマッピングする方法。 - ChatModelでサポートされる定義済みの推論パラメータの使い方。
-
custom_inputs
を用いて、ChatModelにカスタムのパラメータを渡す方法。 - カスタムチャットモデルを定義する際のChatModelとPythonModelの比較。
これらのポイントを説明するために、このガイドでは例としてローカルにホストされたOllamaモデルを用いて、カスタムのChatModel
の構築をウォークスルーします。ビルトインのOllamaモデルフレーバーは存在しないので、MLflowのさまざまなトラッキング、評価、ライフサイクル管理機能をOllamaモデルで使うために、カスタムのChatModel
を作成します。
前提条件
- MLflowのロギングAPIと生成AIの概念に対する習熟度。
- ChatModelを使うためにMLflowバージョン2.17.0以降がインストールされていること。
ChatModelを理解する: 入力/出力のマッピング
mlflow.pyfunc.ChatModelインタフェースは、あなたのアプリケーションとMLflowのエコシステムの間に存在し、あなたのアプリケーションとMLflowの他の機能との連携や、アクセス可能かつプロダクションレディなフォーマットを用いたモデルのデプロイを容易にする、標準化レイヤーを提供します。
そのためには、カスタムのChatModel
を定義する際のキーとなるタスクとして、ChatModel
の標準化されたインタフェースにあなたのアプリケーションのロジックをマッピングする必要があります。このマッピングの練習は、カスタムのChatModel
を作成する際の重要な部分となります。
カスタムChatModelを使用する際、predict
メソッドは以下のように標準化された入力を期待します:
input = {
"messages": [{"role": "user", "content": "What is MLflow?"}],
"max_tokens": 25,
}
ここには、メッセージのリストを含むmessages
キー、max_tokens
、temperature
、top_p
、stop
のようなオプションの推論パラメータが含まれています。こちらで完全なchat requestオブジェクトの詳細を確認することができます。
また、出力も以下のように標準化されたフォーマットで返却されます:
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "MLflow is an open-source platform for machine learning (ML) and artificial intelligence (AI). It's designed to manage,",
},
"finish_reason": "stop",
}
],
"model": "llama3.2:1b",
"object": "chat.completion",
"created": 1729190863,
}
こちらで完全なchat responseオブジェクトの詳細を確認することができます。
これらの入力/出力スキーマは、広く受け入れられているOpenAIの仕様と互換性があるので、いろいろな文脈でのChatModel
の活用が用意となります。
このマッピングプロセスをデモンストレーションするために、ネイティブなMLflowフレーバーを持たないOllama llmクライアントを通じて、MetaのLlama 3.2 1Bモデルを記録するために、mlflow.pyfunc.ChatModelの使い方を説明します。
初めてのChatModelの構築
このセクションでは、ローカルにホストされたOllamaモデルをChatModel
インタフェースでラッピングします。入出力の取り扱い方を説明するためにシンプルなバージョンを構築し、max_tokens
やtemperature
のような推論パラメータの取り扱い方法を説明します。
セットアップ: Ollamaのインストールとモデルのダウンロード
- こちらからOllamaをインストールします。
- Ollamaがインストールされ稼働したら、
ollama pull llama3.2:1b
を実行してLlama 3.2 1Bモデルをダウンロードします。
ollama run llama3.2:1b
でモデルがダウンロードされ、システムで利用できることを検証できます。
> ollama run llama3.2:1b
>>> Hello world!
Hello! It's great to see you're starting the day with a cheerful greeting. How can I assist you today?
>>> Send a message (/? for help)
Ollamaモデルのインタフェースとして、ollama-python
ライブラリを使います。pip install ollama
で環境にインストールします。また、pip install mlflow
でmlflow
をインストールします。
Ollama Pythonライブラリの使用
ChatModelの入出力スキーマにOllamaの入出力スキーマをマッピングするには、はじめにOllamaモデルが期待、返却する入力と出力の種類を理解する必要があります。シンプルなプロンプトでこのモデルにクエリーする方法を示します:
import ollama
from ollama import Options
from rich import print
response = ollama.chat(
model="llama3.2:1b",
messages=[
{
"role": "user",
"content": "What is MLflow Tracking?",
}
],
options=Options({"num_predict": 25}),
)
print(response)
以下の出力が返却されます:
{
'model': 'llama3.2:1b',
'created_at': '2024-11-04T12:47:53.075714Z',
'message': {
'role': 'assistant',
'content': 'MLflow Tracking is an open-source platform for managing, monitoring, and deploying machine learning (ML) models. It provides a'
},
'done_reason': 'length',
'done': True,
'total_duration': 1201354125,
'load_duration': 819609167,
'prompt_eval_count': 31,
'prompt_eval_duration': 41812000,
'eval_count': 25,
'eval_duration': 337872000
}
Ollamaの入出力に関して注意すべきことがいくつかあります:
-
ollama.chat
メソッドによって期待される引数messages
は、role
とcontent
のキーを持つディクショナリーのリストです。ChatModel APIによって期待されるChatMessage
オブジェクトのリストをディクショナリーのリストに変換する必要があります。 - パラメータのディクショナリーである引数
options
を通じて、Ollamaに推論パラメータが渡されます。さらに、num_predict
にあるように、パラメータ名はChatModelで期待されるパラメータ名と異なっています。ChatModelの推論パラメータをOllamaのオプションにまっっピングする必要があります。 - 出力の構造は
ChatModel
の出力スキーマと異なっています。これをChatModelの出力スキーマにマッピングする必要があります。
Ollama ChatModelバージョン1: チャットのみ
推論パラメータには対応しませんが、入力/出力のメッセージに対応するシンプルなバージョンのカスタムChatModel
からスタートしましょう。これを達成するには以下が必要となります:
- mlflow.pyfunc.ChatModelを拡張するクラスを定義します。
- Ollamaクライアントの初期化を取り扱う
load_context
メソッドを実装します。 - 入出力マッピングを取り扱う
predict
メソッドを実装します。
少なくともこのシンプルなバージョンのカスタマイズの大部分は、predict
メソッドで行われます。predict
メソッドを実装する際には、以下の標準化された入力を活用します:
-
messages
:ChatMessage
オブジェクトのリスト -
params
: 推論パラメータを含むChatParams
オブジェクト
そして、ChatChoice
オブジェクトのリストと(オプションの)利用データや他のメタデータから構成されるデータクラスであるChatCompletionResponse
オブジェクトを返却する必要があります。
これらがOllamaの入出力にマッピングしなくてはならないものです。今のところは、入出力メッセージのみを取り扱うシンプルなバージョンとなります:
# if you are using a jupyter notebook
# %%writefile ollama_model.py
from mlflow.pyfunc import ChatModel
from mlflow.types.llm import ChatMessage, ChatCompletionResponse, ChatChoice
from mlflow.models import set_model
import ollama
class SimpleOllamaModel(ChatModel):
def __init__(self):
self.model_name = "llama3.2:1b"
self.client = None
def load_context(self, context):
self.client = ollama.Client()
def predict(self, context, messages, params=None):
# Prepare the messages for Ollama
ollama_messages = [msg.to_dict() for msg in messages]
# Call Ollama
response = self.client.chat(model=self.model_name, messages=ollama_messages)
# Prepare and return the ChatCompletionResponse
return ChatCompletionResponse(
choices=[{"index": 0, "message": response["message"]}],
model=self.model_name,
)
set_model(SimpleOllamaModel())
上のコードでは、Ollamaの入力にChatModel
の入力、Ollamaの出力をChatModel
の出力スキーマにマッピングしました。特に:
-
ChatModel
の入力スキーマにおけるmessages
キーは、ChatMessage
オブジェクトのリストとなります。これをOllamaで期待される入力であるrole
とcontent
キーのディクショナリーのリストに変換しました。 -
predict
メソッドが返却するChatCompletionResponse
は、ChatCompletionResponse
データクラスを用いて作成する必要がありますが、期待されるスキーマにマッチするディクショナリーとして、ネストされたメッセージやチョイスデータを提供することもできます。MLflowは自動的にこれらのディクショナリーを適切なデータクラスオブジェクトに変換します。我々のケースでは、ChatCompletionResponse
を作成しましたが、ディクショナリーとしてチョイスとメッセージを提供しちえます。
ノートブックの環境では、%%writefile
マジックコマンドでollama_model.py
と呼ばれるファイルにモデルを保存し、set_model(SimpleOllamaModel())
を呼び出すことができます。これは、こちらで詳細を確認できる「models from code」のモデルロギングのアプローチです。
これで、以下のように作成したモデル定義を含むファイルへのパスを指定することで、MLflowにこのモデルを記録することができます:
import mlflow
mlflow.set_experiment("chatmodel-quickstart")
code_path = "ollama_model.py"
with mlflow.start_run():
model_info = mlflow.pyfunc.log_model(
"ollama_model",
python_model=code_path,
input_example={
"messages": [{"role": "user", "content": "Hello, how are you?"}]
},
)
繰り返しになりますが、モデルを記録するためにmodels-from-codeアプローチを採用しているので、python_model
パラメータにモデル定義を含むファイルへのパスを指定しています。これで、モデルをロードして試すことができます:
loaded_model = mlflow.pyfunc.load_model(model_info.model_uri)
result = loaded_model.predict(
data={
"messages": [{"role": "user", "content": "What is MLflow?"}],
"max_tokens": 25,
}
)
print(result)
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "MLflow is an open-source platform for model deployment, monitoring, and tracking. It was created by Databricks, a cloud-based data analytics company, in collaboration with The Data Science Experience (TDEE), a non-profit organization that focuses on providing high-quality, free machine learning resources.\n\nMLflow allows users to build, train, and deploy machine learning models in various frameworks, such as TensorFlow, PyTorch, and scikit-learn. It provides a unified platform for model development, deployment, and tracking across different environments, including local machines, cloud platforms (e.g., AWS), and edge devices.\n\nSome key features of MLflow include:\n\n1. **Model versioning**: Each time a model is trained or deployed, it generates a unique version number. This allows users to track changes, identify conflicts, and manage multiple versions.\n2. **Model deployment**: MLflow provides tools for deploying models in various environments, including Docker containers, Kubernetes, and cloud platforms (e.g., AWS).\n3. **Monitoring and logging**: The platform includes built-in monitoring and logging capabilities to track model performance, errors, and other metrics.\n4. **Integration with popular frameworks**: MLflow integrates with popular machine learning frameworks, making it easy to incorporate the platform into existing workflows.\n5. **Collaboration and sharing**: MLflow allows multiple users to collaborate on models and tracks changes in real-time.\n\nMLflow has several benefits, including:\n\n1. **Improved model management**: The platform provides a centralized view of all models, allowing for better model tracking and management.\n2. **Increased collaboration**: MLflow enables team members to work together on machine learning projects more effectively.\n3. **Better model performance monitoring**: The platform offers real-time insights into model performance, helping users identify issues quickly.\n4. **Simplified model deployment**: MLflow makes it easy to deploy models in various environments, reducing the complexity of model deployment.\n\nOverall, MLflow is a powerful tool for managing and deploying machine learning models, providing a comprehensive platform for model development, tracking, and collaboration.",
},
"finish_reason": "stop",
}
],
"model": "llama3.2:1b",
"object": "chat.completion",
"created": 1730739510,
}
これで、標準化され、OpenAIと互換性のあるフォーマットでチャットのレスポンスを受け取りました。しかし、何かおかしいです: max_tokens
を25に設定したのに、レスポンスは25トークン以上となっています!なぜでしょうか?
我々のカスタムChatModelでは、まだ推論パラメータに対応していません: ChatModelとOllamaフォーマット間での入力/出力のメッセージのマッピングに加え、二つのフォーマット間の推論パラメータをマッピングする必要があります。カスタムChatModelの次のバージョンではこれに対応します。
推論パラメーターを受け付けるChatModelの構築
多くのLLMでは、レスポンスに含めるトークン数を制限するmax_tokens
やレスポンスの「創造性」を調整するtemperature
のように、レスポンスの生成方法を制御する推論パラメータをサポートしています。ChatModel APIでは、一般的に使用される推論パラメータの多くに対するビルトインのサポートが提供されており、このセクションではどのように設定、活用するのかを設営します。
ChatModelへのパラメータの引き渡し
ChatModelを使う際、入力のメッセージと共にパラメータが引き渡されます:
result = model.predict(
{
"messages": [{"role": "user", "content": "Write a story"}],
"max_tokens": 100,
"temperature": 0.7,
}
)
こちらでサポートされるパラメータの完全なリストを確認できます。さらに、次のセクションでカバーするcustom_inputs
キーを通じて、ChatModelに任意の追加パラメータを渡すことができます。
カスタムPyFuncモデルにおけるパラメータの取り扱いとの比較
PyFuncモデルでの推論パラメータに慣れているのであれば、ChatModelにおけるパラメータの取り扱いにはいくつかのキーとなる違いがあることに気づくことでしょう:
ChatModel | PyFunc |
---|---|
パラメータはpredict に引き渡されるmessages キーを含むdata ディクショナリーの一部となります。 |
パラメータはparams キーワード引数としてpredict に引き渡されます。 |
ChatModelクラスでは、一般的に使われるチャットモデルパラメータ(max_tokens 、temperature 、top_p など)は事前に定義されています。 |
開発者によってパラメータは選択、設定されます。 |
一般的なチャットモデルパラメータをサポートするために、モデルシグネチャは自動で設定されます。 | モデルシグネチャでパラメータを明示的に定義する必要があります。 |
まとめると、ChatModelによって推論パラメータの設定と利用が簡単になることに加えて、ある程度の柔軟性と引き換えに、標準化され、OpenAIと互換性がある出力フォーマットが提供されます。
それでは、推論パラメータを取り扱うカスタムChatModelを設定しましょう。
Ollama ChatModelバージョン2: 推論パラメータを用いたチャット
推論パラメータを持つChatModelのセットアップはわかりやすいものとなっています: 入力メッセージのように、Ollamaクライアントで期待されるフォーマットに推論パラメータをマッピングする必要があります。Ollamaクライアントでは、推論パラメータはoptions
ディクショナリーとしてモデルに渡されます。カスタムChatModelを定義する際に、params
キーワード引数を通じて、predict
に渡される推論パラメータにアクセスすることができます。ここでの仕事は、Ollamaクライアントのoptions
ディクショナリーにpredictメソッドのparams
ディクショナリーをマッピングすることです。Ollamaでサポートされているオプションのリストはこちらで確認することができます。
# if you are using a jupyter notebook
# %%writefile ollama_model.py
import mlflow
from mlflow.pyfunc import ChatModel
from mlflow.types.llm import ChatMessage, ChatCompletionResponse, ChatChoice
from mlflow.models import set_model
import ollama
from ollama import Options
class OllamaModelWithMetadata(ChatModel):
def __init__(self):
self.model_name = None
self.client = None
def load_context(self, context):
self.model_name = "llama3.2:1b"
self.client = ollama.Client()
def _prepare_options(self, params):
# Prepare options from params
options = {}
if params:
if params.max_tokens is not None:
options["num_predict"] = params.max_tokens
if params.temperature is not None:
options["temperature"] = params.temperature
if params.top_p is not None:
options["top_p"] = params.top_p
if params.stop is not None:
options["stop"] = params.stop
if params.custom_inputs is not None:
options["seed"] = int(params.custom_inputs.get("seed", None))
return Options(options)
def predict(self, context, messages, params=None):
ollama_messages = [
{"role": msg.role, "content": msg.content} for msg in messages
]
options = self._prepare_options(params)
# Call Ollama
response = self.client.chat(
model=self.model_name, messages=ollama_messages, options=options
)
# Prepare the ChatCompletionResponse
return ChatCompletionResponse(
choices=[{"index": 0, "message": response["message"]}],
model=self.model_name,
)
set_model(OllamaModelWithMetadata())
以前のバージョンからの変更点を示します:
-
params
ディクショナリーからmax_tokens
、temperature
、top_p
、stop
をOllamaクライアントのoptions
ディクショナリーのnum_predict
、temperature
、top_p
、stop
にマッピングしました(Ollamaではmax_tokens
で期待されるパラメータ名が異なることに注意してください)。 - Ollamaクライアントの
chat
メソッドにoptions
ディクショナリーを引き渡しました。params
からoptions
へのマッピングを取り扱う新たなプライベートメソッド_prepare_options
を作成していることに注意してください。カスタムロジックに対応しつつも、コードをきれいで整理した状態に保つためにカスタムのChatModel
にメソッドを追加することができます。 -
seed
の値がparams
ディクショナリーにあるかどうかcustom_inputs
をチェックしています。これは次のセクションで詳細を説明します。
これで、以前と同じように、MLflowにこのモデルを記録し、ロードし、試すことができます:
code_path = "ollama_model.py"
with mlflow.start_run():
model_info = mlflow.pyfunc.log_model(
"ollama_model",
python_model=code_path,
input_example={
"messages": [{"role": "user", "content": "Hello, how are you?"}]
},
)
loaded_model = mlflow.pyfunc.load_model(model_info.model_uri)
result = loaded_model.predict(
data={
"messages": [{"role": "user", "content": "What is MLflow?"}],
"max_tokens": 25,
}
)
print(result)
以下が返却されます:
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "MLflow is an open-source platform that provides a set of tools for managing and tracking machine learning (ML) model deployments,",
},
"finish_reason": "stop",
}
],
"model": "llama3.2:1b",
"object": "chat.completion",
"created": 1730724514,
}
これで、ChatModelの入力スキーマからmax_tokens
をOllamaクライアントのnum_predict
パラメーターに適切にマッピングし、期待したトークン数のレスポンスを受け取っています。
カスタムパラメータの引き渡し
ビルトインの推論パラメータに含まれていないカスタムパラメータを引き渡したい場合にはどうしたらいいのでしょうか?ChatModel APIはそのままのモデルに引き渡されるキーバリューペアのディクショナリーを受け付けるcustom_inputs
キーを通じてそれを行う方法を提供します。キーとバリューの両方は文字列である必要があるので、predict
メソッドで型変換に対応する必要が出てくることがあります。上の例では、custom_inputs
ディクショナリーにseed
キーを追加することで、カスタムのseed
の値をOllamaモデルが使えるように設定しました:
if params.custom_inputs is not None:
options["seed"] = int(params.custom_inputs.get("seed", None))
これを含めたことで、predict
メソッドのcustom_inputs
キーを通じて、seed
の値を引き渡すことができます。同じシード値で複数回predict
メソッドをコールすると、常に同じレスポンスを受け取ります。
result = loaded_model.predict(
data={
"messages": [{"role": "user", "content": "What is MLflow?"}],
"max_tokens": 25,
"custom_inputs": {"seed": "321"},
}
)
print(result)
以下が返却されます:
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "MLflow is an open-source software framework used for machine learning model management, monitoring, and deployment. It's designed to provide",
},
"finish_reason": "stop",
}
],
"model": "llama3.2:1b",
"object": "chat.completion",
"created": 1730724533,
}
ティップ
ChatModelの使用 vs. 定義
ChatModelを使う際にデータを引き渡す方法と、ChatModelを定義する際にデータにアクセスする方法の間には重要な違いがあります。
インスタンスが作成されたChatModelを使う際には、メッセージ、パラメータなどのすべての引数は単一のディクショナリーとしてpredict
メソッドに引き渡されます。
model.predict({"messages": [{"role": "user", "content": "Hello"}], "temperature": 0.7})
一方、カスタムChatModelのpredict
メソッドを定義する際には、別々のmessages
とparams
引数を通じてデータにアクセスします。ここで、messages
はChatMessage
オブジェクトのリストであり、params
はChatParams
オブジェクトとなります。この違いを理解すること、すなわちユーザーには統合された入力、開発者には構造化されたアクセス、はChatModelを効果的に取り扱うためには重要なこととなります。
PyFuncとの比較
ChatModel
APIを通じてチャットモデルをセットアップすることと、PythonModel
APIを用いることのいくつかのメリットとトレードオフを説明するために、PythonModel
として上述のモデルを実装するとどうなるのかを見てみましょう。
Ollamaモデルバージョン3: カスタムPyFuncモデル
# if you are using a jupyter notebook
# %%writefile ollama_pyfunc_model.py
import mlflow
from mlflow.pyfunc import PythonModel
from mlflow.types.llm import (
ChatCompletionRequest,
ChatCompletionResponse,
ChatMessage,
ChatChoice,
)
from mlflow.models import set_model
import ollama
from ollama import Options
import pandas as pd
from typing import List, Dict
class OllamaPyfunc(PythonModel):
def __init__(self):
self.model_name = None
self.client = None
def load_context(self, context):
self.model_name = "llama3.2:1b"
self.client = ollama.Client()
def _prepare_options(self, params):
options = {}
if params:
if "max_tokens" in params:
options["num_predict"] = params["max_tokens"]
if "temperature" in params:
options["temperature"] = params["temperature"]
if "top_p" in params:
options["top_p"] = params["top_p"]
if "stop" in params:
options["stop"] = params["stop"]
if "seed" in params:
options["seed"] = params["seed"]
return Options(options)
def predict(self, context, model_input, params=None):
if isinstance(model_input, (pd.DataFrame, pd.Series)):
messages = model_input.to_dict(orient="records")[0]["messages"]
else:
messages = model_input.get("messages", [])
options = self._prepare_options(params)
ollama_messages = [
{"role": msg["role"], "content": msg["content"]} for msg in messages
]
response = self.client.chat(
model=self.model_name, messages=ollama_messages, options=options
)
chat_response = ChatCompletionResponse(
choices=[
ChatChoice(
index=0,
message=ChatMessage(
role="assistant", content=response["message"]["content"]
),
)
],
model=self.model_name,
)
return chat_response.to_dict()
set_model(OllamaPyfunc())
これは、上でChatModel
を定義した方法と非常に似ており、実際のところ、同じOllamaモデルをサービングするのにこのPythonModel
を使うことができます。しかし、いくつかの重要な違いが存在します:
- 最終的には入力は単なるメッセージのリストであるにもかかわらず、入力データをpandasデータフレームとして取り扱う必要がありました。
- 事前に定義されている
ChatParams
オブジェクトとして推論パラメータを受け取るのではなく、params
ディクショナリーを受け取っています。この結果の一つは、他の推論パラメータとは個別にseed
を取り扱う必要がないということでした: これらはPythonModel
APIにおいては、すべてがカスタムのパラメータとなります。 -
ChatCompletionResponse
ではなく、ChatCompletionResponse
をディクショナリーに変換するためにchat_response.to_dict()
を呼び出す必要がありました。これは、ChatModel
では自動的に対応されます。
モデルを記録する際に最大の違いのいくつかに直面します:
code_path = "ollama_pyfunc_model.py"
params = {
"max_tokens": 25,
"temperature": 0.5,
"top_p": 0.5,
"stop": ["\n"],
"seed": 123,
}
request = {"messages": [{"role": "user", "content": "What is MLflow?"}]}
with mlflow.start_run():
model_info = mlflow.pyfunc.log_model(
"ollama_pyfunc_model",
python_model=code_path,
input_example=(request, params),
)
カスタムのPythonModelでは、入力サンプルを用いてモデルシグネチャが推定できるように、入力サンプルを手動で定義する必要があります。これは、標準的なOpenAI互換の入力/出力/パラメータのスキーマに準拠するように自動的にシグネチャを設定するChatModel APIとの大きな違いとなります。入力サンプルに基づいたモデルシグネチャの自動推定に関しては、GenAI model signature exampleをご覧ください。
また、モデルのpredict
メソッドの呼び出し方法にも特筆すべき違いがあります: メッセージを含むディクショナリーではなく、params
キーワード引数を通じて、ディクショナリーとしてパラメータが引き渡されます。
loaded_model = mlflow.pyfunc.load_model(model_info.model_uri)
result = loaded_model.predict(
data={"messages": [{"role": "user", "content": "What is MLflow?"}]},
params={"max_tokens": 25, "seed": 42},
)
print(result)
これは以下を返却します:
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "MLflow is an open-source platform for machine learning (ML) and deep learning (DL) model management, monitoring, and",
},
"finish_reason": "stop",
}
],
"model": "llama3.2:1b",
"object": "chat.completion",
"created": 1731000733,
}
まとめると、ChatModel
は標準化され、OpenAI互換の入出力にフォーカスすることで、カスタムチャットモデルの定義に対してより構造化されたアプローチを提供します。ChatModel
のスキーマと螺っぽいんぐするアプリケーション間での入力/出力スキーマをマッピングするためのちょっとしたセットアップの手間はありますが、入力/出力/パラメータのスキーマの定義が多くの場合困難になるタスクに対応しなくてはならない完全にカスタムのPythonModelよりも取り扱いが簡単になる場合があります。一方、PythonModelのアプローチは、最大の柔軟性を提供しますが、開発者は入力/出力/パラメータのマッピングロジックのすべてを手動で対応する必要があります。
まとめ
このガイドでは、以下のことを学びました:
- あなたのアプリケーションロジックを
ChatModel
の入力/出力スキーマにマッピングする方法。 - ChatModelでサポートされる定義済みの推論パラメータの使い方。
-
custom_inputs
を用いて、ChatModelにカスタムのパラメータを渡す方法。 - カスタムチャットモデルを定義する際のChatModelとPythonModelの比較。
これで、ChatModel APIが何であって、カスタムチャットモデルを定義する際にどのように使えるのかについて感触がつかめたかと思います。
ChatModel
には、この入門ガイドでカバーしていない以下のようなその他の機能があります:
- 特にモデルが複数のコンポーネントやLLMのAPIを呼び出すモデルにおいて、あなたのチャットモデルをデバッグ、モニタリングする際に有用なMLflow Tracingのネイティブサポート。
- 外部設定ファイルを用いたモデル設定のカスタマイズのサポート。
これらの機能や、ChatModel APIのその他の高度な機能を学ぶにはこちらのガイドをご覧ください。