Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sdk): SDK - Deprecation warning when using ContainerOp #4166

Conversation

Ark-kun
Copy link
Contributor

@Ark-kun Ark-kun commented Jul 7, 2020

We have long advised our users to create reusable components.
Creating reusable components is as easy as creating ContainerOp instances, but the components are shareable, portable and are easier to support going forward.

@k8s-ci-robot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@kubeflow-bot
Copy link

This change is Reviewable

We have long advised our users to create reusable components.
Creating reusable components is as easy as creating ContainerOp instances, but the components are shareable, portable and are easier to support going forward.
@Ark-kun Ark-kun force-pushed the SDK---Added-warning-when-not-using-components branch from 1a8e256 to 02e1a49 Compare July 7, 2020 21:59
@Ark-kun Ark-kun marked this pull request as ready for review July 7, 2020 22:47
sdk/python/kfp/dsl/_component_bridge.py Outdated Show resolved Hide resolved
# The warning is suppressed for pipelines created using the TFX SDK.
warnings.warn(
"Please create reusable components instead of constructing ContainerOp instances directly."
" Reusable components are shareable, portable and have compatibility and support guarantees."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does deprecation warning mean container op will be removed in the future?

have compatibility and support guarantees

Can you explain this part?

I think people typically don't want a layer of abstraction before thinking about reusability. Is the best option a component with no arguments in that case?

Copy link
Contributor Author

@Ark-kun Ark-kun Jul 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does deprecation warning mean container op will be removed in the future?
Not necessary. But its role would be "task-like object that you get when creating an instance of component when compiling pipeline using KFP's compiler". So the users will still be interacting with ContainerOp objects, but they won't be creating those objects manually.

have compatibility and support guarantees
Can you explain this part?

Components have better support throughout the system compared with raw ContainerOp.

  • ContainerOps do not have inputs
  • ContainerOps do not have types (so the artifacts in MLMD are untyped)
  • ContainerOps are not supported in graph components
  • There are no plans to support ContainerOps in TFX, but there are already multiple experimenta implementations of component support

Components have a more supported way forward compared to ContainerOp. There are already multiple experimental implementations of KFP component support for TFX, but it's not really possible to support ContainerOps there.

I think people typically don't want a layer of abstraction before thinking about reusability.

I understand. But the equivalent components are the same number of lines/characters as ContainerOp code while providing more benefits. Also, I've answered dozens of issues from people using ContainerOps and many of those would not happen is they just used components. For example, with ContainerOp people are not thinking how they consume outputs, so they sometimes consume big outputs as values and then get runtime errors due to the data size.

Is the best option a component with no arguments in that case?

I think so.

Example 1:

hello_op = kfp.components.load_component_from_text('''
implementation:
  container:
    image: alpine
    command: ["echo", "Hello world"]
''')

instead of

def hello_op():
    return kfp.dsl.ContainerOp(
        name="Hello",
        image="alpine",
        command=["echo", "Hello world"],
    )

Example 2:

hello_op = kfp.components.load_component_from_text('''
inputs:
- name: message
implementation:
  container:
    image: alpine
    command: ["echo", {inputValue: message}]
''')

instead of

def hello_op(message):
    return kfp.dsl.ContainerOp(
        name="Hello",
        image="alpine",
        command=["echo", message],
    )

Example 3:

hello_op = kfp.components.load_component_from_text('''
inputs:
- name: message
inputs:
- name: result
implementation:
  container:
    image: alpine
    command: ["sh", "-c", 'mkdir -p "$(dirname "$1")"; echo "$0" > "$1"', {inputValue: message}, {outputPath: result}]
''')

instead of

def hello_op(message):
    return kfp.dsl.ContainerOp(
        name="Hello",
        image="alpine",
        command: ["sh", "-c", 'mkdir -p "$(dirname "$1")"; echo "$0" > "$1"', message, '/tmp/outputs/result/data'],
        output_artifact_paths={
            'result': '/tmp/outputs/result/data',
        },
    )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'm convinced. It would be great adding these to documentation.

So the plan is deprecating ContainerOp right now and removing it in the future?
SGTM

/lgtm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the plan is deprecating ContainerOp right now and removing it in the future?

For now there are no plans to actually deprecate the class or remove it. Here is how it currently works:

KFP: component.yaml --load--> Callable --instantiate--> ContainerOp object
TFX: component.yaml --load--> Callable --instantiate--> BaseComponent object

So ContainerOp will still exist. You'll be able to access ContainerOp.outputs, ContainerOp.container.*, , ContainerOp.set_display_name(), ContainerOp.after(), ContainerOp.apply(), ContainerOp.add_volume() etc. It's still ContainerOp. Basically, we're only deprecating calling ContainerOp.__init__, but everything else remains.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great adding these to documentation.

Good idea. I'm working on updating the documentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, sounds good

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KFP: component.yaml --load--> Callable --instantiate--> ContainerOp object
Will this continue to be the case? We have code depending on manipulating the returned ContainerOp in kfp.dsl.pipeline annotated functions.

@k8s-ci-robot k8s-ci-robot added size/M and removed size/S labels Jul 8, 2020
@Ark-kun
Copy link
Contributor Author

Ark-kun commented Jul 8, 2020

/retest

1 similar comment
@Ark-kun
Copy link
Contributor Author

Ark-kun commented Jul 9, 2020

/retest

@Ark-kun
Copy link
Contributor Author

Ark-kun commented Jul 9, 2020

/approve

@Ark-kun Ark-kun added cherrypick-approved area OWNER approves to cherry pick this PR to current active release branch and removed approved labels Jul 9, 2020
@Bobgy
Copy link
Contributor

Bobgy commented Jul 9, 2020

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Ark-kun, Bobgy

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Bobgy Bobgy changed the title feat(sdk): SDK - Added warning when not using components feat(sdk): SDK - Added warning when using ContainerOp Jul 9, 2020
@Bobgy Bobgy changed the title feat(sdk): SDK - Added warning when using ContainerOp feat(sdk): SDK - Deprecation warning when using ContainerOp Jul 9, 2020
@Bobgy
Copy link
Contributor

Bobgy commented Jul 9, 2020

edited title to make it clearer ContainerOp is the one being deprecated

@k8s-ci-robot k8s-ci-robot merged commit 2f94827 into kubeflow:master Jul 9, 2020
@Bobgy Bobgy added the cherrypicked cherry picked to release branch `release-x.y` label Jul 9, 2020
Bobgy pushed a commit that referenced this pull request Jul 9, 2020
* SDK - Added warning when not using components

We have long advised our users to create reusable components.
Creating reusable components is as easy as creating ContainerOp instances, but the components are shareable, portable and are easier to support going forward.

* Disable warning for TFX

* Fixed the warning disabling logic

* Added tests
Jeffwan pushed a commit to Jeffwan/pipelines that referenced this pull request Dec 9, 2020
…#4166)

* SDK - Added warning when not using components

We have long advised our users to create reusable components.
Creating reusable components is as easy as creating ContainerOp instances, but the components are shareable, portable and are easier to support going forward.

* Disable warning for TFX

* Fixed the warning disabling logic

* Added tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved area/sdk/dsl cherrypick-approved area OWNER approves to cherry pick this PR to current active release branch cherrypicked cherry picked to release branch `release-x.y` cla: yes lgtm size/M
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants