Skip to content

Arm backend: Make composable_quantizer default#19758

Merged
AdrianLundell merged 14 commits into
pytorch:mainfrom
AdrianLundell:change-1253855
Jul 16, 2026
Merged

Arm backend: Make composable_quantizer default#19758
AdrianLundell merged 14 commits into
pytorch:mainfrom
AdrianLundell:change-1253855

Conversation

@AdrianLundell

@AdrianLundell AdrianLundell commented May 25, 2026

Copy link
Copy Markdown
Collaborator

A few fixes needed:

  • Add new ops added since initial upstream of composable_quantizer
  • Add while-op quantize fix from 3be4546 to TosaQuantizerV2
  • Add fixed_qparams fix from fb90480 to TosaQuantizerV2
  • Update some tests to mirror new behaviours
  • Update quanitzer_tutorial to not be WIP
  • Remove hardsigmoid from FUSED_ACTIVATION_OPS
  • Explicitly check that weights and biases are input args to conv/ linear ops. The assumption that wights and biases are the only parameters of networks does not hold for real models.

cc @digantdesai @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani

A few fixes needed:
- Add new ops added since initial upstream of composable_quantizer
- Add while-op quantize fix from 3be4546 to TosaQuantizerV2
- Add fixed_qparams fix from fb90480 to TosaQuantizerV2
- Update some tests to mirror new behaviours
- Update quanitzer_tutorial to not be WIP
- Remove hardswish from FUSED_ACTIVATION_OPS
- Explicitly check that weights and biases are input args to
  conv/ linear ops. The assumption that wights and biases are
  the only parameters of networks does not hold for real models.

Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: Ifa127a73d4db45cd2d3461101f97c0cf852bf7bf
@AdrianLundell
AdrianLundell requested review from 3l1 and Copilot May 25, 2026 15:05
@AdrianLundell AdrianLundell added help wanted Extra attention is needed partner: arm For backend delegation, kernels, demo, etc. from the 3rd-party partner, Arm ciflow/trunk release notes: arm Changes to the ARM backend delegate labels May 25, 2026
@pytorch-bot

pytorch-bot Bot commented May 25, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

✅ No Failures

As of commit 130f60b with merge base e182e8b (image):
💚 Looks good so far! There are no failures yet. 💚

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

@meta-cla meta-cla 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 May 25, 2026
@linux-foundation-easycla

linux-foundation-easycla Bot commented May 25, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

@github-actions github-actions Bot added the module: arm Issues related to arm backend label May 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR switches the Arm backend’s TOSAQuantizer to use the composable quantizer implementation by default, and updates Arm quantization annotation/support logic plus tests/tutorial materials to match the new behaviors (including while-loop and fixed-qparams handling).

Changes:

  • Make TOSAQuantizer default to use_composable_quantizer=True.
  • Extend/update quantizer support + annotation behavior (e.g., while-loop shared-qspec handling, fixed-qparams input qspecs for trig ops, additional supported ops).
  • Update Arm backend tests and the Arm quantizer tutorial notebook to reflect the new defaults/behaviors.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
examples/arm/quantizer_tutorial.ipynb Removes WIP framing in the composable quantizer tutorial intro.
backends/arm/test/ops/test_while.py Adds an INT while-loop test path forcing composable quantizer usage.
backends/arm/test/ops/test_transpose_conv2d.py Updates tests to use TOSAQuantizationConfig for global config setup.
backends/arm/test/ops/test_to_copy.py Simplifies redundant-cast xfail configuration shared between FP/INT.
backends/arm/test/misc/test_shared_qspecs.py Updates golden expectations for shared-qspec annotation counts/qparams.
backends/arm/test/misc/test_quant_custom_meta.py Adjusts test quantizer config (including set_io(None)) to match new behavior.
backends/arm/quantizer/quantizer_support.py Updates supported/fused patterns (and adds more supported ops).
backends/arm/quantizer/quantization_config.py Adds fixed-qparams input spec generation for specific trig ops under composable flow.
backends/arm/quantizer/arm_quantizer.py Makes composable quantizer the default for TOSAQuantizer.
backends/arm/quantizer/arm_quantizer_utils.py Tightens weight/bias identification and adds while-loop shared-qspec special-casing; extends shared-qspec op list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backends/arm/quantizer/arm_quantizer.py
Comment thread backends/arm/quantizer/quantizer_support.py
Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: I75e207d010b2bdc9abc86023153c86d2c96af3fd
@meta-codesync

