注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
モデルアダプターは、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 65 66import 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 メソッドでモデルを保存・シリアライズした場所と同じ場所から学習済みモデルの状態を読み込み、モデルを初期化するロジックを記述する必要があります。 コンテナモデル: コンテナがこの ModelAdapter のサイドカーとして起動された後に Foundry が呼び出すメソッドです。この ModelAdapter の作成者は、container_context の内容を使って、アダプターで必要になるクラス変数を初期化する必要があります。たとえば、ユーザーは多くの場合、#run_inference 内でコンテナに POST リクエストを送信するために、関連するサービス URI を抽出します。 外部でホストされるモデル: モデルアダプターが初期化されるときに Foundry が呼び出すメソッドです。この ModelAdapter の作成者は、外部でホストされるモデルへの接続を初期化して永続化し、ほかに必要なモデル設定も初期化するロジックを記述する必要があります。 :param state_reader: A ModelStateReader object that can be used to read model files. :param container_context: This is only provided for container backed models, and defaults to None. The container context includes a mapping from container name to service URIs and the shared directory mount path. :param external_model_context: This is only provided for externally hosted models, and defaults to None. The external_model_context includes references to the configuration a user defines when creating an externally hosted model that uses this Model Adapter. :return: An instance of a ModelAdapter. """ def save(self, state_writer: pm.ModelStateWriter) -> None: """ Foundry がモデルアダプターをシリアライズするために呼び出すメソッドです。このメソッドは、この ModelAdapter を使って Foundry 内で新たに学習または再学習したモデルをラップする場合にのみ必要です。 この ModelAdapter の作成者は、学習済みモデルの状態と関連するメタデータを ModelStateWriter に保存するロジックを記述する必要があります。 :param state_writer: The ModelStateWriter object to which the model is serialized and saved. """ @classmethod def api(cls) -> pm.ModelApi: """ このモデルが想定する入力と出力のデータ構造を定義します。 :return: The ModelApi object for the model """ def run_inference(self, inputs, outputs) -> None: """ このメソッドは、ModelAdapter.api メソッドで定義された関連する入力と出力を渡して呼び出されます。 関連付けられたモデルで推論を実行します。 :param inputs: A namedtuple of the inputs defined in the ModelAdapter.api method. :param outputs: A namedtuple of the outputs defined in the ModelAdapter.api method. Outputs should be written to in the run_inference method. """ def predict(self, *args, **kwargs) -> Union[Tabular, Parameter]: """ このメソッドは、複数(>=1)の入力から単一の出力(表形式またはパラメーター)を生成するモデルで推論を実行するために使います。 入力は、api() メソッドで定義した名前で、このメソッドのシグネチャに記述する必要があります。生成された出力は、このメソッドから返されます。 predict() を使う場合、ユーザーは run_inference() メソッドを定義しないことに注意してください。 """
save() と load()palantir_models.serializers ライブラリは、一般的なモデリングフレームワークでモデルのシリアライズ(保存)とデシリアライズ(読み込み)に使用できる多くのデフォルトのシリアライザーを提供しています。
場合によっては、モデルのシリアライズやデシリアライズにカスタムロジックを実装したいこともあります。たとえば、使用しているモデリングフレームワークで利用可能なデフォルトのシリアライザーがない場合や、どのモデルをどの時点でメモリーに読み込むかを手動で制御する必要がある場合に、カスタムロジックが必要になることがあります。
このような複雑なケースについては、以下の save と load の実装を参照してください。
SaveModelAdapter がモデルアーティファクトを Foundry ストレージに保存・シリアライズできるように、ModelAdapter.save メソッドには ModelStateWriter が渡されます。
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: If provided, the file will be placed at this path in the repository. Otherwise the file will be placed in the root directory of the repository. """ def put_directory(self, local_root_path, asset_root_path = "/"): """ ローカルディレクトリとその内容をこのモデルのリポジトリに配置します。 :param asset_root_path: The path relative to the root path of the repository to place this directory. """
save() メソッドは、トランスフォーム内で model.publish() を使用してモデルアダプターが公開されるたびに呼び出されます。その際、ModelStateWriter の内容は zip ファイルにパッケージ化され、新しく作成されたモデルバージョンが参照するアーティファクトリポジトリに永続化されます。
次の例では、モデルを model.pkl ファイルとして保存します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13from 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) ...
LoadModelAdapter が保存済みのモデルアーティファクトを読み取り・デシリアライズし、モデルを初期化できるように、ModelAdapter.load メソッドには ModelStateReader が渡されます。
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: If specified, the root directory to extract """ def extract(self, destination_path: str = None) -> None: """ 指定されたローカルディレクトリのパスにリポジトリを展開します。 :param destination_path: If specified, the directory where the repository will be extracted """
load() メソッドは、モデルアダプターがインスタンス化されるたびに呼び出されます(トランスフォーム内の ModelInput を介して、またはモデルに基づいているライブデプロイメントやバッチデプロイメントの起動時)。このメソッドは、ModelStateWriter が書き込むのと同じアーティファクトリポジトリにアクセスし、ModelStateReader を介してその内容へのアクセスを提供します。load() は、トランスフォームや推論ロジックが実行される前に呼び出されます。
次の例では、モデルファイルを読み込み、そのファイルで初期化されたモデルアダプターのインスタンスを返します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13from palantir_models.models import ModelAdapter, ModelStateReader class ExampleModelAdapter(ModelAdapter): def __init__(self, model): self.model = model @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: """ すべてのコンテナ内およびモデルアダプターから利用可能な、共有の空ディレクトリのマウントパスです。 このディレクトリは、コンテナおよびモデルのエントリーポイントから読み取りと書き込みができます。 """
値が設定された services 変数の例を以下に示します。
Copied!1 2 3 4{ "container1": ["localhost:8080"], "container2": ["localhost:8080", "localhost:8081"], }
次の例では、渡された ContainerizedApplicationContext の特定のボリュームパス、ホスト、ポートを使用してモデルアダプターを初期化します。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15from palantir_models.models import ModelAdapter, ModelStateReader import models_api.models_api_executable as executable_api class ExampleModelAdapter(ModelAdapter): 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 @classmethod def load(cls, state_reader, container_context: executable_api.ContainerizedApplicationContext): shared_volume_path = container_context.shared_empty_dir_mount_path model_host_and_port = container_context.services["container1"][0] 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 と connection_configuration を含みます。 """ 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 29from 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): # 「接続設定」マップからモデル設定を抽出します model_name = configuration_map['model_name'] model_parameter = configuration_map['model_parameter'] # 「資格情報設定」マップからモデルの資格情報を抽出します 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 16import palantir_models as pm class ExampleModelAdapter(pm.ModelAdapter): ... @classmethod def api(cls): inputs = { "df_in": pm.Pandas([('input_feature', float)]) } outputs = { "df_out": pm.Pandas([('output_feature', int)]) } return inputs, outputs ...
ModelInput 型には、ModelAdapter.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 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# 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, dict. .transform() の args に直接渡されない場合、指定されたデフォルト値が使われます。 """ class FileSystemInput: def __init__(self, name: str): """ ModelAdapter がファイルシステムの入力を想定していることを指定するために使います。 """ class MediaReferenceInput: def __init__(self, name: str): """ ModelAdapter が入力として Media Reference を想定していることを指定するために使います。 """ class ObjectInput: def __init__(self, object_type: OntologyObject): """ ModelAdapter が入力として Python オントロジー SDK の Object を想定していることを指定するために使います。 """ class ObjectSetInput: def __init__(self, object_type: OntologyObject): """ ModelAdapter が入力として Python オントロジー SDK の ObjectSet を想定していることを指定するために使います。 """ class DFType(Enum): SPARK = "spark" PANDAS = "pandas" class ModelApiColumn(NamedTuple): """ 表形式の入力の列名とデータ型を指定するために使います。 """ name: str type: type required: bool = True
TabularInput は、model.transform() に渡される入力が表形式のデータ型であることを指定するために使用します。このモデルアダプターの推論ロジックでは、この入力のデータ型は api() メソッドで指定された df_type パラメーターの値になります。必要に応じて、適切な型変換が実行されます。次の表形式のデータ型を使用できます。
df_type=DFType.SPARK を指定した表形式の入力でのみサポートされます。DFType.PANDAS を指定した表形式の入力では、Spark DataFrame の型変換に対応していません。TabularInput では、表形式の入力で期待される列スキーマを記述する ModelApiColumn のリストも指定します。type パラメーターには、次のいずれかを指定できます。
strintfloatboollistdictdatetime.datedatetime.timedatetime.datetimetyping.AnyMediaReferencetyping ライブラリの型エイリアス List と Dict も使用できます。たとえば、次のように指定します。
List[str]、Dict[str, float]。モデルを関数として公開する際にこれらのデータ型を使用する場合の固有の要件を確認してください。
ParameterInput は、model.transform() に渡される入力がパラメーター型であることを指定するために使用します。パラメーターは定数値の入力であり、そのデータ型は type パラメーターで指定します。パラメーター入力には、次のデータ型を使用できます。
strintfloatboollist (*)dict (*)typing.Any (*)palantir_models.NDArrayアスタリスク (*) が付いたデータ型には、モデルを関数として公開する際に固有の要件があります。
パラメーター入力では、モデルアダプターの api() メソッドで定義されたパラメーター入力に対応する入力が model.transform() に渡されない場合に使用する default 値も指定できます。
FileSystemInput は、model.transform() に渡される入力がファイルシステム型であることを指定するために使用します。FileSystemInput の入力タイプとしてサポートされるのは TransformInput のみです。
MediaReferenceInput は、model.transform() に渡される入力が Media Reference であることを指定するために使用します。Media Reference は str 型で、Media Reference オブジェクトの完全な定義を含む必要があります。モデルアダプターは、この Media Reference 文字列を MediaReference オブジェクトに変換します。このオブジェクトには、参照先のメディアアイテムを操作するためのメソッドが含まれます。
Object または ObjectSet 入力では、モデルアダプター API で入力を定義する際にオブジェクトタイプを指定します。このオブジェクトタイプは、選択したオントロジー用に生成されたオントロジー SDKからインポートされます。
モデル推論を実行する際、オブジェクトまたはオブジェクトセットは、次の方法でモデルに渡すことができます。
一般的な原則として、モデルアダプター API は推論時に厳密には強制適用されません。ただし、ライブ推論では一般により厳密に強制適用され、特に強い型付けが行われる Functionsでは厳密に強制適用されます。
パラメーターのデータ型は常に強制適用され、model.transform() へのパラメーター入力が指定されたデータ型と一致しない場合は、エラーが発生します。
モデルアダプターでは、推論時に API で指定されていない追加の列を表形式の入力に含めて渡すことができます。Foundry は、入力を predict メソッドに渡す前に追加の列を削除しません。これは、モデルアダプター API ガイドで説明されているように、モデルアダプターが評価で動作することを保証するうえで重要です。バッチ推論の場合、API で指定された列の一部がなくても、アダプターはエラーを発生させません。MediaReference 型は例外です。この型では、列の各要素が Media Reference 文字列である必要があります。バッチ推論中は各要素が 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 Parameter = 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, dict. `run_inference()` で書き込まれない場合、指定されたデフォルト値が使われます。 """
利用可能な2つのモデル出力は、どちらも対応する入力と同様に動作します。主要な違いの1つは、TabularOutput には df_type パラメーターが_ない_ことです。Pandas と Spark の両方の DataFrame を受け付けることができます。
predict() メソッド出力が表形式またはパラメーター型の1個のみであるモデルでは、run_inference() メソッドの代わりに predict() メソッドを使用して、モデルアダプターの推論ロジックを定義できます。このメソッドの引数は、モデルアダプターの api() メソッドで定義された入力オブジェクトの名前になります。引数の順序を定義時と同じにする必要はありませんが、名前は一致している必要があります。
predict() メソッドの例次の例では、表形式の入力を複数受け取り、表形式の出力を1個返すモデルアダプターの predict() メソッドを定義しています。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14import 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): resulting_dataframe = ... # input_1 と input_2 を使った推論ロジック return resulting_dataframe
上記の例では、2個の入力(input_1 と input_2)を predict() メソッドのシグネチャで名前によって参照しています。関数が返すデータフレーム resulting_dataframe は、output_dataframe という名前の単一の出力に書き込まれます。
run_inference() メソッド出力が複数あるモデルや、ファイルシステムに書き込むモデルでは、run_inference() メソッドを使ってカスタム推論ロジックを定義する必要があります。このメソッドは、inputs と outputs の2個の引数を受け取ります。これらの引数はいずれも NamedTuples で、その名前は api() メソッドで定義された入力と出力の name パラメーターに対応します。
入力を名前で参照すると、model.transform() に渡されたオブジェクトのうち、同じ名前の api() 入力に対応するオブジェクトにアクセスできます。
次の 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 24import palantir_models as pm class ExampleModelAdapter(pm.ModelAdapter): ... @classmethod def api(cls): inputs = { "df_in": pm.Pandas([("input_feature", float)]) } outputs = { "df_out_one": pm.Pandas([("feature_one", int)]), "df_out_two": pm.Pandas([("output_feature_1", int), ("output_feature_2", float)]) } return inputs, outputs def run_inference(self, inputs, outputs): my_input_df = inputs.df_in my_output_one = outputs.df_out_one my_output_two = outputs.df_out_two ...
また、次のように .transform() を呼び出すとします。
Copied!1 2 3 4 5 6 7 8@transform( my_input_data=Input(...), my_output_data_one=Output(...), my_output_data_two=Output(...), 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 型の表形式入力である "df_in" という名前の入力を参照するため、トランスフォームから渡された 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 24import palantir_models as pm class ExampleModelAdapter(pm.ModelAdapter): ... @classmethod def api(cls): inputs = { "input_dataframe": pm.Pandas([('input_feature', float)]) } outputs = { "output_dataframe_one": pm.Pandas([('output_feature', int)]), "output_dataframe_two": pm.Pandas([('output_feature', int)]), } return 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(...), my_output_data_two=Output(...), 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 my_output_dataframe_two = my_model_outputs.output_dataframe_two my_output_data_one.write_pandas(my_output_dataframe_one) my_output_data_two.write_pandas(my_output_dataframe_two)
トランスフォーム内の 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 の Media Reference に関する情報は、こちらを参照してください。
モデルアダプターの api() で、MediaReference 型のパラメーター入力または表形式入力の列が指定されている場合、model.transform() を介して渡された Media Reference の文字列は MediaReference オブジェクトに変換されます。このオブジェクトタイプには、Media Reference を操作するメソッドが用意されています。
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 46class MediaReference: @property def media_reference(self): """ 未加工の Media Reference 文字列です。 """ @property def media_item_rid(self): """ Media Reference から抽出されたメディアアイテムの 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): """ メディアアイテムに変換を適用し、ファイルライクオブジェクトとして返します。 output_path は transformation に渡されます。 変換の計算は、この Spark モジュールではなく Mio が行います。 """ def get_media_item_metadata(self): """ メディアアイテムのメタデータ(幅、高さなど)を返します。 """ def transform_and_wait(self, transformation, output_path="", poll_interval_seconds=3.0, poll_timeout_seconds=30.0): """ 変換を適用し、結果が準備できるまでメディアサービスをポーリングします。 poll_timeout_seconds 以内に変換が完了しない場合、TimeoutError を発生させます。 """ def transformation_calculation_hint(self, transformation, output_paths): """ 指定された出力パスに対する変換を事前にウォームアップし、後続の transform_and_wait 呼び出しがウォームアップ済みまたはキャッシュ済みの計算を利用できるようにします。 """
次の例では、MediaReference 列を含む表形式の入力を受け取り、参照先のメディアアイテムをそれぞれ読み込んで、その内容に対して推論を実行するモデルアダプターを定義しています。バッチ推論では、列の各要素はアダプターの推論ロジックに渡される前に MediaReference オブジェクトに変換されます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22import palantir_models as pm class ImageClassifierAdapter(pm.ModelAdapter): # 簡潔にするため、load() メソッドと save() メソッドは省略しています。 @classmethod def api(cls): inputs = { "df_in": pm.Pandas(columns=[("image", pm.MediaReference)]) } outputs = { "df_out": pm.Pandas(columns=[("prediction", str)]) } return inputs, outputs def predict(self, df_in): predictions = [] for media_reference in df_in["image"]: with media_reference.get_media_item() as media_item: predictions.append(self.model.classify(media_item.read())) df_in["prediction"] = predictions return df_in