Skip to content

Select perturbed values without arithmetic masking (#1921) - #1921

Open
craymichael wants to merge 2 commits into
meta-pytorch:masterfrom
craymichael:export-D117601315
Open

craymichael wants to merge 2 commits into
meta-pytorch:masterfrom
craymichael:export-D117601315

Conversation

@craymichael

@craymichael craymichael commented Aug 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

Summary

Perturbation paths combined original and replacement values as old * (1 - mask) + new * mask. IEEE arithmetic makes NaN * 0 and Inf * 0 non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input [1, 2], baseline [0, NaN], and mask [0, 1], ablating feature 0 should evaluate [0, 2]. Arithmetic masking instead produced [0, NaN], so feature 0 incorrectly received a NaN attribution.

Fix

  • Use torch.where for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
  • Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
  • Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
  • Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (Pass 159, Fail 6).

After:

  • buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation — Pass 178, Fail 0.
  • Regressions cover NaN, +Inf, and -Inf in selected and inactive positions.
  • arc lint -a on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
  • arc lint -a --engine extra --take CITRINEAGENT on implementation files — no issues.
  • arc pyre check-owning-targets on changed files — no type errors.

Differential Revision: D117601315

@meta-codesync

meta-codesync Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

@craymichael has exported this pull request. If you are a Meta employee, you can view the originating Diff in D117601315.

craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
@meta-codesync meta-codesync Bot changed the title Select perturbed values without arithmetic masking Aug 28, 2026
craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Aug 28, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Sep 11, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Sep 15, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Sep 15, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
Summary:

Summary

Feature Ablation and Shapley formatted baselines but did not validate tuple arity or tensor shape before running the model. `_tensorize_baseline` also paired inputs and baselines with `zip`, silently discarding extra baselines.

Problem

For two inputs, a one-element baseline tuple reached the model with a missing argument, while a three-element tuple silently ignored its final baseline. A baseline pool with shape `[2, 1]` for a three-row input was neither a per-example baseline nor a singleton baseline and failed later through opaque broadcasting errors.

Fix

* Validate baselines in both synchronous and future Feature Ablation and Shapley entry points.
* Defensively reject arity mismatches in `_tensorize_baseline`.
* Require Shapley tensor baselines to match the input or use a singleton leading dimension with matching trailing dimensions.
* Preserve Feature Ablation’s documented support for any tensor shape that broadcasts exactly to the input, including `[F]` and 0-D tensors.

Test Plan

Before: the new regressions failed through late `IndexError`, missing-forward-argument, and broadcast errors; the extra-baseline case did not raise at all.

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_common fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_shapley` — Pass 131, Fail 0.
* `arc lint -a` on changed Python files — no source lint issues; focused autodeps updates applied.
* `arc lint -a --engine extra --take CITRINEAGENT` on changed Captum implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601314
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315
craymichael added a commit to craymichael/captum that referenced this pull request Sep 15, 2026
Summary:

Summary

Perturbation paths combined original and replacement values as `old * (1 - mask) + new * mask`. IEEE arithmetic makes `NaN * 0` and `Inf * 0` non-finite, so values outside the selected feature could corrupt model inputs and attributions.

Counterexample

For input `[1, 2]`, baseline `[0, NaN]`, and mask `[0, 1]`, ablating feature 0 should evaluate `[0, 2]`. Arithmetic masking instead produced `[0, NaN]`, so feature 0 incorrectly received a `NaN` attribution.

Fix

* Use `torch.where` for Feature Ablation, Feature Permutation, Shapley feature updates, and attribution-mask accumulation.
* Apply the same selection semantics to within-group baseline construction, add-back, and permutation helpers.
* Mirror the fix in the legacy UFO implementations so alternate call paths cannot retain the corruption.
* Keep masks and donor indices on the destination tensor device.

Test Plan

Before: six focused regressions failed across core and within-group paths (`Pass 159, Fail 6`).

After:
* `buck test fbcode//pytorch/captum/tests/attr:test_feature_ablation fbcode//pytorch/captum/tests/attr:test_feature_permutation fbcode//pytorch/captum/tests/attr:test_shapley fbcode//pytorch/captum/tests/attr/fb:test_within_groups_utils fbcode//pytorch/captum/tests/attr/fb:test_shapley_value_permutation` — Pass 178, Fail 0.
* Regressions cover `NaN`, `+Inf`, and `-Inf` in selected and inactive positions.
* `arc lint -a` on all changed Python files — no new lint issues; existing legacy UFO line-length advice remains unchanged.
* `arc lint -a --engine extra --take CITRINEAGENT` on implementation files — no issues.
* `arc pyre check-owning-targets` on changed files — no type errors.

Differential Revision: D117601315

This branch has not been deployed

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

1 participant