Skip to content

Conversation

@andrewor14
Copy link
Contributor

Summary: FqnToConfig does not handle module swap configs like QATConfig today because it does not reassign the replaced modules, but instead assumes there is no need to do so because the underlying tensors are swapped. This breaks when the user tries to use FqnToConfig with QATConfig, which does not rely on tensor subclasses. This commit fixes this by making the replacement logic in FqnToConfig more general.

Fixes #3490.

Test Plan:

python test/quantization/test_quant_api.py -k test_fqn_config_quantized_nested_module_module_swap

@pytorch-bot
Copy link

pytorch-bot bot commented Dec 15, 2025

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/ao/3492

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

✅ You can merge normally! (1 Unrelated Failure)

As of commit 264b3c2 with merge base f3342a0 (image):

BROKEN TRUNK - The following job failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

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

@andrewor14 andrewor14 requested a review from jcaip December 15, 2025 22:22
@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 Dec 15, 2025
@andrewor14 andrewor14 added the topic: bug fix Use this tag for PRs that fix bugs label Dec 15, 2025
module.to(device=device)
return
if isinstance(config, AOBaseConfig):
_fqn_to_config_replace(config, model, device=device)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is hard to follow, would it be cleaner to use iteration instead of recursion here

or ("_default" in config.fqn_to_config and _is_linear(module))
):
# this replaces inplace, so no need to reassign
_fqn_to_config_handler(module, module_fqn, config)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can implement something like

def set_module_by_fqn(model, fqn, new_module):
    # set model[fqn] to new_module

so then we can keep it iterative? Only thing is that we have to get the modules in top-down order (this does appear to be how named_modules is implemented)

    for module_fqn, module in model.named_modules():
            if (
                fqn_matches_fqn_config(module_fqn, config)
                or _module_param_matches_fqn_config(module, module_fqn, config)
                or ("_default" in config.fqn_to_config and _is_linear(module))
            ):
                new_module = _fqn_to_config_handler(module, module_fqn, config)
                # reassign module
                set_module_by_fqn(model, fqn, new_module) 

**Summary:** `FqnToConfig` does not handle module swap configs
like `QATConfig` today because it does not reassign the replaced
modules, but instead assumes there is no need to do so because
the underlying tensors are swapped. This breaks when the user
tries to use `FqnToConfig` with `QATConfig`, which does not
rely on tensor subclasses. This commit fixes this by making
the replacement logic in `FqnToConfig` more general.

Fixes #3490.

**Test Plan:**
```
python test/quantization/test_quant_api.py -k test_fqn_config_quantized_nested_module_module_swap
```
@andrewor14
Copy link
Contributor Author

Rewrote using iteration, check again? @vkuzo @jcaip

@andrewor14 andrewor14 requested review from jcaip and vkuzo December 17, 2025 16:36
child_name = module_fqn.split(".")[-1]
parent_fqn = module_fqn.removesuffix(child_name).removesuffix(".")
parent_module = named_modules[parent_fqn]
setattr(parent_module, child_name, replacement)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we're missing a return here at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the next case to elif, is that OK?

Copy link
Contributor

Choose a reason for hiding this comment

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

oh missed that, yeah lgtm

@andrewor14
Copy link
Contributor Author

Test failure doesn't seem related, merging this. Thanks

@andrewor14 andrewor14 merged commit 1f9bfd7 into main Dec 17, 2025
20 of 21 checks passed
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. topic: bug fix Use this tag for PRs that fix bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FqnToConfig doesn't handle module swaps

3 participants