Closed sakamomo554101 closed 2 years ago
VertexAI Prediction APIを用いて、モニタリングができるため。
タイムアウト処理必要だなぁ・・。 ダッシュボード側がレスポンスないと、ずっとグルグルしてしまう
ModelDeploymentMonitoringJobを使って、モニターを構築すれば良い?
pipeline上でモニタリングを構築するオペレーターを追加できんかなー
https://github.com/GoogleCloudPlatform/mlops-with-vertex-ai お、これ参考になりそう。
眺めてみる
ModelMonitorのコンフィグは上記っぽい。 上記にskewのパラメーターとかを入れていくように見える。
上記でモニターを作成可能。 上記に入れるパラメーター(先程のコンフィグも含まれる。他にはアラート設定やモニタリング期間など)を解釈すれば、モニタリングが作れそう。
エンドポイントに紐づいたモデル情報を取る際に、EndpointServiceClientが必要。 モニタリングサービスを開始する際に、JobServiceClientが必要。
https://cloud.google.com/python/docs/reference/aiplatform/latest/google.cloud.aiplatform_v1.services.endpoint_service.EndpointServiceClient https://cloud.google.com/python/docs/reference/aiplatform/latest/google.cloud.aiplatform_v1.services.job_service.JobServiceClient
なるほど、すでに同一エンドポイントにモニタリング設定している状態で、再度モニタリングを設定しようとすると、エラーになるっぽい。
モニタリングがあるかのチェックか上書き対応ができるかを調査したほうが良さそう。
サンプルコードが参考になる。
def list_monitoring_jobs():
client_options = dict(api_endpoint=API_ENDPOINT)
parent = f"projects/{PROJECT_ID}/locations/us-central1"
client = JobServiceClient(client_options=client_options)
response = client.list_model_deployment_monitoring_jobs(parent=parent)
print(response)
def delete_monitoring_job(job):
client_options = dict(api_endpoint=API_ENDPOINT)
client = JobServiceClient(client_options=client_options)
response = client.delete_model_deployment_monitoring_job(name=job)
print(response)
どうやって、モニタリングの存在判定をするか
list_model_deployment_monitoring_jobsを実行すると、 ModelDeploymentMonitoringJobのリストが返ってくるっぽい
多分、同一エンドポイント名が存在するかを見れば良いかなー
うーん、、下記のようにFieldMaskを指定しても、エラーになってしまう。
response = client.update_model_deployment_monitoring_job(
model_deployment_monitoring_job=job, update_mask=FieldMask(paths=["*"])
)
エラーが謎なので、deleteして、createを試してみる
なるほど、ModelDeploymentMonitoringJob.nameはすでにデプロイ済みのjobから取得する必要がありそう。 ※デプロイ前だと、job.nameが空文字だった。
あ、そういえば、ドリフト(スキューかな)検知で利用するデータソースはcsv形式でもいいのかしら
BigquerySourceではなく、GcsSource使えばいいのかも。
artifactのuriを取得すれば、そこに文字列が格納されてるのかも。 (endpointをカスタムコンポーネントから返す場合の取得方法)
いや、無理か。outputPathに指定しちゃうと、Vertex側でパスが勝手に設定されちゃうんだよな。
あー、やっぱ、urisにgcsのfile uriのリスト渡せばOKだな。
gcsのuriのリスト(training, validationあたり)を取得する必要があるな。
あれ、モデル側で、予測対象って、どう決めてたっけ? 特に決めてないのか
学習時に決めてるはず
csvにカラム名は書いてなくて、列数でターゲットを指定してる。 titleがターゲットなので、1列目(0指定)となる。
とりあえず、prediction_target_fieldには0入れてみるけど、ダメだったら、csvに列名入れるか。
pipelineのビルドでこける。 なんだっけ、これ。ListでpipelineParamsを受け取っているのが問題?
Traceback (most recent call last):
File "model_pipeline/pipeline.py", line 844, in <module>
pipeline_instance.compile_pipeline(
File "model_pipeline/pipeline.py", line 280, in compile_pipeline
v2_compiler.Compiler().compile(
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/v2/compiler/compiler.py", line 1274, in compile
pipeline_job = self._create_pipeline_v2(
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/v2/compiler/compiler.py", line 1196, in _create_pipeline_v2
pipeline_func(*args_list)
File "model_pipeline/pipeline.py", line 382, in kfp_youyakuai_pipeline
monitoring_op = self.create_monitoring_op(
File "model_pipeline/pipeline.py", line 717, in create_monitoring_op
return monitoring_func(
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/components/_dynamic.py", line 53, in Monitoring func
return dict_func(locals()) # noqa: F821 TODO
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/components/_components.py", line 386, in create_task_object_from_component_and_pythonic_arguments
return _create_task_object_from_component_and_arguments(
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/components/_components.py", line 323, in _create_task_object_from_component_and_arguments
task = _container_task_constructor(
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/dsl/_component_bridge.py", line 319, in _create_container_op_from_component_and_arguments
_attach_v2_specs(task, component_spec, original_arguments)
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/site-packages/kfp/dsl/_component_bridge.py", line 593, in _attach_v2_specs
json.dumps(argument_value))
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/shotasakamoto/.pyenv/versions/3.8.3/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type PipelineParam is not JSON serializable
dataset_gcs_source_uris=dataset_gcs_source_uris
の所をコメントアウトすると、コンパイルできるから、List指定が問題そう。
ふーむ、、コンバーターを作ると良い(= componentアノテーターなりを使って)、というイメージか。
んー、結局、PipelineParamがlistに入らんから、同じ問題がおきるな。
多分、エンドポイント にモデルがアタッチされてないから、と思ったが、下記のエラーはなんだろ?
Field: model_deployment_monitoring_job; Message: model_deployment_monitoring_objective_configs is empty in ModelDeploymentMonitoringJob
あー、model_idが取れなかったからか。 やはり、エンドポイント にモデルが紐づいてないのが原因。
んー、モデルモニタリングのデプロイタスクは成功するが、実際にモニタリングは開始されていない。 通知先のメールアドレスにデプロイが失敗した旨のメールが来てた。
trainingDatasetに対して、何も設定できていなかったのが問題。 GcsSourceを設定するようにしたら、モニタリングが動くようになった。 ただ、データフォーマットが見えてないのは大丈夫なのか?
2022-02-12T09:37:52.320125961Zmodel_deployment_monitoring_objective_configs {
情報
2022-02-12T09:37:52.320131405Z deployed_model_id: "5768856035963961344"
情報
2022-02-12T09:37:52.320136939Z objective_config {
情報
2022-02-12T09:37:52.320142387Z training_dataset {
情報
2022-02-12T09:37:52.320147521Z data_format: "data-format-unspecified"
情報
2022-02-12T09:37:52.320153215Z gcs_source {
情報
2022-02-12T09:37:52.320158741Z uris: "gs://youyaku_ai_pipeline/pipeline_output/749925056555/youyaku-ai-pipeline-20220212172750/data-generator_1178458761673572352/train_data"
情報
2022-02-12T09:37:52.320164814Z }
情報
2022-02-12T09:37:52.320170270Z target_field: "0"
情報
2022-02-12T09:37:52.320175932Z }
data_format
Data format of the dataset, only applicable if the input is from Google Cloud Storage. The possible formats are: "tf-record" The source file is a TFRecord file. "csv" The source file is a CSV file.
なるほど、csv指定するか(csvなので)
下記のようなエラーが出ているから、ちゃんとラベル(入力のパラメーターと合わせる)を設定する必要があるな。
Error message:
Unexpected Feature Name input_text
あ、モニタリングが途中で無効化されてる。 やはりちゃんとモニタリング出来ていない、ということか。
もうbqに流し込んじゃおうかな。 もしくは、csvにカラム名(title = target, body = input_textとする。genreは削除する)を設定するか。
https://qiita.com/komiya_____/items/8fd900006bbb2ebeb8b8
お、to_gpqなんてあるのか。
概要
VertexAIのモデルモニタリングを試しに導入する。 手順などをドキュメントにまとめる + スクリプトを作成する。