Skip to content

NXP backend: Create NeutronAtenPassManager with initial BatchNorm fusing passes #10579

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

skywall
Copy link
Contributor

@skywall skywall commented Apr 30, 2025

Summary

Add NeutronAtenPassManager that by default runs passes for optimal model conversion. Initially, only passes for BatchNorm + Conv/Linear fusing are added. I haven't intentionally moved passes into backend/transforms because added passes are executed on Aten ops and not Edge ops. Please let me know if I should follow different approach.

This pass manager is planned to be included in Neutron backend's pipeline - https://github.com/pytorch/executorch/pull/10196/files#diff-b3b0844670da322bb4c245ae440e8c71378d631bb94334148322cdf758369baaR51

cc @digantdesai @JakeStevens @robert-kalmar

Copy link

pytorch-bot bot commented Apr 30, 2025

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/10579

Note: Links to docs will display an error until the docs builds have been completed.

✅ No Failures

As of commit 5d69743 with merge base d7030aa (image):
💚 Looks good so far! There are no failures yet. 💚

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

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 30, 2025
@skywall
Copy link
Contributor Author

skywall commented Apr 30, 2025

@pytorchbot label "module: nxp" "release notes: nxp"

@pytorch-bot pytorch-bot bot added module: nxp Issues related to NXP Neutron NPU delegation and code under backends/nxp/ release notes: nxp Changes to the NXP Neutron backend delegate labels Apr 30, 2025

bn_node = node

if not _is_linear(bn_node.args[0]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and above, you can be defensive and also make sure args len == 1. there is nothing stopping someone from adding a skip connection after conv/linear and before batchnorm, or some other op. Can't say i've seen it in practice though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added check for number of users of Conv/Linear op.


import torch

from executorch.backends.nxp.aten_passes.fuse_batch_norm_with_conv_pass import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can become unwieldly since there are a few other permutations of "batch norm" fusion, maybe just one file for fuse_batch_norm would be good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with you. Maybe we can create subdirectories in backend/transforms based on what dialect/ir is pass targeting?

@JakeStevens
Copy link
Contributor

LGTM but @digantdesai thoughts on the aten pass setup?

@skywall skywall changed the title [Neutron] Create NeutronAtenPassManager with initial BatchNorm fusing passes NXP backend: Create NeutronAtenPassManager with initial BatchNorm fusing passes May 2, 2025
@skywall skywall force-pushed the feature/nxf93343/neutron-batch-norm-fusion-passes branch from d1913ae to 5d69743 Compare May 2, 2025 12:06
@skywall
Copy link
Contributor Author

skywall commented May 2, 2025

I have also disabled some tests that require changes from #10258 . We'll update PR that will be merged last.

program = torch.export.export_for_training(module, example_input, strict=True)
og_module = program.module()

pm = NeutronAtenPassManager()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why does it have to be before export? Typically this is done in neutron.preprocess(). The reason is, it is not easy to run these nodes if Neutron partitioner fails to pick them up. There are several examples of this in Arm, XNNPACK etc.

class FuseBatchNormWithLinearPass(PassBase):
"""The executorch batch normalization carries out the following computation [1].

(x - mean) / (var + eps) * W + B
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(x - mean) / (var + eps) * W + B
(x - mean) / sqrt(var + eps) * W + B

from torch.fx import GraphModule, Node
from torch.fx.passes.infra.pass_base import PassBase, PassResult
from torch.nn.parameter import Parameter
from torch.nn.utils import fuse_conv_bn_weights
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glad you are using this as is

conv_args.append(None)

weight_attr_name = conv_weight_node.target
_assign_attr(
Copy link
Contributor

@digantdesai digantdesai May 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do this without using internal methods, and insert new params and delete old params https://github.com/pytorch/executorch/blob/main/backends/transforms/utils.py#L65 (assuming you are doing this after export)

assert np.allclose(out1, out2, atol=1.2e-7)


# TODO - enable within PR #10196
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move it to that PR?

Copy link
Contributor

@digantdesai digantdesai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, if we can move this either in NeutronQuantizer.transform_for_annotation (unless you are waiting for the other PR) with or move to Neutron.Preprocess it will be ready to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: nxp Issues related to NXP Neutron NPU delegation and code under backends/nxp/ release notes: nxp Changes to the NXP Neutron backend delegate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants