kubeflow管道动态输出列表作为输入参数

时间:2019-12-22 14:38:33

标签: python kubeflow kubeflow-pipelines

我在动态列表上使用了ParallelFor。我想从循环中收集所有输出,并将它们传递给另一个ContainerOp。
 如下所示,由于outputs列表是静态的,因此显然不起作用。

with dsl.ParallelFor(op1.output) as item:
    op2 = dsl.ContainerOp(
      name='op2',
      ...
      file_outputs={
         'outputs': '/outputs.json',
    })
    outputs.append(op2.output)


op3 = dsl.ContainerOp(
   name='op3',
   ...
   arguments=['--input': outputs]  # won't work
)

3 个答案:

答案 0 :(得分:1)

不幸的是,方舟坤的解决方案对我不起作用。但是,如果我们提前知道输入数量,则有一种简单的方法可以实现扇入式工作流程。我们可以像这样预先计算管道DAG:

@kfp.components.create_component_from_func
def my_transformer_op(item: str) -> str:
    return item + "_NEW"


@kfp.components.create_component_from_func
def my_aggregator_op(items: list) -> str:
    return "HELLO"


def pipeline(array_of_arguments):
    @dsl.pipeline(PIPELINE_NAME, PIPELINE_DESCRIPTION)
    def dynamic_pipeline():
        outputs = []
        for i in array_of_arguments:
            outputs.append(my_transformer_op(str(i)).output)
        my_aggregator_op(outputs)
    return dynamic_pipeline

...

    run_id = client.create_run_from_pipeline_func(
        pipeline(data_samples_chunks), {},
        run_name=PIPELINE_RUN,
        experiment_name=PIPELINE_EXPERIMENT).run_id

Here

答案 1 :(得分:0)

问题是op3没有正确地引用op2的输出作为输入参数。试试这个:

op3 = dsl.ContainerOp(
    ...
    arguments=['--input': op2.outputs['outputs']]
)

答案 2 :(得分:0)

我遇到了动态“扇出”问题,然后又出现了Kubeflow管道“扇入”问题。也许有些笨拙,但我使用了固定式PVC宣称来克服这个问题。

Kubeflow允许您使用min(链接here)动态安装已知的PVC或动态创建新的PVC。此代码段显示了如何使用已知的PVC。

max

确保VolumeOp pvc_name = '<available-pvc-name>' pvc_volume_name = '<pvc-uuid>' # pass the pvc uuid here # Op 1 creates a list to iterate over op_1 = dsl.ContainerOp( name='echo', image='library/bash:4.4.23', command=['sh', '-c'], arguments=['echo "[1,2,3]"> /tmp/output.txt'], file_outputs={'output': '/tmp/output.txt'}) # Using withParam here to iterate over the results from op1 # and writing the results of each step to its own PVC with dsl.ParallelFor(op_1.output) as item: op_2 = dsl.ContainerOp( name='iterate', image='library/bash:4.4.23', command=['sh', '-c'], arguments=[f"echo item-{item} > /tmp/output.txt; " # <- write to output f"mkdir -p /mnt/{{workflow.uid}}; " # <- make a dir under /mnt f"echo item-{item}\n >> /mnt/{{workflow.uid}}"], # <- append results from each step to the PVC file_outputs={'output': '/tmp/output.txt'}, # mount the PVC pvolumes={"/mnt": dsl.PipelineVolume(pvc=pvc_name, name=pvc_volume_name)}) op_3 = dsl.ContainerOp( name='echo', image='library/bash:4.4.23', command=['sh', '-c'], arguments=[f"echo /mnt/{{workflow.uid}} > /tmp/output.txt"], # mount the PVC again to use pvolumes={"/mnt": dsl.PipelineVolume(pvc=pvc_name, name=pvc_volume_name)}, file_outputs={'output': '/tmp/output_2.txt'}).after(op_2) op_3开始的循环之后运行。

注意:这可能是一种繁重的方法,如果KFP允许将其作为KF编译器的一部分,但可能会有更好的解决方案,但我无法使其正常工作。如果在环境中轻松创建PVC,则可能适合您的情况。

相关问题