注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
model adapterは、Foundryと保存されたモデル作成物の間の通信レイヤーを提供する公開されたPythonライブラリで、任意のモデルをロード、初期化、推論実行できるようにFoundryを有効化します。
ModelAdapter
を実装するには、以下にリストされているクラスを理解する必要があります:
ModelAdapter
クラスは、すべてのモデルアダプター実装が拡張しなければならない抽象基底クラスです。すべてのモデルアダプターが実装しなければならない抽象メソッドは以下の4つです:
load()
save()
load()
とsave()
は必要ありません。api()
predict()
は単一出力のため、run_inference()
は複数出力のためです。Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
import palantir_models as pm import models_api.models_api_executable as executable_api class ExampleModelAdapter(pm.ModelAdapter): @classmethod def load( cls, state_reader: pm.ModelStateReader, container_context: Optional[executable_api.ContainerizedApplicationContext] = None, external_model_context: Optional[executable_api.ExternalModelExecutionContext] = None ) -> "pm.ModelAdapter": """ Pythonまたはバイナリモデル: これは、FoundryがModelAdapterをデシリアライズするために呼び出すメソッドです。このModelAdapterの作者は、saveメソッドでモデルが保存/シリアル化されたのと同じ場所からモデルの状態を読み込み、モデルを初期化するロジックを記述することが期待されています。 コンテナモデル: これは、FoundryがこのModelAdapterのサイドカーとしてコンテナが起動された後に呼び出すメソッドです。このModelAdapterの作者は、container_contextの内容を使用して、アダプタが必要とするクラス変数を初期化することが期待されています。例えば、ユーザーは、#run_inference内でコンテナにPOSTリクエストを送信するための関連するサービスURIを抽出することがよくあります。 外部でホストされているモデル: これは、Foundryがモデルアダプタが初期化されたときに呼び出すメソッドです。このModelAdapterの作者は、外部でホストされているモデルへの接続を初期化および維持し、他の必要なモデル設定を記述するロジックを記述することが期待されています。 :param state_reader: モデルファイルを読み取るために使用できるModelStateReaderオブジェクト。 :param container_context: これはコンテナバックアップモデルにのみ提供され、デフォルトではNoneです。コンテナのコンテキストには、コンテナ名からサービスURIへのマッピングと共有ディレクトリのマウントパスが含まれています。 :param external_model_context: これは外部でホストされているモデルにのみ提供され、デフォルトではNoneです。external_model_contextには、このモデルアダプタを使用する外部でホストされているモデルを作成する際にユーザーが定義する設定への参照が含まれています。 :return: ModelAdapterのインスタンス。 """ def save(self, state_writer: pm.ModelStateWriter) -> None: """ これは、Foundryがモデルアダプタをシリアル化するために呼び出すメソッドです。このメソッドは、Foundryで新しくトレーニングされたり再適合されたりしたモデルをラップするために使用されるModelAdapterの場合にのみ必要です。 このModelAdapterの作者は、トレーニング済みのモデルの状態と関連するメタデータをModelStateWriterに保存するロジックを記述することが期待されています。 :param state_writer: モデルがシリアル化され保存されるModelStateWriterオブジェクト。 """ @classmethod def api(cls) -> pm.ModelApi: """ これは、このモデルの入力と出力のデータ構造が期待されることを定義します。 :return: モデルのModelApiオブジェクト """ def run_inference(self, inputs, outputs) -> None: """ このメソッドは、ModelAdapater.apiメソッドで定義された関連する入力と出力で呼び出されます。 関連するモデルで推論を実行します。 :param inputs: ModelAdapater.apiメソッドで定義された入力の名前付きタプル。 :param outputs: ModelAdapater.apiメソッドで定義された出力の名前付きタプル。 出力は、run_inferenceメソッド内で書き込まれるべきです。 """ def predict(self, *args, **kwargs) -> Union[Tabular, Parameter]: """ このメソッドは、複数(>=1)の入力から単一の出力(表形式またはパラメータ)モデルに対して推論を実行するために使用されます。 入力は、api()メソッドで定義された名前でこのメソッドのシグネチャに書き込まれることが期待されています。結果の出力は、このメソッドで返されます。 predict()が使用される場合、ユーザーはrun_inference()メソッドを定義しません。 """
save()
と load()
palantir_models_serializers
ライブラリは、一般的なモデリングフレームワークのモデルシリアル化(保存)およびデシリアル化(読み込み)に使用できる多くのデフォルトシリアライザを提供しています。
場合によっては、ユーザーがモデルのシリアル化やデシリアル化のカスタムロジックを実装したい場合があります。たとえば、使用しているモデリングフレームワークにデフォルトのシリアライザがない場合や、いつどのモデルがメモリにロードされるかを手動で制御する必要がある場合などです。
これらのより複雑なケースでは、以下のsaveとloadの実装を参照してください。
Save
ModelStateWriter は、ModelAdapter.save
メソッドに提供されるため、ModelAdapter
はモデル作成物を Foundry ストレージに保存/シリアル化できます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# ModelStateWriter は palantir_models.models からインポートできます。 from io import IOBase from typing import ContextManager class ModelStateWriter: def open(self, asset_file_path: str, mode: str = "wb") -> ContextManager[IOBase]: """ モデルのアーティファクトとパラメータをシリアライズするためのファイルライクなオブジェクトを開きます。 """ def put_file(self, local_file_path, asset_file_path=None): """ このモデルのリポジトリにローカルファイルを置きます。 :param asset_file_path: 提供された場合、ファイルはリポジトリのこのパスに配置されます。 それ以外の場合、ファイルはリポジトリのルートディレクトリに配置されます。 """ def put_directory(self, local_root_path, asset_root_path = "/"): """ ローカルディレクトリとその内容をこのモデルのリポジトリに置きます。 :param asset_root_path: このディレクトリを置くためのリポジトリのルートパスに対する相対パス。 """
save()
メソッドは、モデルアダプターが model.publish()
を介して変換で公開されるたびに、または新しく作成されたモデルバージョンが参照する作成物リポジトリに zip ファイルとしてパッケージ化される ModelStateWriter の内容が永続化されるたびに呼び出されます。
次の例では、モデルを model.pkl
ファイルとして保存します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from palantir_models.models import ModelAdapter, ModelStateWriter class ExampleModelAdapter(ModelAdapter): def __init__(self, model): self.model = model # モデルを初期化 ... def save(self, state_writer: ModelStateWriter): with state_writer.open("model.pkl", "wb") as model_outfile: # モデルの状態を保存するファイルを開く pickle.dump(self.model, model_outfile) # モデルの状態をファイルに書き込む ...
Load
ModelStateReaderは、ModelAdapter.load
メソッドに提供され、ModelAdapter
が保存されたモデル作成物を読み込み/デシリアライズしてモデルを初期化することができます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# ModelStateReaderはpalantir_models.modelsからインポートすることができます from tempfile import TemporaryDirectory class ModelStateReader: def open(self, asset_file_path: str, mode: str = "rb") -> ContextManager[IOBase]: """ モデルのアーティファクトとパラメーターを逆シリアル化するためのファイルライクオブジェクトを開きます。 """ def extract_to_temp_dir(self, root_dir: str = None) -> AnyStr: """ このモデルに関連するモデルのアーティファクトを含むTempDirectoryを返します。 :param root_dir: 指定された場合、抽出するルートディレクトリ """ def extract(self, destination_path: str = None) -> None: """ リポジトリを提供されたローカルディレクトリパスに抽出します。 :param destination_path: 指定された場合、リポジトリが抽出されるディレクトリ """
load()
メソッドは、モデルアダプタがインスタンス化されるたび(トランスフォーム内のModelInput
を経由して、またはモデルにバックアップされたライブまたはバッチデプロイメントを起動するとき)に呼び出されます。このメソッドは、ModelStateWriter
が書き込むのと同じ作成物リポジトリにアクセスし、その内容にModelStateReader
を通じてアクセスを提供します。load()
は、任意のトランスフォームまたは推論ロジックが実行される前に呼び出されます。
次の例は、モデルファイルをロードし、それで初期化されたモデルアダプタのインスタンスを返します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
from palantir_models.models import ModelAdapter, ModelStateReader # クラス ExampleModelAdapter の定義 class ExampleModelAdapter(ModelAdapter): # 初期化メソッド def __init__(self, model): self.model = model # クラスメソッド load の定義 @classmethod def load(cls, state_reader: ModelStateReader): # モデルを読み込む with state_reader.open("model.pkl", "rb") as model_infile: model = pickle.load(model_infile) # インスタンスを返す return cls(model) ...
save()
メソッドと併用すると、このメソッドは save()
メソッドで永続化された同じ model.pkl
オブジェクトを取得します。ModelStateReader
オブジェクトもコンテナ化されたモデルに提供され、ユーザーがアップロードした zip ファイルを利用しています。
ContainerizedApplicationContext はオプションであり、モデルがコンテナイメージまたはイメージによってサポートされている場合にのみ、ModelAdapter.load
メソッドに提供されます。コンテキストオブジェクトには、共有ディレクトリのマウントパスと、コンテナ名からサービス URI へのマッピングが含まれます。各コンテナは複数のサービス URI を持つことができます。これは、複数の開いたポートがあっても問題ありません。
Copied!1 2 3 4 5 6 7 8 9 10 11 12
# このクラスタイプは、作成されたアダプター内でインポートする必要はありません class ContainerizedApplicationContext: def services(self) -> Dict[str, List[str]]: """ 個々のコンテナ名から、そのコンテナが提供するサービスURIのリストへのマッピング。 """ def shared_empty_dir_mount_path(self) -> str: """ すべてのコンテナとモデルアダプター内で利用可能な共有空ディレクトリのマウントパス。 このディレクトリは、コンテナおよびモデルエントリポイントによって読み取りおよび書き込みが可能です。 """
例として、次のようにサービス変数が設定されている場合があります:
Copied!1 2 3 4 5 6 7
{ # "container1"は "localhost:8080"に接続されています "container1": ["localhost:8080"], # "container2"は "localhost:8080"と"localhost:8081"に接続されています "container2": ["localhost:8080", "localhost:8081"], }
以下の例では、提供されたContainerizedApplicationContextから特定のボリュームパス、ホスト、およびポートを使用してモデルアダプタを初期化します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# palantir_models.modelsからModelAdapterとModelStateReaderをインポートします from palantir_models.models import ModelAdapter, ModelStateReader # models_api.models_api_executableからexecutable_apiをインポートします import models_api.models_api_executable as executable_api # ExampleModelAdapterクラスを定義します。これはModelAdapterクラスを継承しています。 class ExampleModelAdapter(ModelAdapter): # 初期化メソッドを定義します。引数としてshared_volume_pathとmodel_host_and_portを受け取ります。 def __init__(self, shared_volume_path, model_host_and_port): self.shared_volume_path = shared_volume_path self.model_host_and_port = model_host_and_port # クラスメソッドloadを定義します。引数としてstate_readerとcontainer_contextを受け取ります。 @classmethod def load(cls, state_reader, container_context: executable_api.ContainerizedApplicationContext): # container_contextからshared_empty_dir_mount_pathを取得し、shared_volume_pathとして設定します。 shared_volume_path = container_context.shared_empty_dir_mount_path # container_contextからservicesの"container1"の0番目を取得し、model_host_and_portとして設定します。 model_host_and_port = container_context.services["container1"][0] # clsを使って自身のクラスの新しいインスタンスを作成し、それを戻り値として返します。 return cls(shared_volume_path, model_host_and_port) ...
ExternalModelContext はオプションで、モデルが外部ホスト型モデルの場合に限り、ModelAdapter.load
メソッドに提供されます。このコンテキストオブジェクトには、外部ホスト型モデルを表すオブジェクトと、この外部ホスト型モデルに接続するために必要なユーザー定義の復号化された秘密のマップが含まれています。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# このクラスタイプは、作成されたアダプタ内でインポートする必要はありません class ExternalModelContext: def external_model(self) -> models_api_external_ExternalModel: """ 主にbase_urlと接続設定を含む、外部ホストのモデルを表すオブジェクト。 """ def resolved_credentials(self) -> Dict[str, str]: """ この外部ホストのモデルと接続するために必要な、ユーザー定義の復号化された秘密値のマッピング。 """ # このクラスタイプは、作成されたアダプタ内でインポートする必要はありません class models_api_external_ExternalModel: def base_url(self) -> str: """ この外部ホストモデルがホストされている場所を表すユーザー定義のurl。 """ def connection_configuration(self) -> Dict[str, str]: """ ユーザー定義の暗号化されていない設定フィールドの辞書。 これは、モデル名、推論パラメータ、予測閾値などの特定の設定詳細を格納するためのものです。 """
以下の例では、外部ホストのモデルにリクエストを実行するモデルアダプターを初期化します。外部ホストのモデルとの連携についての詳細は、ドキュメンテーションを参照してください。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
from palantir_models.models import ModelAdapter, ModelStateReader import models_api.models_api_executable as executable_api class ExampleModelAdapter(ModelAdapter): def __init__(self, url, credentials_map, configuration_map): # "Connection configuration" マップからモデル設定を抽出 model_name = configuration_map['model_name'] model_parameter = configuration_map['model_parameter'] # "Credentials configuration" マップからモデルの認証情報を抽出 secret_key = credentials_map['secret_key'] # モデルのロード時に http クライアントを開始 self.client = ExampleClient(url, model_name, model_parameter, secret_key) @classmethod def load( cls, state_reader: ModelStateReader, container_context: Optional[executable_api.ContainerizedApplicationContext] = None, external_model_context: Optional[executable_api.ExternalModelExecutionContext] = None, ) -> "ModelAdapter": return cls( url=external_model_context.external_model.base_url, credentials_map=external_model_context.resolved_credentials, configuration_map=external_model_context.external_model.connection_configuration, ) ...
モデルアダプタの api()
メソッドは、このモデルアダプタの推論ロジックを実行するために期待される入力と出力を指定します。入力と出力は別々に指定されます。
api()
の例Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
from palantir_models.models import ModelAdapter class ExampleModelAdapter(ModelAdapter): ... # apiメソッドをクラスメソッドとして定義します。 @classmethod def api(cls): # 入力は"input_dataframe"という名前のTabular形式のデータフレームで、 # カラムは"input_feature"という名前でfloat型のデータです。 inputs = [ModelInput.Tabular(name="input_dataframe", df_type=DFType.PANDAS, columns=[ModelApiColumn(name="input_feature", type=float)])] # 出力は"output_dataframe"という名前のTabular形式のデータフレームで、 # カラムは"output_feature"という名前でint型のデータです。 outputs = [ModelOutput.Tabular(name="output_dataframe", columns=[ModelApiColumn(name="output_feature", type=int)])] # 入力と出力を含むModelApiオブジェクトを返します。 return ModelApi(inputs, outputs) ...
ModelInput タイプは、ModelAdapter.api
メソッドで定義できる入力タイプを含んでいます。モデルアダプターは次の入力タイプをサポートします:
注:メディアリファレンスのサポートは現在ベータ版であり、Pythonトランスフォームでの推論のみをサポートしています。メディアリファレンスとモデルは、Modeling Objectives アプリケーションでの自動評価、バッチデプロイメント、またはライブデプロイメントをサポートしていません。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
# DFTypeとModelInputはpalantir_models.models.apiからインポート可能です。 class ModelInput: Tabular = TabularInput # テーブル形式の入力を示す FileSystem = FileSystemInput # ファイルシステムの入力を示す Parameter = ParameterInput # パラメータ入力を示す MediaReference = MediaReferenceInput # メディア参照入力を示す class TabularInput: def __init__(self, name: str, df_type: DFType = DFType.SPARK, columns: List[ModelApiColumn]): """ ModelAdapterがテーブル形式の入力を期待することを示すために使用されます。 この入力タイプは、適用可能な場合、`df_type`で指定されたタイプにテーブル入力を変換します。 Pandasのデータフレーム、Sparkのデータフレーム、TransformInputsがテーブル入力タイプとして受け入れられます。 """ class ParameterInput: def __init__(self, name: str, type: type, default = None): """ ModelAdapterが'type'型の定数値パラメータを期待することを示すために使用されます。 パラメータ入力の利用可能なタイプは次のとおりです: str, int, float, bool, list, set, dict, tuple。 .transform()のargsに直接渡されない場合、提供されたデフォルト値が使用されます。 """ class FileSystemInput: def __init__(self, name: str): """ ModelAdapterがファイルシステム入力を期待することを示すために使用されます。 """ class MediaReferenceInput: def __init__(self, name: str): """ ModelAdapterがメディア参照を入力として期待することを示すために使用されます。 """ class DFType(Enum): SPARK = "spark" # Sparkのデータフレームを示す PANDAS = "pandas" # Pandasのデータフレームを示す class ModelApiColumn(NamedTuple): """ テーブル入力の列の名前とタイプを指定するために使用されます。 """ name: str # 列の名前 type: type # 列のタイプ required: bool = True # この列が必須であることを示す(デフォルトはTrue)
TabularInput
は、model.transform()
へ提供される入力がタブラー型であることを指定するために使用されます。このモデルアダプタの推論ロジックの文脈では、この入力の型はapi()
メソッドで指定されたdf_type
パラメーターとなります。必要に応じて適切な型変換が行われます。以下のタブラー型が許可されています:
df_type=DFType.SPARK
と指定するタブラー入力でのみサポートされています。DFType.PANDAS
を指定するタブラー入力のSparkデータフレームの変換はサポートされていません。TabularInputsはまた、タブラー入力の期待される行スキーマを記述するModelApiColumn
のリストを指定します。type
パラメーターは以下のいずれかになります:
str
int
float
bool
list
dict
set
tuple
typing.Any
MediaReference
行タイプは強制されず、このモデルアダプタの使用者に対して期待される行タイプを伝えるための手段として働きます。これに対する唯一の例外は、MediaReference
タイプで、各行の要素がメディア参照文字列であることを期待し、各要素をMediaReference
オブジェクトに変換してから、このモデルアダプタの推論ロジックに渡します。
ParameterInput
は、model.transform()
へ提供される入力がパラメータータイプであることを指定するために使用されます。パラメーターは、以下のタイプの一つである定数値入力です:
str
int
float
bool
list
dict
set
tuple
パラメータータイプは強制され、指定されたタイプに対応しないmodel.transform()
へのパラメーター入力はエラーを発生させます。
パラメーター入力はまた、モデルアダプタのapi()
メソッドで定義されたパラメーター入力に対応するmodel.transform()
への入力が提供されていない場合のdefault
値を指定することもできます。
FileSystemInput
は、model.transform()
へ提供される入力がファイルシステムタイプであることを指定するために使用されます。TransformInputsのみがFileSystemInput
の入力タイプとしてサポートされています。
MediaReferenceInput
は、model.transform()
へ提供される入力がメディア参照であることを指定するために使用されます。メディア参照はstr
タイプであることが期待され、完全なメディア参照オブジェクト定義を含む必要があります。モデルアダプタはこのメディア参照文字列を、参照されるメディア項目と対話するメソッドを含むMediaReference
オブジェクトに変換します。
ModelOutputは、ModelAdapter.api
メソッドで定義された出力タイプを含みます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# ModelOutput は palantir_models.models.api からインポートできます class ModelOutput: FileSystem = FileSystemOutput Paramter = ParameterOutput class TabularOutput: def __init__(self, name: str): """ ModelAdapterが表形式の出力を生成することを指定するために使用されます。 PandasまたはSparkデータフレームのみが、表形式の出力タイプとしてサポートされています。 """ class ParameterOutput: def __init__(self, name: str, type: type, default = None): """ ModelAdapterが'type'タイプの定数値パラメータを生成することを指定するために使用されます。 パラメータ出力の利用可能なタイプは、str, int, float, bool, list, set, dict, tuple です。 `run_inference()` を介して書き込まれていない場合、指定されたデフォルト値が使用されます。 """
両方の利用可能なモデル出力は、それぞれの入力 counterpart に似たように動作します。主な違いの 1 つは、TabularOutput
には df_type
パラメーターが ない ということです。Pandas と Spark のデータフレームの両方を受け入れることができます。
predict()
メソッドタブラーまたはパラメータータイプの単一出力を持つモデルでは、run_inference()
メソッドの代わりに predict()
メソッドを使用して、モデルアダプタの推論ロジックを定義することができます。このメソッドの引数は、モデルアダプタの api()
メソッドで定義された入力オブジェクトの名前になります。引数が定義された順序と同じ順序を保持する必要はありませんが、名前は一致していなければなりません。
predict()
メソッドの例次の例は、マルチタブラー入力、シングルタブラー出力のモデルアダプタの predict()
メソッドを定義しています。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import palantir_models as pm class ExampleModelAdapter(pm.ModelAdapter): ... @classmethod def api(cls): # 入力データの形式を定義 inputs = {"input_1": pm.Pandas(), "input_2": pm.Pandas()} # 出力データの形式を定義 outputs = {"output_dataframe": pm.Pandas()} return inputs, outputs def predict(self, input_1, input_2): # input_1 と input_2 を使って推論ロジックを実行し、結果のデータフレームを生成 resulting_dataframe = ... return resulting_dataframe
上記の例では、二つの入力(input_1
とinput_2
)は、predict()
メソッドの署名で名前で参照されています。関数が返すデータフレーム、resulting_dataframe
は、output_dataframe
という名前の単一の出力に書き込まれます。
run_inference()
メソッド複数の出力を持つモデルや、ファイルシステムに書き込むモデルの場合、カスタム推論ロジックは run_inference()
メソッドを介して定義する必要があります。このメソッドは二つの引数、inputs
とoutputs
を取ります。これらの引数は、api()
メソッドで定義された入力と出力の name
パラメーターに対応する名前を持つ NamedTuples
です。
名前で入力を参照すると、api()
の同じ名前の入力に対応する model.transform()
に渡されたオブジェクトにアクセスします。
以下の ModelAdapter
定義を考えてみましょう:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
# palantir_models.modelsからModelAdapterをインポートします from palantir_models.models import ModelAdapter # ExampleModelAdapterという名前のクラスを作成し、ModelAdapterを継承します class ExampleModelAdapter(ModelAdapter): ... # apiというクラスメソッドを定義します @classmethod def api(cls): # 入力として、名前が"input_dataframe"で、タイプがPANDASのデータフレームを定義します # このデータフレームは、"input_feature"という名前のfloat型の列を持っています inputs = [ModelInput.Tabular(name="input_dataframe", df_type=DFType.PANDAS, columns=[ModelApiColumn(name="input_feature", type=float)])] # 出力として、"output_dataframe_one"と"output_dataframe_two"という名前のデータフレームを定義します # これらのデータフレームは、"output_feature"という名前のint型の列を持っています outputs = [ModelOutput.Tabular(name="output_dataframe_one", columns=[ModelApiColumn(name="output_feature", type=int)]), ModelOutput.Tabular(name="output_dataframe_two", columns=[ModelApiColumn(name="output_feature", type=int)])] # ModelApiオブジェクトを作成し、入力と出力を返します return ModelApi(inputs, outputs) # run_inferenceというメソッドを定義します。このメソッドは入力と出力を受け取ります def run_inference(self, inputs, outputs): # 入力からデータフレームを取得します my_input_df = inputs.input_dataframe ...
そして、次の .transform()
の呼び出し:
Copied!1 2 3 4 5 6 7 8 9 10
# この関数は、入力データを受け取り、モデルを使用してデータを変換し、2つの出力データに分割しています。 @transform( my_input_data=Input(...), # 入力データ my_output_data_one=Output(...), # 出力データ1 my_output_data_two=Output(...), # 出力データ2 my_model=ModelInput(...) # 使用するモデル ) def compute(my_input_data, my_output_data_one, my_output_data_two, my_model): my_model_outputs = my_model.transform(my_input_data) # モデルを使用して入力データを変換
モデルアダプターの run_inference()
メソッド中の my_input_df
オブジェクトは、Pandas タイプのタブラー入力である "input_dataframe"
という名前の入力への参照であり、変換から渡される my_input_data
TransformInput の pandas 表現に等しくなります。
出力を名前で参照すると、同じ名前の api()
出力に対応する書き込み可能なオブジェクトが提供されます。これらのオブジェクトそれぞれには、各出力にどのデータが書き込まれるかを指定するための .write()
メソッドがあります。
次の ModelAdapter
定義を考えてみてください:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
from palantir_models.models import ModelAdapter class ExampleModelAdapter(ModelAdapter): ... @classmethod # API定義 def api(cls): # 入力: input_dataframe (Pandasデータフレーム) inputs = [ModelInput.Tabular(name="input_dataframe", df_type=DFType.PANDAS, columns=[ModelApiColumn(name="input_feature", type=float)])] # 出力: output_dataframe_one および output_dataframe_two (どちらも整数の列を持つ) outputs = [ModelOutput.Tabular(name="output_dataframe_one", columns=[ModelApiColumn(name="output_feature", type=int)]), ModelOutput.Tabular(name="output_dataframe_two", columns=[ModelApiColumn(name="output_feature", type=int)])] return ModelApi(inputs, outputs) # 推論実行 def run_inference(self, inputs, outputs): # 入力データフレームを取得 my_input_df = inputs.input_dataframe # 入力データフレームを処理して新しいデータフレームを作成 my_output_dataframe_one = do_something_to_input_and_return_a_new_dataframe(my_input_df) # 入力データフレームを別の方法で処理して新しいデータフレームを作成 my_output_dataframe_two = do_something_else_to_input_and_return_a_new_dataframe(my_input_df) # 出力データフレームに結果を書き込む outputs.output_dataframe_one.write(my_output_dataframe_one) outputs.output_dataframe_two.write(my_output_dataframe_two)
そして、次の.transform()
への呼び出し:
Copied!1 2 3 4 5 6 7 8 9 10 11 12
@transform( my_input_data=Input(...), # 入力データ my_output_data_one=Output(...), # 出力データ1 my_output_data_two=Output(...), # 出力データ2 my_model=ModelInput(...) # モデル ) def compute(my_input_data, my_output_data_one, my_output_data_two, my_model): my_model_outputs = my_model.transform(my_input_data) # モデルによる変換 my_output_dataframe_one = my_model_outputs.output_dataframe_one # データフレーム1 my_output_dataframe_two = my_model_outputs.output_dataframe_two # データフレーム2 my_output_data_one.write_pandas(my_output_dataframe_one) # 出力データ1にデータフレーム1を書き込む my_output_data_two.write_pandas(my_output_dataframe_two) # 出力データ2にデータフレーム2を書き込む
トランスフォーム内の my_output_dataframe_one
および my_output_dataframe_two
オブジェクトは、モデルアダプターの run_inference()
メソッドで output_dataframe_one
と output_dataframe_two
出力に書き込まれたオブジェクトと同じになります(この場合、 my_output_dataframe_one
と my_output_dataframe_two
)。
Foundry のメディア参照に関する情報はここで見つけることができます。
モデルアダプターの api()
で MediaReference
タイプのパラメーター入力または表形式の入力行が指定された場合、 model.transform()
を通じて提供されるメディア参照文字列は MediaReference
オブジェクトに変換されます。このオブジェクトタイプは、メディア参照とやりとりするためのメソッドを提供します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
class MediaReference: @property def media_reference(self): """ 生のメディア参照文字列。 """ @property def media_item_rid(self): """ メディア参照から抽出されたメディアアイテムのrid。 """ def get_media_item(self): """ メディアアイテムをファイルのようなオブジェクトとして返します。 """ def get_media_item_via_access_pattern(self, access_pattern_name, access_pattern_path): """ メディアアイテムのアクセスパターンをファイルのようなオブジェクトとして返します。 メディアセットの永続性ポリシーにより、これは一度計算されたアクセスパターンをキャッシュするかもしれません。 """ def transform_media_item(self, output_path, transformation): """ 変換をメディアアイテムに適用し、それをファイルのようなオブジェクトとして返します。 出力パスは変換に提供されます。 変換計算は、このSparkモジュールではなく、Mioによって行われます。 """ def get_media_item_metadata(self): """ メディアアイテムのメタデータ(幅、高さなど)を返します。 """
palantir_models
のバージョン 0.897.0
以降、dependencies()
関数は無視されます。モデルの依存関係は meta.yaml
またはモデルアダプターのコードリポジトリのライブラリタブで定義されたCondaの依存関係から抽出されます。
PythonEnvironment は、ModelAdapter.dependencies
メソッドによって返される ModelAdapter の必要な実行環境を指定します。これは常に、現在公開されているバージョンのモデルアダプターを公開するリポジトリへの参照でなければなりません。テンプレートリポジトリによって生成された generated_version_tag
を使用することを強く推奨します。
condaPackageName
と repositoryRid
の両方を gradle.properties
から取得できます。
コードリポジトリにあるモデルトレーニングテンプレートでは、generated_version_tag
を使用して、このモデルアダプターの現在のバージョンに自動的に依存関係を追加することができます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from palantir_models.models import PythonEnvironment, CondaDependency from palantir_models.models._types import CondaVersionExact @classmethod def dependencies(cls): # モデルトレーニングテンプレートのバージョンは main._version で公開されます from main._version import __version__ as generated_version_tag # PythonEnvironment および CondaDependency を使用して依存関係を返します return PythonEnvironment( conda_dependencies=[ CondaDependency( "<CONDA_PACKAGE_NAME> ", CondaVersionExact(version=f"{generated_version_tag}"), "REPOSITORY_RID" ) ] )
このコードは、特定のCondaパッケージの依存関係を管理するためのものです。具体的には、モデルトレーニングテンプレートのバージョンを使用して、Condaパッケージの正確なバージョンを指定しています。このバージョンは main._version
モジュールから取得します。
コードリポジトリにあるモデルアダプターライブラリテンプレートでは、generated_version_tag
を使用して、このモデルアダプターの現在のバージョンに自動的に依存性を追加することができます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from palantir_models.models import PythonEnvironment, CondaDependency from palantir_models.models._types import CondaVersionExact @classmethod def dependencies(cls): # モデルアダプタテンプレートにあるmodel_adapter._versionからバージョンが公開されています from model_adapter._version import __version__ as generated_version_tag return PythonEnvironment( conda_dependencies=[ CondaDependency( "<CONDA_PACKAGE_NAME> ", # 生成されたバージョンタグを使用してCondaパッケージのバージョンを指定します CondaVersionExact(version=f"{generated_version_tag}"), "<REPOSITORY_RID>" ) ] )