def gdmix_distributed_workflow(gdmix_config_file, namespace, secret_name, image, service_account): """ Generate gdmix kubeflow pipeline using Kubeflow pipeline python DSL( kfp.dsl). """ gdmix_config_obj = yaml_config_file_to_obj(gdmix_config_file) current_op = no_op("GDMix-training-start") suffix = gen_random_string() if not hasattr(gdmix_config_obj, FIXED_EFFECT_CONFIG): raise ValueError(f"Need to define {FIXED_EFFECT_CONFIG}") fe_tip_op = no_op("fixed-effect-training-start") fe_tip_op.after(current_op) fe_workflow = FixedEffectWorkflowGenerator(gdmix_config_obj, namespace=namespace, secret_name=secret_name, image=image, service_account=service_account, job_suffix=suffix) fe_start_op, current_op = fe_workflow.gen_workflow() fe_start_op.after(fe_tip_op) if hasattr(gdmix_config_obj, RANDOM_EFFECT_CONFIG): re_tip_op = no_op("random-effect-training-start") re_tip_op.after(current_op) re_workflow = RandomEffectWorkflowGenerator(gdmix_config_obj, namespace=namespace, secret_name=secret_name, image=image, service_account=service_account, job_suffix=suffix, prev_model_name=fe_workflow.fixed_effect_name) re_start_op, _ = re_workflow.gen_workflow() re_start_op.after(re_tip_op)
def no_op(msg): """ Empty op as a placeholder on workflow to handle dependency. """ from kfp import dsl return dsl.ContainerOp(name="{}-{}".format(msg, gen_random_string()), image="alpine", command=['sh', '-c'], arguments=["echo {}".format(msg)])
def load_launcher_from_file(src_file, name_placeholder, name): """ Load launcher's commponent yaml file and update launcher name """ dest_file = shutil.copyfile(src_file, gen_random_string(20) + ".tmp.yaml") with fileinput.FileInput(dest_file, inplace=True) as f: for line in f: line = line.replace(name_placeholder, name) print(line, end='') from kfp import components component = components.load_component_from_file(dest_file) os.remove(dest_file) return component