我想在Kubeflow管道中编写一个包含2个组件的管道:A和B
A的输出是图像路径列表。
我想为每个图像路径运行一个docker图像(B)
从我看到的B的dsl.ContainerOp
可以等待A的输出,但是我不知道如何创建B的多个实例
答案 0 :(得分:1)
这是Kubeflow DSL的一个公认问题:使用一个组件(A)的输出,并为上一个输出中的每个条目运行一个新组件(B)对其进行迭代。由于Kubeflow使用的DSL处于编译时,因此很难,并且当时尚无法知道输出中将包含多少个元素。
参考:
从KF v0.6开始,支持动态(运行时)迭代的唯一形式是:dsl-recursion。我已经通过2种方式使它工作,而上述问题缺乏悬而未决的工作:
如果A的结果大小在每次运行中都将是一个常数并且是已知的,则很简单。
案例A:上一步的输出大小是已知的
# Write a python code to extract the path from
# the string of refs the previous step returns
def get_path(str_of_paths: str, idx: int) -> str:
return str_of_paths.split(" ")[idx] # or some other delimiter
get_img_path_comp = comp.func_to_container_op(get_path,base_image='tensorflow/tensorflow') # or any appropriate base image
然后管道dsl代码中的常规for循环将起作用
image_path_res = ContainerOP_A() # run your container Op
for idx in range(4):
path = get_path(image_path_res.output, i)
ContainerOp_B(path.output)
情况B:当上一步的输出大小不是固定的
这有点棘手和复杂。从KF v0.6开始,Kubeflow允许的动态循环的唯一形式是dsl-recursion
选项1
sizer_op
的大小,然后从上方重用相同的get_img_path_comp
。@dsl.component
def sizer_op(str_of_refs) -> int:
return len(str_of_refs.split("|"))
sizer_op_comp = comp.func_to_container_op(sizer_op,base_image='tensorflow/tensorflow')
然后您可以运行回溯功能
@dsl.graph_component
def recursive_run(list_of_images, cur_ref):
with dsl.Condition(cur_ref >= 0):
path = get_path(image_path_res.output, i)
ContainerOp_B(path.output)
# call recursively
recursive_run(list_of_images, cur_ref - 1)
image_path_res = ContainerOP_A() # run your container Op
sizer = sizer_op_comp(image_path_res)
recursive_run(image_path_res.output, sizer.output)
选项2
运行ContainerOp_A之后,创建一个Kubeflow组件,该组件从ContainerOp_A读取结果,将结果解析为python代码本身,然后使用kfclient生成仅运行Containerop_B的新运行。您可以使用以下方法连接到KF管道客户端:
kf_client = Client(host=localhost:9990)
引用:kf_client