Как использовать OutputPath для нескольких компонентов в kubeflow

Мы определяем несколько компонентов в конвейерах kubeflow, используя @dsl.containerop.

Требование состоит из двух этапов.

  1. Сначала нам нужно запустить задачу загрузки, которая принимает входные данные url и загружает файл внутри контейнера.

  2. Нам нужно использовать файл, сгенерированный на первом шаге, и запустить программу Python - это будет сделано за секунды containerop.

Пример кода приведен ниже.

@dsl.component
    def download(url: str, output_file: OutputPath(str)):
        return dsl.ContainerOp(
            name='Download',
            image='busybox:latest',
            command=["sh", "-c"],
            arguments=["wget %s " % url, output_file)],
        )

И вышеупомянутый код будет вызываться с использованием

download_task = download(url=<URL>")

Согласно спецификации компонента https://www.kubeflow.org/docs/components/pipelines/reference/component-spec/ - выходной путь указывать не нужно.

https://github.com/kubeflow/pipelines/blob/d106a6533bf4e1cbda4364560bc7526cb67d4eb2/samples/tutorials/Data%20passing%20in%20python%20components/Data%20passing%2020inpy#L69 - @func_to_container_op - Мы могли увидеть способ получить вывод с использованием типа OutputPath.

Есть ли способ добиться этого в dsl.containerop. Мы не хотим жестко кодировать выходной путь с помощью file_outputs.


person srinath    schedule 24.04.2021    source источник


Ответы (2)


Вы не можете сделать это в ContainerOp, это было одной из причин, по которой ContainerOp устарел, см. https://github.com/kubeflow/pipelines/pull/4166.

Предложения:

  1. После https://www.kubeflow.org/docs/components/pipelines/reference/component-spec/ для создания многоразового компонента yaml.
  2. если вы предпочитаете встраивать компонент yaml для одноразовых компонентов, вы можете загрузить его с помощью метода kfp.components.load_component_from_text, обращаясь к этот пример конвейера.
person Bob Gong    schedule 26.04.2021
comment
Большое спасибо за ответ. В нашем случае у нас есть два шага. 1. На первом этапе данные загружаются по определенному пути. 2. На втором этапе нам нужно использовать загруженные данные и обучаться. Большая часть примера kubeflow говорит о передаче данных в виде строк. Я предполагаю, что если у нас есть несколько component.yaml, мы можем сгенерировать вывод на первом шаге и использовать ту же переменную на втором. Есть ли у вас какие-либо предложения по передаче пути к папке между несколькими компонентами (работающими в разных контейнерах)? - person srinath; 26.04.2021
comment
Передача файлов / папок между контейнерами уже поддерживается, см. Этот раздел документа выше: kubeflow.org/docs/components/pipelines/reference/component-spec/ - person Bob Gong; 27.04.2021
comment
@srinath KFP не совсем передает пути - пути локальны для контейнера. KFP передает фактические данные (файлы, каталоги) - KFP берет выходные данные из контейнера вышестоящих компонентов и затем помещает их в контейнеры последующих компонентов. - person Ark-kun; 28.04.2021

Пожалуйста, проверьте следующие два руководства для shell и Python.

Вот как вы можете написать компонент загрузчика: (Сохраните это как component.yaml), а затем выполните download_op = load_component_from_file('component.yaml')

name: Download data
inputs:
- {name: Url, type: URI}
options given to the curl bprogram. See https://curl.haxx.se/docs/manpage.html'}
outputs:
- {name: Data}
implementation:
  container:
    image: curlimages/curl
    command:
    - sh
    - -exc
    - |
      url="$0"
      output_path="$1"
      mkdir -p "$(dirname "$output_path")"
      curl --get "$url" --output "$output_path"
    - inputValue: Url
    - outputPath: Data

Существует также пример конвейера, который загружает данные с помощью curl, а затем обучается на этих данных: конвейер XGBoost

P.S. Компонент для загрузки данных из Интернета уже существует: download_op = load_component_from_url('https://raw.githubusercontent.com/kubeflow/pipelines/master/components/web/Download/component.yaml')

person Ark-kun    schedule 27.04.2021