-
Notifications
You must be signed in to change notification settings - Fork 28.2k
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
Add ViTImageProcessorFast to tests #31424
Add ViTImageProcessorFast to tests #31424
Conversation
@@ -151,6 +151,11 @@ def center_crop( | |||
**kwargs, | |||
) | |||
|
|||
def to_dict(self): | |||
encoder_dict = super().to_dict() | |||
encoder_dict.pop("_valid_processor_keys", None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@molbap Would be good to have your confirmation here that we can remove - I don't think we want to save this out in the config: it's private and wouldn't be used when creating a new config class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I agree! no use having it written to the config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering:
- why is
_valid_processor_keys
instance attribute? (could be class attribute?)
image_processor_class += "Fast" | ||
elif not use_fast and image_processor_class.endswith("Fast"): | ||
image_processor_class = image_processor_class[:-4] | ||
if use_fast is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only update the image_processor_class if use_fast
is explicitly set. This makes sure that if a fast image processor is saved out, it will be loaded in as a fast image processor from AutoImageProcessor
by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got the idea. But it looks like to me here you want to make sure if a slow (rather than slow
as you mentioned above) image processor is saved, and use_fast
is not specified, we want to load with fast image processor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I completely understood your comment, but let me try and explain the desired behaviour, and you can let me know if I've mistaken something :)
At the moment, we don't want use_fast
to default to either False
or True
, as this will affect the image processor loaded in regardless of the type of image processor saved out.
Desired behaviours
- Saved slow image processor -> loads slow image processor by default (
use_fast
unset) - Saved fast image processor -> loads fast image processor by default (
use_fast
unset) - Save slow image processor,
use_fast=False
-> loads slow image processor - Save slow image processor,
use_fast=True
-> loads fast image processor - Save fast image processor,
use_fast=False
-> loads slow image processor - Save fast image processor,
use_fast=True
-> loads fast image processor
i.e. if a fast image processor is available, but a slow image processor is saved out, we still want to default to the slow image processor for now as they won't produce exactly the same outputs, and instead inform them that a fast version is available. This is to avoid unexpected behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I got it now.
that if a fast image processor is saved out, it will be loaded in as a fast image processor if
use_fast is None
which is not the current main
but addressed in this PR.!
sorry (not easy to reason about all these cases and motivation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which is not the current main but addressed in this PR.!
Yep! It was a bug that I hadn't noticed before 😬
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. |
e888ec4
to
cf622c7
Compare
@@ -772,7 +772,7 @@ def preprocess( | |||
ignore_index, | |||
do_reduce_labels, | |||
return_tensors, | |||
input_data_format=input_data_format, | |||
input_data_format=data_format, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this model (and the ones below with this change) the "input_data_format" is now data_format because the images were changed to data_format in the _preprocess_image step.
This wasn't previously caught because the test images and the defaults were always in channels_last format.
Now, we're feeding in channels_first numpy images for tests, as this is the standard format for numpy images.
_ = image_processor(image, return_tensors="pt") | ||
return time.time() - start | ||
|
||
dummy_images = torch.randint(0, 255, (4, 3, 224, 224), dtype=torch.uint8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing with a PIL image was a bit flaky in terms of time comparisons...
@@ -238,6 +239,52 @@ def test_image_processor_save_load_with_autoimageprocessor(self): | |||
|
|||
self.assertEqual(image_processor_second.to_dict(), image_processor_first.to_dict()) | |||
|
|||
def test_save_load_fast_slow(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added tests to make sure we can correctly cross-load fast and slow image processors directly with its class and with the auto class.
Hi @amyeroberts . Could you help me to get some more context regarding the changes in this PR 🙏 ? From the title and the description, I understand:
However, I don't understand why we have the changes below:
Is this because previously we don't test with
Hope I don't ask too much 😅 |
@ydshieh Of course! :) Sorry that I didn't make it clear in the PR description.
We previously tested with numpy images. However, the numpy images created were in channels first format i.e. (C, H, W). They were essentially numpy versions of images in torch. When we added the fast image processor, we had to include logic to convert both PIL.Image.Image images and numpy arrays to torch tensors.
We wanted an operation equivalent to Within PyTorch transforms, there is the assumption that incoming numpy arrays are in channels last format. This is reasonable, as this is normally true. In order for this transform to now work for the fast image processors, the numpy arrays made for testing needed to be made in channels last, (H, W, C) format. Previously, as the tests had all arrays in channels_first format, the default if/else logic was fine, but now we need to condition on whether the input is a numpy array to get the correct size.
They completely are, mistake on my part, I'll update!
For the numpy tests, the inputs are now in channels_last format. I could also remove |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for explaining with details. LGTM with some comments/nits if you want to update directly in this PR
image_processor_class += "Fast" | ||
elif not use_fast and image_processor_class.endswith("Fast"): | ||
image_processor_class = image_processor_class[:-4] | ||
if use_fast is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got the idea. But it looks like to me here you want to make sure if a slow (rather than slow
as you mentioned above) image processor is saved, and use_fast
is not specified, we want to load with fast image processor.
@@ -151,6 +151,11 @@ def center_crop( | |||
**kwargs, | |||
) | |||
|
|||
def to_dict(self): | |||
encoder_dict = super().to_dict() | |||
encoder_dict.pop("_valid_processor_keys", None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering:
- why is
_valid_processor_keys
instance attribute? (could be class attribute?)
d97c848
to
90c9584
Compare
image_processor_class += "Fast" | ||
elif not use_fast and image_processor_class.endswith("Fast"): | ||
image_processor_class = image_processor_class[:-4] | ||
if use_fast is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I got it now.
that if a fast image processor is saved out, it will be loaded in as a fast image processor if
use_fast is None
which is not the current main
but addressed in this PR.!
sorry (not easy to reason about all these cases and motivation)
What does this PR do?
Accidentally didn't add ViTImageProcessorFast to the test suite when adding the class to the library in #28847 as
fast_image_processor_class
wasn't set in the tester.Adds it to the tester and fixes anything needed for tests to pass as well as two additional tests to make sure cross loading between the fast and slow image processors works as expected