[sdk] Component parameters with 'Bool' type cannot be used in conditions ("invalid truth value")
Environment
- KFP SDK version: kfp 1.6.3 kfp-pipeline-spec 0.1.8 kfp-server-api 1.6.0
Steps to reproduce
Using a boolean parameter in an "if" condition in container arguments used to work in kfp==1.4.0, but kfp==1.6.x gives the following "invalid truth value" error (apparently trying to pass the parameter placeholder to strtobool() even if the value is available):
Traceback (most recent call last):
File "test_case.py", line 25, in <module>
compiler.Compiler().compile(pipeline, 'pipeline.yaml')
File ".../lib/python3.9/site-packages/kfp/compiler/compiler.py", line 1053, in compile
self._create_and_write_workflow(
File ".../lib/python3.9/site-packages/kfp/compiler/compiler.py", line 1106, in _create_and_write_workflow
workflow = self._create_workflow(
File ".../lib/python3.9/site-packages/kfp/compiler/compiler.py", line 896, in _create_workflow
pipeline_func(*args_list, **kwargs_dict)
File "test_case.py", line 22, in pipeline
op()
File ".../lib/python3.9/site-packages/kfp/components/_dynamic.py", line 34, in Component
return dict_func(locals()) # noqa: F821 TODO
File ".../lib/python3.9/site-packages/kfp/components/_components.py", line 343, in create_task_object_from_component_and_pythonic_arguments
return _create_task_object_from_component_and_arguments(
File ".../lib/python3.9/site-packages/kfp/components/_components.py", line 290, in _create_task_object_from_component_and_arguments
task = _container_task_constructor(
File ".../lib/python3.9/site-packages/kfp/dsl/_component_bridge.py", line 302, in _create_container_op_from_component_and_arguments
_attach_v2_specs(task, component_spec, original_arguments)
File ".../lib/python3.9/site-packages/kfp/dsl/_component_bridge.py", line 596, in _attach_v2_specs
resolved_cmd = _resolve_commands_and_args_v2(
File ".../lib/python3.9/site-packages/kfp/dsl/_component_bridge.py", line 442, in _resolve_commands_and_args_v2
resolved_cmd = _components._resolve_command_line_and_paths(
File ".../lib/python3.9/site-packages/kfp/components/_components.py", line 511, in _resolve_command_line_and_paths
expanded_args = expand_argument_list(container_spec.args)
File ".../lib/python3.9/site-packages/kfp/components/_components.py", line 502, in expand_argument_list
expanded_part = expand_command_part(part)
File ".../lib/python3.9/site-packages/kfp/components/_components.py", line 482, in expand_command_part
condition_result_bool = condition_result and strtobool(condition_result) #Python gotcha: bool('False') == True; Need to use strtobool; Also need to handle None and []
File ".../lib/python3.9/distutils/util.py", line 320, in strtobool
raise ValueError("invalid truth value %r" % (val,))
ValueError: invalid truth value "{{$.inputs.parameters['enable']}}"
Code to reproduce the problem:
# test_case.py
@dsl.pipeline(name="Pipeline", description="Pipeline")
def pipeline() -> None:
op = components.load_component_from_text(
"""
name: Component
inputs:
- {name: enable, type: Bool, default: False}
implementation:
container:
image: some/container
args:
- if:
cond:
inputValue: enable
then:
- '--enable'
"""
)
op()
if __name__ == '__main__':
compiler.Compiler().compile(pipeline, 'pipeline.yaml')
Expected result
The pipeline is expected to compile. In the code sample, the component would not have any arguments. Calling op(True) would add the --enable argument to the component. (This is how kfp==1.4.0 works.)
Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.
/cc @chensun
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Bump
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Is there any workaround or alternative that can be used?
Started using Kubeflow after a long while and ran into this problem again with Kubeflow 1.8.22. I think this workaround should work:
- Make the default value of all Bool parameters False.
- Use isPresent instead of the inputValue condition.
- Never set a parameter to False, i.e. either use the default or True.
The workaround gets tricky if you want to pass a boolean pipeline parameter to the component. I thought it would be possible (although ugly) using two dsl.Conditions in the pipeline: one dsl.Condition is executed when the pipeline parameter is True and passes a True value to the component and the other one is executed when the pipeline parameter is False and doesn't pass the component parameter. However, I couldn't get it to work due to another bug. Maybe it works in KFP 2.0.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed because it has not had recent activity. Please comment "/reopen" to reopen it.