-
Notifications
You must be signed in to change notification settings - Fork 31.5k
Add common test for torch.export and fix some vision models
#35124
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
Conversation
|
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. |
|
@guangy10 please have a look if you have bandwidth! Do you have anything in mind that should be added to the common test on the side of the |
ydshieh
left a comment
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.
Thanks @qubvel for working on this!
I haven't check the changes in models but left a few comments in test_modeling_common.py
ydshieh
left a comment
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 left a few tiny comments.
Could we also trigger slow CI for the modified models?
You can rebase on main to use the new way to trigger slow CI.
ydshieh
left a comment
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.
Make sure run a slow CI 🙏
Thanks for the work.
|
Ok, sure, what is a new way to trigger slow tests? Thanks for review 🤗 |
|
Second part in https://www.notion.so/huggingface2/CI-for-pull-requests-8335bd9217d24d1e8ed1d3a016f39804 or my message in slack https://huggingface.slack.com/archives/C01NE71C4F7/p1734527174922859 |
guangy10
left a comment
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.
@qubvel Great work and thank you for standardizing the test for exportability! Does this PR cover all vision existing vision models in transformers? Is there a plan to set up the same standard for audio models (in separate PRs)?
| test_mismatched_shapes = True | ||
| test_missing_keys = True | ||
| test_model_parallel = False | ||
| test_torch_exportable = False |
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.
If vast majority vision models are exportable, should we strategically turn this flag to True? Typically new models are more popular and important than old models, the biggest benefit of reversing the default to True is to "softly enforce" new models to be exportable, naturally growing this path to be the default and hard enforced over time. When I say softly enforce, I mean the new model can still have the option to disable export test if confirmed the failure is not obvious to fix and file a github issue in the backlog. But I do think most of the failures would be common and easy fixable given the work you did in this PR.
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.
Common tests are applied to all modalities, so for now, I suppose we will set it to False before updating for other models.
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.
Including text models right? @qubvel Could you guide me how I can leverage this common test to cover more test models like this: https://github.com/search?q=repo%3Ahuggingface%2Ftransformers%20test_export_static_cache&type=code
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.
It' s fine to have to as we want to reach 100% exportability no?
| for key in eager_outputs: | ||
| is_tested = is_tested or recursively_check(eager_outputs[key], exported_outputs[key]) | ||
| return is_tested | ||
| return is_tested |
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.
A nit for debuggability: Is silent return from here is expected? I think we should explicitly report/catch an error instead because it bypasses all checks due to output type mismatch?
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 suppose the main targets are covered, in case no matching types is_tested will be False and the error will be raised below.
| model, | ||
| args=(), | ||
| kwargs=inputs_dict, | ||
| strict=True, |
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.
@gmagogsfm Oh I think I recommended strict=True somewhere. The reason is to ensure the safety. If some python code block is unsupported by torchdynamo and got traced out in non-strict mode, instead of proceed silently defer seeing inconsistent results in the exported graph, a better process is to first surface the error up with strict mode, let the the model author or reviewers to see the source and confirm if it's safe and then turn the strict flag to False to unblock. cc: @ydshieh @qubvel
tests/test_modeling_common.py
Outdated
| with tempfile.TemporaryDirectory() as tmpdirname: | ||
| save_path = os.path.join(tmpdirname, "exported_model.pt2") | ||
| torch.export.save(exported_model, save_path) | ||
| exported_model = torch.export.load(save_path) |
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.
@qubvel You may want to add a check to ensure the loaded exported model is identical, to avoid any weird issues due to bugs in (de)serialization as you are checking the export outputs against eager using the loaded artifact.
In a workflow (e.g. to ExecuTorch for inference on-device) where exported model is just an intermediate representation, there is no need to save the exported program to a local fs first. We don't want any bug in (de)serialization of the exported IR affect the testability of the downstream workflow, so it's better to first compare the export and eager outputs, then test the (de)serialization.
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, basically, there is almost nothing we can do on our side in case of a deserialization error (just report to a torch team). So, I suppose we can remove this entirely, WDYT?
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.
Sure, we can remove this entirely
| raise ValueError(f"Unsupported parallel style value: {style}") | ||
|
|
||
|
|
||
| def compile_compatible_method_lru_cache(*lru_args, **lru_kwargs): |
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.
@qubvel Do you mind elaborate a bit more how this decorator helps with export?
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.
please, see below
| def compile_compatible_method_lru_cache(*lru_args, **lru_kwargs): | ||
| """ | ||
| LRU cache decorator from standard functools library, but with a workaround to disable | ||
| caching when torchdynamo is compiling. Expected to work with class methods. |
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.
what particular caching is disabled when torchdynamo is tracing?
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 turning off standard lru_cache when torchdynamo is compiling.
We had this decorator previously only for RT-DETR, I just moved it to make it common:
RT-DETR (afair) caches anchors to avoid it's creation for the same image size.
OmDet-Turbo (zero-shot-object-detection, out of this PR) cashes text label embeddings in order to avoid recomputing them once again in case the same label is passed.
Not that much speedup coming from these optimizations tbh, so I suppose it's fine to turn it off to enable compile/export.
|
|
||
| default_config, default_inputs_dict = self.model_tester.prepare_config_and_inputs_for_common() | ||
| config = config or default_config | ||
| inputs_dict = inputs_dict or default_inputs_dict |
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.
What are required parameters to be passed to the forward()? I think we should standardize the signature of forward so that we can simplify and standardize developing an ExecuTorch runtime for all vision models? Like what we did for text model in transformers.integrations.executorch where only input_ids and current cache_position are required as the model is always exported with the static_cache. We don't have to maintain backwards compatibility (BC) for all arguments.
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.
It might be different for different vision models, but most of them should have only pixel_values as the required parameter.
guangy10
left a comment
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.
Looks good! 🚀 🚀
ArthurZucker
left a comment
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.
Missing one big thing: documentation about supported models for export!
otherwise 🚀 ! Kudos
| test_mismatched_shapes = True | ||
| test_missing_keys = True | ||
| test_model_parallel = False | ||
| test_torch_exportable = False |
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.
It' s fine to have to as we want to reach 100% exportability no?
|
@qubvel Let me know the timeline. I can start working on e2e enablement by connecting these models to optimum-executorch once this PR merged. |
|
Hey @guangy10, going to finish this week! |
|
Nice work in bringing the torch.export coverage up. Are the export tests executed with torch==2.6.0? |
|
Hey @chrsmcgrr, yes we have 2.6.0 in CI. I have also run these tests with torch 2.5.0 locally |
|
run-slow: rt_detr_v2, dab_detr, beit, conditional_detr, deformable_detr, detr, swin2sr |
|
This comment contains run-slow, running the specified jobs: This comment contains run-slow, running the specified jobs: models: ['models/beit', 'models/conditional_detr', 'models/dab_detr', 'models/deformable_detr', 'models/detr', 'models/rt_detr_v2', 'models/swin2sr'] |
|
@qubvel While I'm working on lowering these vision models e2e to ExecuTorch in |
|
@qubvel Thanks for looping in the audio team! 👋 @eustlb, nice to e-meet you! I'm from PyTorch team at Meta. We've been collaborating with 🤗 to expand |
|
Hey @guangy10, nice to e-meet you too! It would be a pleasure to help 🤗 |
…gface#35124) * Add is_torch_greater_or_equal test decorator * Add common test for torch.export * Fix bit * Fix focalnet * Fix imagegpt * Fix seggpt * Fix swin2sr * Enable torch.export test for vision models * Enable test for video models * Remove json * Enable for hiera * Enable for ijepa * Fix detr * Fic conditional_detr * Fix maskformer * Enable test maskformer * Fix test for deformable detr * Fix custom kernels for export in rt-detr and deformable-detr * Enable test for all DPT * Remove custom test for deformable detr * Simplify test to use only kwargs for export * Add comment * Move compile_compatible_method_lru_cache to utils * Fix beit export * Fix deformable detr * Fix copies data2vec<->beit * Fix typos, update test to work with dict * Add seed to the test * Enable test for vit_mae * Fix beit tests * [run-slow] beit, bit, conditional_detr, data2vec, deformable_detr, detr, focalnet, imagegpt, maskformer, rt_detr, seggpt, swin2sr * Add vitpose test * Add textnet test * Add dinov2 with registers * Update tests/test_modeling_common.py * Switch to torch.testing.assert_close * Fix masformer * Remove save-load from test * Add dab_detr * Add depth_pro * Fix and test RT-DETRv2 * Fix dab_detr
What does this PR do?
Add a common slow test to check if a model can be exported with no issues using
torch.export.exporttest_torch_exportable = Trueflag for model-specific test.The main fixes include:
requires_grad=Truein the forward pass.Testing is not complete, there might be code paths that can't be exported. I did additional testing with specific checkpoints. In most cases, we are safe. The only two situations I found where tests pass but checkpoint export does not pass are:
Results
✅ - can be exported with
torch.export.export🔵 - export fixed in this PR
❌ - can't be exported
Vision models
Video models
Fixes # (issue)
Before submitting
Pull Request section?
to it if that's the case.
documentation guidelines, and
here are tips on formatting docstrings.
Who can review?
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag
members/contributors who may be interested in your PR.