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
[ONNX] Introduce Input/Ouptut adapter; Switch to 'DynamoExporter' #98421
Conversation
[ghstack-poisoned]
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/98421
Note: Links to docs will display an error until the docs builds have been completed. ⏳ No Failures, 2 PendingAs of commit 73a01d0: This comment was automatically generated by Dr. CI and updates every 15 minutes. |
ghstack-source-id: 39cc6e28980ebd06e249ec3c37e55330434dd2b6 Pull Request resolved: #98421
…matter; Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 15b53c15756e096c844f01764ebae0a55ca57996 Pull Request resolved: #98421
…t formatter; Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 35aa14ab11fd80f46557880e3f30fbcc686d7bf4 Pull Request resolved: #98421
…uptut formatter; Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 417f3a993252b55823ff6597dd6817a0c663b5f0 Pull Request resolved: #98421
… Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: f7d6e5b42843e96f93a196b31a34623d45aba8f1 Pull Request resolved: #98421
…namoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 24cf566f4a1dfff0e3828f63fc44168ec983b0ae Pull Request resolved: #98421
…Exporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: cfd74b3d586468ec1c026c8c3dc62fb50ff6cae5 Pull Request resolved: #98421
…Exporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
…er; Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 8ff147e1094f5943ed04dd462be88c42d892df08 Pull Request resolved: #98421
…duce Input/Ouptut formatter; Switch to 'DynamoExporter'" Summary * Introduce input/output formatter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output formatter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: c89f1cda4c217bb1cd593c13993eedf0c1e72b6a Pull Request resolved: #98421
DynamoExporter: ( | ||
"beartype.roar.BeartypeCallHintReturnViolation: @beartyped " | ||
"torch.onnx._internal.exporter.ExportOutput.adapt_torch_inputs_to_onnx() " | ||
"return (tensor([[[ 1.5410, -0.2934]]]), 8.0) violates type hint " |
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.
Could we change type Hint to Union[torch.Tensor, int, float, bool]
and have these built-in converted to constant tensors during onnx 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.
We can, it can happen in follow ups though. I'm unsure yet if we'd need adjustments on fx_to_onnx conversion pass, so don't want to extend the scope of this PR.
"instance of <protocol 'torch.Tensor'>." | ||
), | ||
DynamoOptimizeExporter: ( | ||
"RuntimeError: The two modules have different number of 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.
Is there a reason the input/output adapter cannot handle this?
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.
Same as the other reply.
return self.export_fx_to_onnx(compiler.captured_graph, model_args) | ||
|
||
|
||
class _PyTreeExtensionContext: |
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.
Not for this PR, this almost feels like deserving a deeper discussion.
If Dynamo cannot support custom types, maybe we could propose an interface for users to register any custom data type, so that exporter knows how to serialize? We can do that at dynamo or exporter context, probably? In fact, we discussed this idea in the past for the torchscript exporter.
self._input_adapter.append_step(adapt_step) | ||
return adapt_step.adapt(model_args, model_kwargs) | ||
|
||
def _apply_output_adapt_step( |
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 could move all these adapters to a file of its own and declutter the exporter class files.
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 for follow ups
…witch to 'DynamoExporter'" Summary * Introduce input/output adapter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output adapter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
ghstack-source-id: 0ec4f87e1b5ddb0f774b3da90c467377a42a9a68 Pull Request resolved: #98421
…porter'" Summary * Introduce input/output adapter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output adapter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
…porter'" Summary * Introduce input/output adapter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output adapter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. [ghstack-poisoned]
…amo API usage in fx exporter" Before this PR, dynamo API is not passed in the options.dynamic_shapes leading to a potential static capture in the very begining. After this PR (from dynamo.optimize): ``` def forward(self, L_x_ : torch.Tensor): l_x_ = L_x_ # File: /home/titaiwang/pytorch/test/onnx/test_fx_to_onnx_with_onnxruntime.py:442, code: results.append(x[: x.size(0) - i, i : x.size(2), i:3]) size = l_x_.size(0) sub = size - 0; size = None size_1 = l_x_.size(2) getitem = l_x_[(slice(None, sub, None), slice(0, size_1, None), slice(0, 3, None))]; sub = size_1 = None size_2 = l_x_.size(0) sub_1 = size_2 - 1; size_2 = None size_3 = l_x_.size(2) getitem_1 = l_x_[(slice(None, sub_1, None), slice(1, size_3, None), slice(1, 3, None))]; sub_1 = size_3 = None size_4 = l_x_.size(0) sub_2 = size_4 - 2; size_4 = None size_5 = l_x_.size(2) getitem_2 = l_x_[(slice(None, sub_2, None), slice(2, size_5, None), slice(2, 3, None))]; sub_2 = size_5 = None size_6 = l_x_.size(0) sub_3 = size_6 - 3; size_6 = None size_7 = l_x_.size(2) getitem_3 = l_x_[(slice(None, sub_3, None), slice(3, size_7, None), slice(3, 3, None))]; l_x_ = sub_3 = size_7 = None return (getitem, getitem_1, getitem_2, getitem_3) ``` Wait #98421 to test tracing_mode="symbolic" in `DynamoExportExporter` [ghstack-poisoned]
… fx exporter" Before this PR, dynamo API is not passed in the options.dynamic_shapes leading to a potential static capture in the very begining. After this PR (from dynamo.optimize): ``` def forward(self, L_x_ : torch.Tensor): l_x_ = L_x_ # File: /home/titaiwang/pytorch/test/onnx/test_fx_to_onnx_with_onnxruntime.py:442, code: results.append(x[: x.size(0) - i, i : x.size(2), i:3]) size = l_x_.size(0) sub = size - 0; size = None size_1 = l_x_.size(2) getitem = l_x_[(slice(None, sub, None), slice(0, size_1, None), slice(0, 3, None))]; sub = size_1 = None size_2 = l_x_.size(0) sub_1 = size_2 - 1; size_2 = None size_3 = l_x_.size(2) getitem_1 = l_x_[(slice(None, sub_1, None), slice(1, size_3, None), slice(1, 3, None))]; sub_1 = size_3 = None size_4 = l_x_.size(0) sub_2 = size_4 - 2; size_4 = None size_5 = l_x_.size(2) getitem_2 = l_x_[(slice(None, sub_2, None), slice(2, size_5, None), slice(2, 3, None))]; sub_2 = size_5 = None size_6 = l_x_.size(0) sub_3 = size_6 - 3; size_6 = None size_7 = l_x_.size(2) getitem_3 = l_x_[(slice(None, sub_3, None), slice(3, size_7, None), slice(3, 3, None))]; l_x_ = sub_3 = size_7 = None return (getitem, getitem_1, getitem_2, getitem_3) ``` Wait #98421 to test tracing_mode="symbolic" in `DynamoExportExporter` [ghstack-poisoned]
…8421) Summary * Introduce input/output adapter. Due to design differences, input/output format between PyTorch model and exported ONNX model are often not the same. E.g., `None` inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX, etc. The new input/output adapter is exported with the model. Providing an interface to automatically convert and validate inputs/outputs format. * As suggested by #98251, provide extension for unwrapping user defined python classes for `dynamo.export` based exporter. Unblock huggingface models. * Re-wire tests to run through `DynamoExporter` w/ `dynamo_export` api. Kept `DynamoOptimizeExporter` in the tests for now for coverage of this change. Pull Request resolved: #98421 Approved by: https://github.com/justinchuby, https://github.com/titaiwangms, https://github.com/thiagocrepaldi
This PR refactors how InputAdapter and OutputAdapter is used throughout the exporter. During refactoring, API issues with passes (torch.onnx._internal.fx._pass.Transform) were identified and should be tackled on another API. In short, some passes can modify the input/output of the model and the input/output adapter must be in sync with such change, otherwise, the adapters will not reflect the actual model input/output. The first instance of this issue was with `ReplaceGetAttrWithPlaceholder` pass that adds new inputs to the model. In order to work this around, a new input adapt step to append new inputs (generated by the pass) was introduced. That resulted in the number of inputs of the ONNX model to mismatch the numer of inputs of the pytorch model, though. Follow up on #98421 Pull Request resolved: #100490 Approved by: https://github.com/BowenBao
This PR refactors how InputAdapter and OutputAdapter is used throughout the exporter. During refactoring, API issues with passes (torch.onnx._internal.fx._pass.Transform) were identified and should be tackled on another API. In short, some passes can modify the input/output of the model and the input/output adapter must be in sync with such change, otherwise, the adapters will not reflect the actual model input/output. The first instance of this issue was with `ReplaceGetAttrWithPlaceholder` pass that adds new inputs to the model. In order to work this around, a new input adapt step to append new inputs (generated by the pass) was introduced. That resulted in the number of inputs of the ONNX model to mismatch the numer of inputs of the pytorch model, though. Follow up on pytorch#98421 Pull Request resolved: pytorch#100490 Approved by: https://github.com/BowenBao
Stack from ghstack (oldest at bottom):
Summary
between PyTorch model and exported ONNX model are often not the same. E.g.,
None
inputs are allowed for PyTorch model, but are not supported by ONNX. Nested constructs
of tensors are allowed for PyTorch model, but only flattened tensors are supported by ONNX,
etc. The new input/output adapter is exported with the model. Providing an interface to
automatically convert and validate inputs/outputs format.
dynamo.export
for huggingface models w/ModelOutput
#98251,provide extension for unwrapping user defined python classes for
dynamo.export
basedexporter. Unblock huggingface models.
DynamoExporter
w/dynamo_export
api. KeptDynamoOptimizeExporter
in the tests for now for coverage of this change.