meta-codesync Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

@rascani has imported this pull request. If you are a Meta employee, you can view this in D106381887.

@rascani

rascani commented May 26, 2026

Copy link
Copy Markdown
Contributor

Kicking off an internal test run.

@rascani

rascani commented May 26, 2026

Copy link
Copy Markdown
Contributor

It looks like the new quantizer breaks examples/models/llama/tests/test_export_llama_lib.py, because of asserts on quantizer.module_type_config, which is not implemented by the new quantizer. I think we should probably just remove those asserts in the tests unless you want to expose the module type config in the new quantizer.

https://github.com/pytorch/executorch/blob/main/examples/models/llama/tests/test_export_llama_lib.py#L121

…tream/change-1253855

Change-Id: I86bc8025e41175a796fa0ff7aabc9847b1de923a
These configs does not exist in the new quantizer, so checking it
does not make sense anymore.

Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: Ic6c0b303466010be59e9c9c37fb179938c412a16
Copilot AI review requested due to automatic review settings May 27, 2026 08:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Comment thread backends/arm/quantizer/arm_quantizer_utils.py
Comment on lines +308 to +321
elif node.target in _fixed_input_qspec_ops:

input_act_qspec = super().get_input_act_qspec(node, input_node)
num_bits = torch.iinfo(input_act_qspec.dtype).bits
qparams = _fixed_input_qspec_ops[node.target][num_bits]
return FixedQParamsQuantizationSpec(
dtype=input_act_qspec.dtype,
scale=qparams.scale,
zero_point=qparams.zero_point,
quant_min=input_act_qspec.quant_min,
quant_max=input_act_qspec.quant_max,
qscheme=input_act_qspec.qscheme,
is_dynamic=input_act_qspec.is_dynamic,
)
Comment thread docs/source/backends/arm-vgf/arm-vgf-quantization.md Outdated
Comment thread docs/source/backends/arm-ethos-u/arm-ethos-u-quantization.md Outdated
Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: I7760780d4f06e300f17575e7c6cb34c6dfdae64c
@rascani

rascani commented May 27, 2026

Copy link
Copy Markdown
Contributor

Kicking off another internal run.

@digantdesai

digantdesai commented May 27, 2026

Copy link
Copy Markdown
Contributor

FYI @3l1 - not sure if you saw this.

@digantdesai

Copy link
Copy Markdown
Contributor

From @rascani 's internal CI runs,

