轻量级 Python 组件

从自包含的 Python 函数创建组件

开始编写组件最简单的方法是创建轻量级 Python 组件。我们在Hello World 管道示例中看到了一个带有 say_hello 的轻量级 Python 组件示例。这里是另一个将两个整数相加的轻量级 Python 组件

from kfp import dsl

@dsl.component
def add(a: int, b: int) -> int:
    return a + b

轻量级 Python 组件是通过使用 @dsl.component 装饰器装饰 Python 函数来构建的。@dsl.component 装饰器将您的函数转换为一个 KFP 组件,该组件可以由符合 KFP 标准的后端作为远程函数执行,无论是独立执行还是作为更大管道中的单个步骤执行。

Python 函数要求

要使用 @dsl.component 装饰器装饰函数,它必须满足两个要求

  1. 类型注解:函数的输入和输出必须具有有效的 KFP 类型注解

    KFP 中的输入和输出分为两类:参数Artifact。每类中都有特定类型的参数和 Artifact。每个输入和输出都将通过其类型注解指示特定的类型。

    在前面的 add 组件中,输入 ab 都是类型为 int 的参数。有一个输出,类型也是 int

    有效的参数注解包括 Python 内置的 intfloatstrbooltyping.Dicttyping.List。Artifact 注解在数据类型:Artifact中有详细讨论。

  2. 封闭性(Hermetic):Python 函数不能引用其函数体外部定义的任何符号。

    例如,如果您希望使用一个常量,则该常量必须在函数内部定义

    @dsl.component
    def double(a: int) -> int:
        """Succeeds at runtime."""
        VALID_CONSTANT = 2
        return VALID_CONSTANT * a
    

    相比之下,以下是无效的,将在运行时失败

    # non-example!
    INVALID_CONSTANT = 2
    
    @dsl.component
    def errored_double(a: int) -> int:
        """Fails at runtime."""
        return INVALID_CONSTANT * a
    

    导入语句也必须包含在函数体中

    @dsl.component
    def print_env():
        import os
        print(os.environ)
    

    对于许多实际的组件,封闭性(hermeticism)可能是一个相当严格的要求。容器化 Python 组件 是一种更灵活的编写方法,它取消了这一要求。

dsl.component 装饰器参数

在上面的示例中,我们使用了只有一个参数(即 Python 函数)的 @dsl.component 装饰器。该装饰器接受一些附加参数。

packages_to_install

大多数实际的轻量级 Python 组件都依赖于其他 Python 库。您可以将一个需求列表传递给 packages_to_install,组件将在执行组件函数之前在运行时安装这些包。

这类似于在 requirements.txt 文件中包含需求。

@dsl.component(packages_to_install=['numpy==1.21.6'])
def sin(val: float = 3.14) -> float:
    return np.sin(val).item()

注意:作为生产软件的最佳实践,当您的组件指定了 packages_to_install 时,建议使用 容器化 Python 组件,以避免在运行时安装依赖项。

pip_index_urls

pip_index_urls 提供了从非默认的 PyPI.org 包索引进行 pip 安装 packages_to_install 的能力。

当您设置 pip_index_urls 时,KFP 会将这些索引传递给 pip install 命令的 --index-url--extra-index-url 选项。它还会将每个索引设置为 --trusted-host

以下组件为例

@dsl.component(packages_to_install=['custom-ml-package==0.0.1', 'numpy==1.21.6'],
               pip_index_urls=['http://myprivaterepo.com/simple', 'https://pypi.ac.cn/simple'],
)
def comp():
    from custom_ml_package import model_trainer
    import numpy as np
    ...

这些参数大致转换为以下 pip install 命令

pip install custom-ml-package==0.0.1 numpy==1.21.6 kfp==2 --index-url http://myprivaterepo.com/simple --trusted-host http://myprivaterepo.com/simple --extra-index-url https://pypi.ac.cn/simple --trusted-host https://pypi.ac.cn/simple

请注意,当您设置 pip_index_urls 时,KFP 不会自动包含 'https://pypi.ac.cn/simple'。如果您希望从私有仓库和默认公共仓库安装包,您应该同时包含私有和默认 URL,如前面组件 comp 所示。

base_image

当您创建轻量级 Python 组件时,KFP SDK 会提取您的 Python 函数代码,以便在管道运行时在容器内部执行。默认情况下,使用的容器镜像是 python:3.7。您可以通过为 base_image 提供参数来覆盖此镜像。如果您的代码需要特定的 Python 版本或默认镜像中未包含的其他依赖项,这会很有用。

@dsl.component(base_image='python:3.8')
def print_py_version():
    import sys
    print(sys.version)

install_kfp_package

install_kfp_package 可以与 pip_index_urls 一起使用,以提供对组件运行时 kfp 包安装的精细控制。

默认情况下,Python 组件在运行时安装 kfp。这对于定义组件使用的符号(例如 artifact 注解)以及访问远程执行组件所需的附加 KFP 库代码是必需的。如果 install_kfp_packageFalse,则不会通过正常的自动机制安装 kfp。相反,您可以使用 packages_to_installpip_index_urls 来安装不同版本的 kfp,可能来自非默认的 pip 索引 URL。

请注意,将 install_kfp_package 设置为 False 很少是必需的,并且在大多数使用场景下不建议这样做。

反馈

此页面是否有帮助?


最后修改于 2024年6月20日:重组 Kubeflow Pipelines 文档 (#3737) (8e56df7)