Skip to content

Add the ImageClassificationPipeline#11598

Merged
LysandreJik merged 3 commits into
masterfrom
image-classification-pipeline
May 7, 2021
Merged

Add the ImageClassificationPipeline#11598
LysandreJik merged 3 commits into
masterfrom
image-classification-pipeline

Conversation

@LysandreJik

@LysandreJik LysandreJik commented May 5, 2021

Copy link
Copy Markdown
Member

This PR adds the ImageClassificationPipeline. It is tested on DeiT and ViT and should enable the inference API for these models.

Since I encountered an issue with the AutoExtractor, I fixed it as seen with @sgugger (namely switched it from using names such as "deit" to using the configuration class as a key, similarly to what we do in tokenizers and the other auto classes.

Please let me know if you would like me to split this PR into multiple PRs for simpler reviews, happy to do so.

@NielsRogge, happy to have your review.

``./my_model_directory/``.
- a path or url to a saved feature extractor JSON `file`, e.g.,
``./my_model_directory/feature_extraction_config.json``.
``./my_model_directory/preprocessor_config.json``.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Changed this to the actual name of the configuration file

Comment on lines -41 to +34
("deit", DeiTFeatureExtractor),
("s2t", Speech2TextFeatureExtractor),
("vit", ViTFeatureExtractor),
("wav2vec2", Wav2Vec2FeatureExtractor),
(DeiTConfig, DeiTFeatureExtractor),
(Speech2TextConfig, Speech2TextFeatureExtractor),
(ViTConfig, ViTFeatureExtractor),
(Wav2Vec2Config, Wav2Vec2FeatureExtractor),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As seen with @sgugger

# At that point framework might still be undetermined
model = get_default_model(targeted_task, framework, task_options)

# Try to infer tokenizer from model or config name (if provided as str)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Moved the tokenizer initialization logic beneath the model initialization, with the feature processor. This way it benefits from having access to the model configuration.

self,
model: Union["PreTrainedModel", "TFPreTrainedModel"],
tokenizer: PreTrainedTokenizer,
tokenizer: Optional[PreTrainedTokenizer] = None,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The tokenizer becomes an optional value, alongside the feature_extractor.

Comment on lines -633 to +649
supported_models = [item[1].__name__ for item in supported_models.items()]
supported_models_names = []
for config, model in supported_models.items():
# Mapping can now contain tuples of models for the same configuration.
if isinstance(model, tuple):
supported_models_names.extend([_model.__name__ for _model in model])
else:
supported_models_names.append(model.__name__)
supported_models = supported_models_names

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was forgotten with the addition of the possibility to have two different models for a single configuration in #11150.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good catch!

import os
from collections import OrderedDict

from transformers import DeiTFeatureExtractor, Speech2TextFeatureExtractor, ViTFeatureExtractor

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This enables the use of dummy objects here rather than having None objects

@sgugger sgugger left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice addition! Thanks for working on this!

Comment thread src/transformers/pipelines/base.py
Comment on lines -633 to +649
supported_models = [item[1].__name__ for item in supported_models.items()]
supported_models_names = []
for config, model in supported_models.items():
# Mapping can now contain tuples of models for the same configuration.
if isinstance(model, tuple):
supported_models_names.extend([_model.__name__ for _model in model])
else:
supported_models_names.append(model.__name__)
supported_models = supported_models_names

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good catch!

@patil-suraj patil-suraj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice! Thank you for adding this, LGTM.

Comment thread src/transformers/models/auto/feature_extraction_auto.py Outdated
Comment thread src/transformers/models/auto/feature_extraction_auto.py
Comment thread src/transformers/pipelines/__init__.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread tests/test_feature_extraction_auto.py
Comment thread tests/test_pipelines_image_classification.py

@patrickvonplaten patrickvonplaten left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

The only thing, I feel quite strongly about is to wrap the forward pass into a with torch.no_grad(): to avoid computing costly activations.

The rest is all nits

@NielsRogge

Copy link
Copy Markdown
Collaborator

LGTM, thank you for adding this.

@Narsil Narsil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Biggest change is the tokenizer logic modification, we should really respect that if a user sends us something that is not a str(or tuple...) then we need to assume it's a valid tokenizer and pass it as is.

Also the tests are a bit bloated IMO compared to what they could be. In that instance, because we can't test parity with TF, we should just make the tests much simpler.
Also we don't test pipeline outputs which is a big issue for maintaining BC.

The image loading logic should be fixed too.

The rest are NITs.

Comment thread src/transformers/pipelines/__init__.py
Comment thread src/transformers/pipelines/base.py
Comment thread tests/test_pipelines_image_classification.py
Comment thread tests/test_pipelines_image_classification.py Outdated
Comment thread tests/test_pipelines_image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py Outdated
Comment thread src/transformers/pipelines/image_classification.py
Comment thread src/transformers/pipelines/__init__.py Outdated
Co-authored-by: patrickvonplaten <[email protected]>
@LysandreJik
LysandreJik force-pushed the image-classification-pipeline branch from 60b0263 to 25594b5 Compare May 6, 2021 15:00
@LysandreJik

Copy link
Copy Markdown
Member Author

I should have addressed all comments.

@Narsil, if you could review once again when you have time, would love your feedback on the updated tests and on the updated __init__ method.

@Narsil Narsil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM.

Last nit, maybe the load_image function could be put not inlined (like at the module level).

It should make it easier to test and overload.

@LysandreJik
LysandreJik merged commit 39084ca into master May 7, 2021
@LysandreJik
LysandreJik deleted the image-classification-pipeline branch May 7, 2021 12:08
Iwontbecreative pushed a commit to Iwontbecreative/transformers that referenced this pull request Jul 15, 2021
* Add the ImageClassificationPipeline

* Code review

Co-authored-by: patrickvonplaten <[email protected]>

* Have `load_image` at the module level

Co-authored-by: patrickvonplaten <[email protected]>
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.

6 participants