pipelines icon indicating copy to clipboard operation
pipelines copied to clipboard

[sdk] Component parameters with 'Bool' type cannot be used in conditions ("invalid truth value")

Open senarvi opened this issue 4 years ago • 8 comments

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 👍.

senarvi avatar Jun 07 '21 11:06 senarvi

/cc @chensun

Bobgy avatar Jun 11 '21 00:06 Bobgy

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.

stale[bot] avatar Oct 02 '21 01:10 stale[bot]

Bump

senarvi avatar Oct 05 '21 19:10 senarvi

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.

stale[bot] avatar Mar 02 '22 18:03 stale[bot]

Is there any workaround or alternative that can be used?

BroderPeters avatar Nov 14 '22 12:11 BroderPeters

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.

senarvi avatar May 26 '23 11:05 senarvi

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.

senarvi avatar Jul 27 '23 08:07 senarvi

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.

github-actions[bot] avatar Jun 21 '24 07:06 github-actions[bot]

This issue has been automatically closed because it has not had recent activity. Please comment "/reopen" to reopen it.

github-actions[bot] avatar Jul 13 '24 07:07 github-actions[bot]