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

Image pipelines spec compliance #33899

Merged
merged 15 commits into from
Oct 8, 2024
Merged

Conversation

Rocketknight1
Copy link
Member

This PR checks for Hub spec compliance for a lot of image pipelines that have very similar inputs. In most cases, no changes are required except deprecating the timeout argument, and renaming the images input to inputs.

@HuggingFaceDocBuilderDev

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Copy link
Member

@LysandreJik LysandreJik left a comment

Choose a reason for hiding this comment

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

Looks good, but I wonder if we shouldn't mention in the deprecation/in the pipeline docs that the pipelines will now be 1-1 with the HF specs in general, to justify the change from images to inputs

Comment on lines 86 to 89
warnings.warn(
"The `images` argument has been renamed to `inputs`. In version 5 of Transformers, `images` will no longer be accepted",
FutureWarning,
)
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if these warnings (and the docs) shouldn't point to the global definition of specs across the HF ecosystem to justify such a change

Copy link
Member Author

Choose a reason for hiding this comment

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

What's the right document to link users to as the "source of truth" there? Just the folder in the Hub repo here?

@@ -1,3 +1,4 @@
import warnings
Copy link
Member

Choose a reason for hiding this comment

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

This file is lacking the copyright!
Can you add it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

@@ -50,12 +51,12 @@ def __init__(self, *args, **kwargs):
requires_backends(self, "vision")
self.check_model_type(MODEL_FOR_DEPTH_ESTIMATION_MAPPING_NAMES)

def __call__(self, images: Union[str, List[str], "Image.Image", List["Image.Image"]], **kwargs):
def __call__(self, inputs: Union[str, List[str], "Image.Image", List["Image.Image"]] = None, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

Note for myself: this change won't break Inference API since it's using positional argument and not keyword one (see here - private link). So all good to change it, same for all other pipelines :)

Comment on lines 161 to 165
if "images" in kwargs:
warnings.warn(
"The `images` argument has been renamed to `inputs`. In version 5 of Transformers, `images` will no longer be accepted",
FutureWarning,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if this is working as expected. Say you have a user script like this:

pipeline = ImageClassificationPipeline(...)
output = pipeline(images=<my-image>, foo="bar")

with this PR, the pipeline call will fail with something like "requires 1 positional argument, got 0" because inputs is not provided.

Copy link
Contributor

Choose a reason for hiding this comment

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

what I would suggest is to have a decorator like this:

def _rename_positional_arg(old_name: str) -> Callable:

    def _decorator(fn: Callable) -> Callable:

        def _inner(*args, **kwargs):
            if old_name in kwargs:
                if len(args) > 0 or "inputs" in kwargs:
                    raise ValueError(f"Cannot pass 'inputs' and '{old_name}' at the same time.")
                warnings.warn("Deprecation message 'you should use inputs instead of {old_name}' ...")
                kwargs["inputs"] = kwargs.pop(old_name)
        return fn(*args, **kwargs)

    return decorator

which you can use like this:

...

@_rename_positional_arg(old_name="images")
def __call__(self, inputs: Union[str, List[str], "Image.Image", List["Image.Image"]] = None, **kwargs):
    ...  # here you are guaranteed "inputs" is passed

This way, the pipeline will both if:

  • inputs are passed as positional args (as done in Inference API)
  • inputs are passed as inputs
  • inputs are passed as images

(I did not find a satisfying decorator name but you have the idea^^)

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, it should work! I set a new default argument value of None for inputs, so the pipeline can be called without that argument. However, it will raise an exception if neither inputs nor images are passed.

Copy link
Member Author

@Rocketknight1 Rocketknight1 Oct 3, 2024

Choose a reason for hiding this comment

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

In other words:

Case 1: Users are passing "images" as a positional argument. The argument is renamed to inputs and they don't notice any change

Case 2: Users are passing "images" as a kwarg. inputs is now None but **kwargs contains an "images" key. The code detects this and sets inputs = kwargs.pop("images"), then prints the deprecation warning

Copy link
Contributor

Choose a reason for hiding this comment

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

Ooh, sorry I did not see the added = None. You are completely right, forget what I meant above :)

@LysandreJik
Copy link
Member

Actually thinking more about it and inline with having less and less warnings in transformers, I wonder if we want to have a deprecation warning for images vs outputs, or if we just want to enable both without warning

@Rocketknight1
Copy link
Member Author

Rocketknight1 commented Oct 3, 2024

@LysandreJik yes, I'm fine with that! Want me to just drop all the deprecation warnings? I can maybe throw an error if users specify both arguments, or something.

@Wauplin
Copy link
Contributor

Wauplin commented Oct 3, 2024

If no deprecation warning is raised (i.e. accept both inputs and images on the long run), I would make sure the method signature is in line with the recommendation (i.e. passing inputs). In that sense, I don't think that having inputs: ... = None on the long run is desirable as it can be misleading to users. If it was only for a few versions before settling for the definitive signature (i.e. no images at all), it would have been fine but that's not the case, right?

@Rocketknight1
Copy link
Member Author

@Wauplin Unfortunately, if we don't set inputs = None, then users have to pass inputs, and we can't accept images as an alternative.

I think it's okay, though! There are a lot of classes in transformers that have None defaults for mandatory inputs - it just means that we handle the error when the argument is missing somewhere else.

@LysandreJik
Copy link
Member

I'll let you decide the best course of action in terms of signature/arguments @Rocketknight1, but dropping the deprecation warnings seems to me like the right thing to do here

@Rocketknight1
Copy link
Member Author

Done! Warnings are removed, but I'll accept both keywords for now - I don't think the main input having a default of None should be too confusing, especially since the docstrings are clear.

@Rocketknight1 Rocketknight1 merged commit 3b44d2f into main Oct 8, 2024
20 checks passed
@Rocketknight1 Rocketknight1 deleted the image_pipelines_spec_compliance branch October 8, 2024 12:34
NielsRogge pushed a commit to NielsRogge/transformers that referenced this pull request Oct 21, 2024
* Update many similar visual pipelines

* Add input tests

* Add ImageToText as well

* Add output tests

* Add output tests

* Add output tests

* OutputElement -> Output

* Correctly test elements

* make fixup

* fix typo in the task list

* Fix VQA testing

* Add copyright to image_classification.py

* Revert changes to VQA pipeline because outputs have differences - will move to another PR

* make fixup

* Remove deprecation warnings
BernardZach pushed a commit to BernardZach/transformers that referenced this pull request Dec 5, 2024
* Update many similar visual pipelines

* Add input tests

* Add ImageToText as well

* Add output tests

* Add output tests

* Add output tests

* OutputElement -> Output

* Correctly test elements

* make fixup

* fix typo in the task list

* Fix VQA testing

* Add copyright to image_classification.py

* Revert changes to VQA pipeline because outputs have differences - will move to another PR

* make fixup

* Remove deprecation warnings
BernardZach pushed a commit to innovationcore/transformers that referenced this pull request Dec 6, 2024
* Update many similar visual pipelines

* Add input tests

* Add ImageToText as well

* Add output tests

* Add output tests

* Add output tests

* OutputElement -> Output

* Correctly test elements

* make fixup

* fix typo in the task list

* Fix VQA testing

* Add copyright to image_classification.py

* Revert changes to VQA pipeline because outputs have differences - will move to another PR

* make fixup

* Remove deprecation warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants