簡體   English   中英

如何將 ExitHandler 與 Kubeflow 管道一起使用 SDK v2

[英]How to use ExitHandler with Kubeflow Pipelines SDK v2

我正在嘗試將我所有的 Kubeflow 管道從使用以前的 SDK v1 ( kfp ) 轉移到較新的管道 SDK v2 ( kfp.v2 )。 我正在使用1.8.12版。事實證明,這種重構對於幾乎所有代碼都是成功的,除了ExitHandler ,它仍然存在; from kfp.v2.dsl import ExitHandler 似乎以前使用kfp.compiler.Compiler().compile(pipeline, 'basic_pipeline.tar.gz')文件將管道 object 編譯成tar.gz文件的方法保留了某種類型的 Argo 占位符,而新的.json管道使用compiler.Compiler().compile(pipeline_func=pipeline, package_path="basic-pipeline.json")的工作方式不同。 下面,我將 go 詳細介紹 Pipelines SDK v1 中的工作原理以及我如何嘗試在 v2 中實現它。

以前,使用 Kubeflow Pipelines v1,我可以使用 ExitHandler,如這個 StackOverflow 問題中所示。 當其中一個管道組件失敗時,向 Slack 發送消息。 我會將管道定義為

import kfp.dsl as dsl

@dsl.pipeline(
    name='Basic-pipeline'
)
def pipeline(...):
    exit_task = dsl.ContainerOp(
        name='Exit handler that catches errors and post them in Slack',
        image='eu.gcr.io/.../send-error-msg-to-slack',
        arguments=[
                    'python3', 'main.py',
                    '--message', 'Basic-pipeline failed'
                    '--status', "{{workflow.status}}"
                  ]
    )
    with dsl.ExitHandler(exit_task):
        step_1 = dsl.ContainerOp(...)
        step_2 = dsl.ContainerOp(...) \
            .after(step_1)

if __name__ == '__main__':
    import kfp.compiler as compiler
    compiler.Compiler().compile(pipeline, 'basic_pipeline.tar.gz')

如果管道的任何步驟失敗, exit_task會將message到我們的 Slack。 exit_task圖像的代碼看起來像

import argparse

def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--message', type=str)
    parser.add_argument('--status', type=str)
    return parser.parse_known_args()

def main(FLAGS):
    def post_to_slack(msg):
        ...

    if FLAGS.status == "Failed":
        post_to_slack(FLAGS.message)
    else:
        pass

if __name__ == '__main__':
    FLAGS, unparsed = get_args()
    main(FLAGS)

這行得通,因為底層的 Argo 工作流可以以某種方式理解"{{workflow.status}}"的概念。

但是,我現在正嘗試使用 Vertex AI 來運行管道,利用 Kubeflow Pipelines SDK v2, kfp.v2 使用與之前相同的退出處理程序圖像'eu.gcr.io/.../send-error-msg-to-slack' ,我現在定義一個 yaml 組件文件 ( exit_handler.yaml ),

name: Exit handler
description: Prints to Slack if any step of the pipeline fails

inputs:
  - {name: message, type: String}
  - {name: status, type: String}

implementation:
  container:
    image: eu.gcr.io/.../send-error-msg-to-slack
    command: [
      python3,
      main.py,
      --message, {inputValue: message},
      --status, {inputValue: status}
    ]

管道代碼現在看起來像這樣,

from google.cloud import aiplatform
from google.cloud.aiplatform import pipeline_jobs
from kfp.v2 import compiler
from kfp.v2.dsl import pipeline, ExitHandler
from kfp.components import load_component_from_file

@pipeline(name="Basic-pipeline",
          pipeline_root='gs://.../basic-pipeline')
def pipeline():
    exit_handler_spec = load_component_from_file('./exit_handler.yaml')
    exit_handler = exit_handler_spec(
        message="Basic pipeline failed.",
        status="{{workflow.status}}"
    )
    with ExitHandler(exit_handler):
        step_0_spec = load_component_from_file('./comp_0.yaml')
        step0 = step_0_spec(...)

        step_1_spec = load_component_from_file('./comp_1.yaml')
        step1 = step_1_spec(...) \
            .after(step0)

if __name__ == '__main__':
    compiler.Compiler().compile(
        pipeline_func=pipeline,
        package_path="basic-pipeline.json"
    )
    from google.oauth2 import service_account
    credentials = service_account.Credentials.from_service_account_file("./my-key.json")
    aiplatform.init(project='bsg-personalization',
                    location='europe-west4',
                    credentials=credentials)

    job = pipeline_jobs.PipelineJob(
        display_name="basic-pipeline",
        template_path="basic-pipeline.json",
        parameter_values={...}
    )
    job.run()

這“有效”(沒有例外)編譯和運行,但 ExitHandler 代碼將status解釋為具有值 {{workflow.status}} 的字符串,這也由上面代碼生成的編譯管道 json 指示( basic-pipeline.json ),您可以在下面看到( "stringValue": "{{workflow.status}}" ):

...
         "exit-handler": {
            "componentRef": {
              "name": "comp-exit-handler"
            },
            "dependentTasks": [
              "exit-handler-1"
            ],
            "inputs": {
              "parameters": {
                "message": {
                  "runtimeValue": {
                    "constantValue": {
                      "stringValue": "Basic pipeline failed."
                    }
                  }
                },
                "status": {
                  "runtimeValue": {
                    "constantValue": {
                      "stringValue": "{{workflow.status}}"
                    }
                  }
                }
              }
            },
            "taskInfo": {
              "name": "exit-handler"
            },
            "triggerPolicy": {
              "strategy": "ALL_UPSTREAM_TASKS_COMPLETED"
            }
          }
...

知道如何使用 v1 將我的舊ExitHandler代碼重構為新的 SDK v2,以使退出處理程序了解我的管道狀態是否失敗嗎?

這可能尚未完全記錄,但在 V2 中我們引入了一個不同的變量PipelineTaskFinalStatus ,它可以自動填充以供您將其發送到您的 Slack 頻道。

這是官方文檔https://cloud.google.com/vertex-ai/docs/pipelines/email-notifications#sending_a_notification_from_a_pipeline中退出處理程序的示例

這里是對應的 email 通知組件https://github.com/kubeflow/pipelines/blob/master/components/google-cloud/google_cloud_pipeline_components/v1/vertex_notification_email/component.yaml

您可以使用以下參數編寫自己的組件,該參數將在退出處理程序運行時自動填充。

inputs:
...
  - name: pipeline_task_final_status
    type: PipelineTaskFinalStatus

(請注意,此功能目前在 Kubeflow Pipelines 開源發行版中尚不可用,將在 KFP V2 中提供。它僅在 Vertex Pipelines 發行版中可用)

KFP SDK v2中"{{workflow.status}}"的替換就是上面IronPan提到的特殊類型注解PipelineTaskFinalStatus

它的用法記錄在https://www.kubeflow.org/docs/components/pipelines/v2/author-a-pipeline/pipelines/#dslexithandler

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM