-
Notifications
You must be signed in to change notification settings - Fork 797
Support un-fused batchnorm1d/2d on XNNPACK via decomposition #16533
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
base: main
Are you sure you want to change the base?
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/16533
Note: Links to docs will display an error until the docs builds have been completed. ❌ 3 New Failures, 1 Unrelated FailureAs of commit 1aa7400 with merge base 3dd80c1 ( NEW FAILURES - The following jobs have failed:
UNSTABLE - The following job is marked as unstable, possibly due to flakiness on trunk:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@GregoryComer has exported this pull request. If you are a Meta employee, you can view the originating Diff in D90422630. |
…#16533) Summary: Add a new pass - DecomposeBatchNorm - which converts standalone (non-fused) batch norm operators to 1x1 depthwise convolution. This prevents delegation graph breaks when batch norm operators can't be fused. Differential Revision: D90422630
ddd4c1e to
1aa7400
Compare
| """ | ||
|
|
||
| # See https://docs.pytorch.org/docs/stable/generated/torch.nn.BatchNorm1d.html | ||
| denom = torch.sqrt(running_var + torch.Tensor([eps])) |
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.
torch.Tensor([eps]) won't preserve the dtype of running_var. You can do something like:
eps_t = running_var.new_tensor(eps)
denom = torch.sqrt(running_var + eps_t)
|
|
||
| # Compute the equivalent per-channel weights and biases. | ||
| # Note that the batch norm node args are | ||
| # (input, gamma, beta, running_mean, running_var, [training], momentum, eps). |
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.
check that training is False
| # BatchNorm weights have shape [in_c]. | ||
| # So we just need to unsqueeze the [in_c] to to [in_c, 1, 1, [1]]. | ||
| input_meta = bn_node.args[0].meta["val"] | ||
| channel_count = input_meta.shape[1] |
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 it's channels-last, we should also return early?
| from executorch.backends.xnnpack.test.tester import Tester | ||
|
|
||
|
|
||
| class TestBatchNorm(unittest.TestCase): |
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 like you're testing the no_training variant. Test the other variant too
- Add negative tests too
| .to_edge() | ||
| .check_count({self.bn_name: 1}) | ||
| .run_passes(self.PassStage) | ||
| .check_count({self.conv_name: 1}) |
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.
can you check that conv is in fact depthwise conv with 1×1 kernel?
Summary: Add a new pass - DecomposeBatchNorm - which converts standalone (non-fused) batch norm operators to 1x1 depthwise convolution. This prevents delegation graph breaks when batch norm operators can't be fused.
Differential Revision: D90422630
cc @digantdesai @cbilgin