executorch/backends/arm/quantizer/arm_quantizer.py", line 522, in global_config
    raise NotImplementedError(
NotImplementedError: Composable quantizer does not allow setting global_config directly. Please use set_global() instead.

These should be forward fixed.

@rascani

rascani commented May 27, 2026

Copy link
Copy Markdown
Contributor

From @rascani 's internal CI runs,

executorch/backends/arm/quantizer/arm_quantizer.py", line 522, in global_config
    raise NotImplementedError(
NotImplementedError: Composable quantizer does not allow setting global_config directly. Please use set_global() instead.

These should be forward fixed.

I already have these fixed in D106539874. I'll land it ahead of time so the default switch can be a no-op.

Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: Ib6fefa3ba308d955b46e23095633f54df8ed3bf0
@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

@rascani Which setter-removal do you mean? I don't think setting the config from a dict has been the intended API, setting it using the setter functions should be intact.

@rascani

rascani commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@rascani Which setter-removal do you mean? I don't think setting the config from a dict has been the intended API, setting it using the setter functions should be intact.

We hit many of the NotImplementedError exceptions in this block:

def global_config(self, value: Optional[QuantizationConfig]) -> None:
if isinstance(self.quantizer, _TOSAQuantizerV1):
self.quantizer.global_config = value
else:
raise NotImplementedError(
"Composable quantizer does not allow setting global_config directly. Please use set_global() instead."
)
@property
def io_config(self):
if isinstance(self.quantizer, _TOSAQuantizerV1):
return self.quantizer.io_config
else:
raise NotImplementedError(
"Composable quantizer does not allow accessing io_config."
)
@io_config.setter
def io_config(self, value: Optional[QuantizationConfig]) -> None:
if isinstance(self.quantizer, _TOSAQuantizerV1):
self.quantizer.io_config = value
else:
raise NotImplementedError(
"Composable quantizer does not allow setting io_config directly. Please use set_io() instead."
)
@property
def module_type_config(self):
if isinstance(self.quantizer, _TOSAQuantizerV1):
return self.quantizer.module_type_config
else:
raise NotImplementedError(
"Composable quantizer does not allow accessing module_type_config."
)
@module_type_config.setter
def module_type_config(
self, value: Dict[Callable, Optional[QuantizationConfig]]
) -> None:
if isinstance(self.quantizer, _TOSAQuantizerV1):
self.quantizer.module_type_config = value
else:
raise NotImplementedError(
"Composable quantizer does not allow setting module_type_config directly. Please use set_module_type() instead."
)
@property
def module_name_config(self):
if isinstance(self.quantizer, _TOSAQuantizerV1):
return getattr(self.quantizer, "module_name_config", {})
else:
raise NotImplementedError(
"Composable quantizer does not allow accessing module_name_config."
)
@module_name_config.setter
def module_name_config(
self, value: Dict[str, Optional[QuantizationConfig]]
) -> None:
if isinstance(self.quantizer, _TOSAQuantizerV1):
self.quantizer.module_name_config = value
else:
raise NotImplementedError(
"Composable quantizer does not allow setting module_name_config directly. Please use set_module_name() instead."
)

@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

I would recommend replacing accessing e.g. module_name_config directly with using the official set_module_name setter API in that case, does that resolve the issue?

@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

I realize we could also make a setter which takes the dict and calls set_module_name on all entries to have no breakage, would that help?

…tream/change-1253855

Change-Id: I2c920401d797530b7bab6189941636e1b2035de1
…tream/change-1253855

Change-Id: I931de7467e5697c3a15420913e4b68a8e088a8b4
Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: I9c8dc4e9690d591a286ad22376c509babfb24c0e

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread backends/arm/quantizer/arm_quantizer_utils.py Outdated
Comment thread backends/arm/quantizer/arm_quantizer_utils.py
…tream/change-1253855

Change-Id: I719898b5ea2056d5ab8e9723fb41f612de8e04e1
Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: I39fd172f326909a084c8dc87613ed02d2032963d
@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

I had to take a break from this one, but now you should be able to set quantization specs from dicts as you are used to @rascani.

@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

Look like the quantizers have diverged again, I will fix in a separate commit.

@digantdesai

Copy link
Copy Markdown
Contributor

Still blocked on us, sorry.

@digantdesai digantdesai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review automatically exported from Phabricator review in Meta.

…tream/quantizer

Change-Id: Ieb92342ab40135764270031d19e80a752595d96d
- Annotate IO with none for non supported nonzero operator
- Ensure while cast node is created with a unique meta dict
  to avoid corrupted quantization annotations

Signed-off-by: Adrian Lundell <adrian.lundell@arm.com>
Change-Id: I22e4759cef7cff79f6dce26f147012f01d0d4883
@AdrianLundell
AdrianLundell merged commit 432353a into pytorch:main Jul 16, 2026
504 of 506 checks passed
@zingo

zingo commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Yeah!

@digantdesai

Copy link
Copy Markdown
Contributor

Review automatically exported from Phabricator review in Meta.

sorry error on my part. Let me revert.

@AdrianLundell

Copy link
Copy Markdown
Collaborator Author

I see, when would you say this will be unblocked and can I make any updates to make it easier? @digantdesai

@rascani

rascani commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

I see, when would you say this will be unblocked and can I make any updates to make it easier? @digantdesai

We had a bit of a race condition with an internal change. Barring no surprises, I am hoping to reland this today.

@rascani

rascani commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

I see, when would you say this will be unblocked and can I make any updates to make it easier? @digantdesai

We had a bit of a race condition with an internal change. Barring no surprises, I am hoping to reland this today.

🤞 I think we should be good now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/trunk CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. help wanted Extra attention is needed module: arm Issues related to arm backend partner: arm For backend delegation, kernels, demo, etc. from the 3rd-party partner, Arm release notes: arm Changes to the ARM backend delegate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants