Repository navigation
[XNNPACK] Delegate GEMMs whose weight is computed from parameters - #24352
Open
JakeStevens wants to merge 1 commit into
Open
JakeStevens wants to merge 1 commit into
JakeStevens wants to merge 1 commit into
Conversation
A convolution, linear, addmm or mm whose weight or bias is computed from parameters, such as a convolution under weight_norm or spectral_norm, was declined by the XNNPACK partitioner and ran on the portable kernels together with the computation of its weight. The GEMM configs now accept such a weight or bias when it is computed with pure ops from parameters, unmutated buffers or constants, the computation feeds only that GEMM, and the folded tensor is no larger than the parameters it replaces. The computation is partitioned with the GEMM, and FoldComputedParamsPass folds it into a constant at the start of XNNPACK preprocess, inside the delegate, so the top-level program is not modified. AddmmConfig now also rejects addmm with non-default alpha or beta, which the XNNPACK lowering ignored. Fixes pytorch#22078 This change was authored with Claude Code.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24352
Note: Links to docs will display an error until the docs builds have been completed. This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #22078
The XNNPACK partitioner requires a GEMM's weight and bias to be static params. A convolution, linear, addmm or mm whose weight is computed from parameters is declined, and it runs on the portable kernels together with the computation of its weight.
torch.nn.utils.parametrizations.weight_normandspectral_normproduce exactly this graph, and they are common in audio models; the issue measured 941x on wav2vec2's positional convolution.This is a smaller alternative to #22391 and #23154, which fold parameter-only subgraphs in
transform_for_pre_decomposition. Folding there rewrites the shared ATen program, before functionalization and before every other partitioner and method sees it. Here the top-level program is not modified.get_static_param_depslets a GEMM config accept a weight or bias computed with pure ops from parameters, unmutated buffers or constants. It partitions that computation together with the GEMM and tags it, andFoldComputedParamsPass, the first XNNPACK preprocess pass, folds it into a constant inside the delegate. After the fold, the delegate looks exactly as if the weight had been a parameter, and the named data store's content hashes deduplicate identical folds across methods.The partitioner only accepts a computation that the fold can replace outright without growing the program. Only the folded tensor and its source parameters may be used outside the computation, and only by that GEMM. The folded tensor may be no larger than the parameters it frees, and sources tagged for an external data file are left alone. A computation shared by several GEMMs is therefore not folded, such as the packed bias split across three linears in #23154; delegating it would require merging those GEMMs into one partition, which can create a cycle. Tags are set while a GEMM is being checked, before it is accepted, so the pass folds a tagged node only when one of the GEMMs that tagged it is in the same delegate. As with a buffer used directly as a weight today, a buffer that only another method writes is treated as constant.
AddmmConfignow also rejects addmm with non-defaultalphaorbeta, which the XNNPACK lowering ignored. On main,torch.addmm(b, x, w, alpha=2, beta=3)with parameterswandbis delegated and returns wrong results.Suggested review order:
get_static_param_depsinbackends/xnnpack/utils/utils.py, its two call sites ingemm_configs.py, thenfold_computed_params.py.wav2vec2
pos_conv,weight_norm(Conv1d(1024, 1024, 128, padding=64, groups=16), dim=2)on its own at sequence length 499, synthetic weights, macOS arm64, median of 5 runs after 2 warm-up runs:pow,sum,convolutionThe
.pteis 1,280 bytes smaller: one folded weight replacesweight_gandweight_v, and the program has one delegate instead of two.Test plan
python -m pytest backends/xnnpack/test/passes/test_fold_computed_params.pyThe new tests lower a weight_norm Conv1d and a linear with a computed weight and bias, run them through the runtime against eager, and check that nothing is left outside the delegate. They also check what must not fold: a source used elsewhere, a mutated buffer, a low-rank product that would grow the program, a source that stays another input of the GEMM, an intermediate that also feeds the GEMM, and sources tagged for an external file. A rejected convolution whose weight is computed by a delegated matmul, and a weight computed by an earlier partitioner's delegate, still export and match eager. A param that already has the folded weight's name is not replaced, and a scaled addmm stays on portable and matches eager.
python -m pytest backends/xnnpack/test/passes backends/xnnpack/test/ops backends/xnnpack/test/serialization backends/xnnpack/test/quantizer backends/xnnpack/test/test_xnnpack_partitioner.py -o addopts=""This includes
test_linear.py,test_bmm.pyand the quantizer tests, whichpytest.iniskips. The failures are the same as on main: three qd8 int4 linear tests, and quantizer tests that fail depending on run order. I also compared against main for weight_norm on Linear, Conv2d, depthwise and transposed convolutions, spectral_norm, a dynamic sequence length, and two methods sharing a folded weight. Tied embeddings, packed biases and low-rank weights produce the same.pteas on main.This PR was authored with Claude Code.