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

[ONNX] Introduce Input/Ouptut adapter; Switch to 'DynamoExporter' #98421

Closed
wants to merge 19 commits into from

Conversation

BowenBao
Copy link
Collaborator

@BowenBao BowenBao commented Apr 5, 2023

Stack from ghstack (oldest at bottom):

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 [Dynamo] Enable dynamo.export for huggingface models w/ ModelOutput #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.

@pytorch-bot
Copy link

pytorch-bot bot commented Apr 5, 2023

🔗 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 Pending

As of commit 73a01d0:
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@pytorch-bot pytorch-bot bot added the release notes: onnx torch.onnx related changes that should show up in the release notes label Apr 5, 2023
BowenBao added a commit that referenced this pull request Apr 5, 2023
ghstack-source-id: 39cc6e28980ebd06e249ec3c37e55330434dd2b6
Pull Request resolved: #98421
@BowenBao BowenBao added module: onnx Related to torch.onnx topic: new features topic category labels Apr 5, 2023
…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]
BowenBao added a commit that referenced this pull request Apr 5, 2023
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]
BowenBao added a commit that referenced this pull request Apr 6, 2023
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]
BowenBao added a commit that referenced this pull request Apr 6, 2023
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]
BowenBao added a commit that referenced this pull request Apr 6, 2023
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]
BowenBao added a commit that referenced this pull request Apr 6, 2023
ghstack-source-id: 24cf566f4a1dfff0e3828f63fc44168ec983b0ae
Pull Request resolved: #98421
@BowenBao BowenBao added the ciflow/trunk Trigger trunk jobs on your pull request label Apr 6, 2023
@BowenBao BowenBao marked this pull request as ready for review April 6, 2023 20:23
@BowenBao BowenBao requested a review from abock as a code owner April 6, 2023 20:23
…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]
BowenBao added a commit that referenced this pull request Apr 6, 2023
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]
BowenBao added a commit that referenced this pull request Apr 14, 2023
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]
@BowenBao BowenBao changed the title [ONNX] Introduce Input/Ouptut formatter; Switch to 'DynamoExporter' [ONNX] Introduce Input/Ouptut adapter; Switch to 'DynamoExporter' Apr 14, 2023
BowenBao added a commit that referenced this pull request Apr 14, 2023
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 "
Copy link
Collaborator

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?

Copy link
Collaborator Author

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. "
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

test/onnx/test_fx_to_onnx_with_onnxruntime.py Outdated Show resolved Hide resolved
return self.export_fx_to_onnx(compiler.captured_graph, model_args)


class _PyTreeExtensionContext:
Copy link
Collaborator

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(
Copy link
Collaborator

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.

Copy link
Collaborator Author

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]
BowenBao added a commit that referenced this pull request Apr 14, 2023
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]
titaiwangms added a commit that referenced this pull request Apr 17, 2023
…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]
titaiwangms added a commit that referenced this pull request Apr 17, 2023
… 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]
ZainRizvi pushed a commit that referenced this pull request Apr 19, 2023
…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
pytorchmergebot pushed a commit that referenced this pull request May 6, 2023
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
kiersten-stokes pushed a commit to kiersten-stokes/pytorch that referenced this pull request May 8, 2023
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
@facebook-github-bot facebook-github-bot deleted the gh/BowenBao/225/head branch June 8, 2023 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ciflow/trunk Trigger trunk jobs on your pull request Merged module: onnx Related to torch.onnx open source release notes: onnx torch.onnx related changes that should show up in the release notes topic: new features topic category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants