Skip to content

Conversation

@ProGamerGov
Copy link
Owner

No description provided.

vivekmig and others added 30 commits October 25, 2023 11:43
Summary:
Adds CNAME file to website static files and removes other mentions of CircleCI and replaces with Github actions

Pull Request resolved: meta-pytorch#1198

Reviewed By: aobo-y

Differential Revision: D50657283

Pulled By: vivekmig

fbshipit-source-id: 85471310d187cf6bd8c5de36277f5b83d939e025
Summary:
Remove the dummy dims of 1 of the output of `_select_targets` when the target is selected with `gather` , so it acts the same as when `target` is `int` or scalar.

Also add comments to explain `_select_targets`

(the function is way too confusing. We should seriously rethink what to support or suggest users to no longer use `target`)

Reviewed By: vivekmig

Differential Revision: D50619740

fbshipit-source-id: b1325adcfb6f95b521c6eb889a18f1e72e05b9b5
Summary:
Pull Request resolved: meta-pytorch#1173

Support multi-task attribution in `ShapleyValues` and `ShapleyValueSampling`.

Assuming the return of `forward_fun` is in (*output_shape), the attribution result will be in (*output_shape, *input_shape[1:]). Existing use cases becomes just special cases where output_shape is (1,) or (batch_size,)

Reviewed By: vivekmig

Differential Revision: D48696578

fbshipit-source-id: cc0f9275b20be6416abf0d8e72739a2c3ca421b6
Summary:
Pull Request resolved: meta-pytorch#1175

As ShapleyValues and SHapleyValueSampling have supported multi-task output, they can be used with LLMAttribution

Reviewed By: vivekmig

Differential Revision: D48697749

fbshipit-source-id: 584cee931f351f3a3ac6ac2e2ccc1cf7b2097801
Summary:
Pull Request resolved: meta-pytorch#1200

as title

Reviewed By: vivekmig

Differential Revision: D50715178

fbshipit-source-id: cc249ec7c61a6056cd815b40546dbbc74ff3d40c
Summary: This fix ensure multi-task attribution works correctly when batch in mask is not one

Reviewed By: vivekmig

Differential Revision: D50867023

fbshipit-source-id: 4e0af79c7ca790ba23a329887a89126ececd8383
Summary: `TextTokenInput` is a child of `InterpretableInput` which treat each token as an interpretable feature where the tokens are determined by a given `tokenizer`.

Reviewed By: vivekmig

Differential Revision: D50826444

fbshipit-source-id: 449d67d383c8c2a6dc4549187520d1719a736b58
Summary:
Tutorial generation is currently failing due to ipython_genutils not being found. Adding this dependency for website publishing.

Pull Request resolved: meta-pytorch#1203

Reviewed By: aobo-y

Differential Revision: D51178476

Pulled By: vivekmig

fbshipit-source-id: 7e5a25db1529c0a8ed4dfbc1b152840a18124fbb
Summary:
Currently, build_docs completes successfully even if commands fail, which could cause problematic website deployments and inaccurate signal from the test website deployment. Adds -e to exit script if any command fails.

Pull Request resolved: meta-pytorch#1204

Reviewed By: aobo-y

Differential Revision: D51180604

Pulled By: vivekmig

fbshipit-source-id: 20045f80bea06c7244dce63ba110583515f45731
Summary:
Pull Request resolved: meta-pytorch#1206

Implement the LLM attribution method wrapper for gradient-based algorithm

Only supported token-based attribution

Reviewed By: vivekmig

Differential Revision: D51224438

fbshipit-source-id: cd8c585c7daa592aef4123e8fecad9a6b7054e45
Summary:
Limit the attr target to log_prob and support sequence attr in LLMGradientAttribution

All the gradient attribution methods we plan to support are proven to have their sequence attribution equivalent to the sum of each token's attribution if the target is log probabilities.

Reviewed By: vivekmig

Differential Revision: D51366631

fbshipit-source-id: af1b86e094bea0a218014619c592bd7f3d95c91c
Summary: as title

Reviewed By: vivekmig

Differential Revision: D51415248

fbshipit-source-id: b78f418f5ecdf2218560b2e84a64928dbacca6de
Summary: include `tqdm` as a dependency

Reviewed By: vivekmig

Differential Revision: D51415967

fbshipit-source-id: 848f68866990c50a1d0e5202edc9926f463da67f
Summary:
Pull Request resolved: meta-pytorch#1088

This diff adds an "aggregate" option to `TracInCP.influence`. The "aggregate" influence score of a training example on a test dataset is the sum of the influence of the training example on all examples in the test dataset. When `aggregate` is True, `influence` in influence score mode returns a 2D tensor of shape (1, training dataset size) containing aggregate influence scores of all training examples.  When `aggregate` is True, `influence` in k most influential mode returns a 2D tensor of shape (1, k) of proponents (or opponents), and a 2D tensor containing the corresponding aggregate influence scores, of the same shape.

This option is only added for `TracInCP`, because for it, aggregate influence can be computed more quickly than naively computing the influence score of all training examples on all test examples, and then summing across test examples. In particular, we can first sum the jacobians across all test examples, and then take the dot-product of the sum with the jacobians of training examples.  (all this is done across checkpoints).

Since computing aggregate influence scores is efficient, even if the test dataset is large, we now allow `inputs` for `influence` to be a dataloader, so that it does not need to fit in memory.

One use case of aggregate influence is to compute the influence of a training example on some validation metric, i.e. fairness metric.

We add the following tests:
- in newly added `test_tracin_aggregate_influence`, `test_tracin_aggregate_influence` tests that calling `influence` with `aggregate=True`does give the same result as calling it with `aggregate=False`, and then summing.
- in newly added `test_tracin_aggregate_influence`, `test_tracin_aggregate_influence_api` tests that the result of calling `influence` when `aggregate` is true for a DataLoader of batches is the same as when the batches are collated into a single batch.
- in `test_tracin_k_most_influential`, we modify the test to allow `aggregate` to be true, which tests that the proponents computed with the memory saving approach by `influence` are the same proponents computed via calculating all aggregate influence scores, and then sorting (not memory efficient).ar

Reviewed By: cyrjano

Differential Revision: D41830245

fbshipit-source-id: 5bc12e667bba0c369db75822387784a9184f3b3e
Summary:
There was a typo in the docstring of Layer Activation

Pull Request resolved: meta-pytorch#1208

Reviewed By: aobo-y

Differential Revision: D51577664

Pulled By: vivekmig

fbshipit-source-id: f7af736ba07d851d55b12b85a3531cfb735c6a3b
…1209)

Summary:
Adds support for Lime and KernelShap in LLM Attribution, which return None for token_attr.

Pull Request resolved: meta-pytorch#1209

Reviewed By: aobo-y

Differential Revision: D51577967

Pulled By: vivekmig

fbshipit-source-id: f9ea8d1d9dfae420c44630f2682155a295d8b9bd
Summary:
Adds GPU tests for LLM attribution by parametrizing test class and verifying output attribution device. Currently also includes changes for KernelShap and Lime since there are dependencies, will rebase once that PR is merged.

Pull Request resolved: meta-pytorch#1210

Reviewed By: aobo-y

Differential Revision: D51579521

Pulled By: vivekmig

fbshipit-source-id: 01fefe1fbb3b3784c80e2afc781c11575627669f
Summary:
Pull Request resolved: meta-pytorch#1185

Currently, when testing implementations of `TracInCPBase`, if the model to be tested is on gpu, we always wrap it in `DataParallel`.  However, it is also worth testing when the model is on gpu, but is *not* wrapped in `DataParallel`.  Whether the model is on gpu is currently specified by a `use_gpu` flag, which is boolean.  In this diff, we change `use_gpu` to have type `Union[bool, str]`, which allowable values of `False` (model on cpu), `'cuda'` (model on gpu, not using `DataParallel`, and `'cuda_data_parallel'` (model on gpu, using `DataParallel`).  This has backwards compatibility with classes like `ExplicitDataset`, which moves data to gpu `if use_gpu`, as strings are interpreted as being true.  In further detail, the changes are as follows:
- for tests (`TestTracInSelfInfluence`, `TestTracInKMostInfluential`) where `use_gpu` was called with `True`, now call them with values of `'cuda'` and `'cuda_parallel'` (in addition to `False`)
- in those tests, make the layer names have the 'module' prefix only when `use_gpu='cuda_data_parallel'`
- change `get_random_model_and_data`, which is where the `use_gpu` flag is used to create model and data, to reflect the new logic

Reviewed By: vivekmig

Differential Revision: D47190429

fbshipit-source-id: c7d3b36589beaec306d31ab80a6011b12df9b269
Summary:
Pull Request resolved: meta-pytorch#1212

Implement a Callable Baselines class that returns a sample from the Cartesian product of the inputs' available baselines.

Reviewed By: vivekmig

Differential Revision: D51582979

fbshipit-source-id: ec7c833a5572b6a15c5cc8acb3fb9b1bcf439065
Summary:
as title

Pull Request resolved: meta-pytorch#1213

Reviewed By: vivekmig

Differential Revision: D51628169

Pulled By: aobo-y

fbshipit-source-id: 36d20c58113f99ed915aed4019b915fb6a344368
Summary:
as title

Pull Request resolved: meta-pytorch#1216

Reviewed By: vivekmig

Differential Revision: D51795314

Pulled By: aobo-y

fbshipit-source-id: c7eca5e9c32f4e582052773cf72a87967a30a4eb
Summary:
as title

Pull Request resolved: meta-pytorch#1217

Reviewed By: vivekmig

Differential Revision: D51803181

Pulled By: aobo-y

fbshipit-source-id: 81d9bb4bb5d839ac12b98e2344c87ec59b5f0718
…lize_t… (meta-pytorch#1152)

Summary:
The default argument for `method` in `captum.attr.visualization.visualize_timeseries_attr` is currently `"individual_channels"`, which is not a valid option, resulting in an exception if used. This PR changes the default method to `"overlay_individual"`, which is what the docs indicate the default should be.

Pull Request resolved: meta-pytorch#1152

Reviewed By: aobo-y

Differential Revision: D47197267

Pulled By: vivekmig

fbshipit-source-id: 4d87f792b742fafbb9c30e84247c830e93df1187
Summary:
Adds tests for missing versions of PyTorch to make sure tests cover all supported PyTorch versions.

Pull Request resolved: meta-pytorch#1218

Reviewed By: aobo-y

Differential Revision: D51823341

Pulled By: vivekmig

fbshipit-source-id: 395836ca7683046c99ec2aeaf90c3dd65b1da37b
Summary:
to be merged after everything is ready

Pull Request resolved: meta-pytorch#1219

Reviewed By: vivekmig

Differential Revision: D51808995

Pulled By: aobo-y

fbshipit-source-id: cd4a57a76f1666673352fd669c81ed25fb53571f
Summary:
Pull Request resolved: meta-pytorch#1214

Pull Request resolved: meta-pytorch#1186

# Overview
This diff, along with D42006733, implement 2 different implementations that both calculate the "infinitesimal" influence score as defined in the paper ["Understanding Black-box Predictions via Influence Functions"](https://arxiv.org/pdf/1703.04730.pdf).
- `NaiveInfluenceFunction`: a computationally slow but exact implementation that is useful for obtaining "ground-truth" (though, note that influence scores themselves are an approximation of the effect of removing then retraining). Several papers actually use this approach, i.e. ["Learning Augmentation Network via Influence Functions"](https://openaccess.thecvf.com/content_CVPR_2020/papers/Lee_Learning_Augmentation_Network_via_Influence_Functions_CVPR_2020_paper.pdf), ["Quantifying and Mitigating the Impact of Label Errors on Model Disparity Metrics"](https://openreview.net/forum?id=RUzSobdYy0V), ["Achieving Fairness at No Utility Cost via Data Reweighting with Influence"](https://proceedings.mlr.press/v162/li22p/li22p.pdf)
- `ArnoldiInfluenceFunction`: This is a computationally efficient implementation described in the paper ["Scaling Up Influence Functions"](https://arxiv.org/pdf/2112.03052.pdf) by Schioppa et al.  These [slides](https://docs.google.com/presentation/d/1yJ86FkJO1IZn7YzFYpkJUJUBqaLynDJCbCWlKKglv-w/edit#slide=id.p) give a brief summary of it.

This diff is rebased on top of D41324297, which implements the new API.

Again, note that the 2 above implementations are implemented across 2 diffs, for easier review, though they are jointly described here.

# What is the "infinitesimal" influence score
More details on the "infinitesimal" influence score: This "infinitesimal" influence score approximately answers the question if a given training example were infinitesimally down-weighted and the model re-trained to optimality, how much would the loss on a given test example change. Mathematically, the aforementioned influence score is given by `\nabla_\theta L(x)' H^{-1} \nabla_\theta L(z)`, where `\nabla_\theta L(x)` is the gradient of the loss, considering only training example `x` with respect to (a subset of) model parameters `\theta`, `\nabla_\theta L(z)` is the analogous quantity for a test example `z`, and `H` is the Hessian of the (subset of) model parameters at a given model checkpoint.

# What the two implementations have in common
Both implementations compute a low-rank approximation of the inverse Hessian, i.e. a tall and skinny (with width k) matrix `R` such that `H^{-1} \approx RR'`, where k is small. In particular, let `L` be the matrix of width k whose columns contain the top-k eigenvectors of `H`, and let `V` be the k by k matrix whose diagonals contain the corresponding eigenvalues. Both implementations let `R=LV^{-1}L'`. Thus, the core computational step is computing the top-k eigenvalues / eigenvectors.
This approximation is useful for several reasons:
- It avoids numerical issues associated with inverting small eigenvalues
- Since the influence score is given by `\nabla_\theta L(x)' H^{-1} \nabla_\theta L(z)`, which is approximated by `(\nabla_\theta L(x)' R) (\nabla_\theta L(z)' R)`, we can compute an "influence embedding" for a given example `x`, `\nabla_\theta L(x)' R`, such that the influence score of one example on another is approximately the dot-product of their respective embeddings.  Because k is small, i.e. 50, these influence embeddings are low-dimensional.
- Even for large models, we can store `R` in memory, provided k is small. This means influence embeddings (and thus influence scores) can be efficiently computed by doing a backwards pass to compute `\nabla_\theta L(x)` and then multiplying by `R'`. This is orders of magnitude faster than the previous LISSA approach of Koh et al, which to compute the influence score involving a given example, need to compute Hessian-vector products involving on the order of 10^4 examples.

The implementations differ in how they compute the top-k eigenvalues / eigenvectors.

# How `NaiveInfluenceFunction` computes the top-k eigenvalues / eigenvectors
It is "naive" in that it computes the top-k eigenvalues / eigenvectors by explicitly forming the Hessian, converting it to a 2D tensor, computing its eigenvectors / eigenvalues, and then sorting. See documentation of the `_set_projections_naive_influence_function` method for more details.

# How `ArnoldiInfluenceFunction` computes the top-k eigenvalues / eigenvectors
The key novelty of the approach by Schioppa et al is that it uses the Arnoldi iteration to find the top-k eigenvalues / eigenvectors of the Hessian without explicitly forming the Hessian. In more detail, the approach first runs the Arnoldi iteration, which only requires the ability to compute Hessian-vector products, to find a Krylov subspace of moderate dimension, i.e. 200. It then finds the top-k eigenvalues / eigenvectors of the restriction of the Hessian to the subspace, where k is small, i.e. 50. Finally, it expresses the eigenvectors in the original basis. This approach for finding the top-k eigenvalues / eigenvectors is justified by the property of the Arnoldi iteration, that the Krylov subspace it returns tends to contain the top eigenvectors.

This implementation does incur some one-time overhead in `__init__`, where it runs the Arnoldi iteration to calculate `R`. After that overhead, calculation of influence scores is quick, only requiring a backwards pass and multiplication, per example.

Unlike `NaiveInfluenceFunction`, this implementation does not flatten any parameters, as the 2D Hessian is never formed, and Pytorch's Hessian-vector implementation (`torch.autograd.functional.hvp`) allows the input and output vector to be a tuple of tensors. Avoiding flattening / unflattening parameters brings scalability gains.

# High-level organization of the two implementations
Because of the common logic of the two implementations, they share the same high-level organization.
- Both implementations accept a `hessian_dataset` initialization argument.  This is because "infinitesimal" influence scores depend on the Hessian, which is in practice, computed not over the entire training data, but over a subset of it, which is specified by `hessian_dataset`.
- in `__init__`, `NaiveInfluenceFunction` and `ArnoldiInfluenceFunction` both compute `R` using private helper methods `_set_projections_naive_influence_function` and `_set_projections_arnoldi_influence_function`, respectively.
- `R` is used by their respective `compute_intermediate_quantities` methods to compute influence embeddings.
- Because influence scores (and self-influence scores) are computed by first computing influence embeddings, the `_influence` and `self_influence` methods for both implementations call the `_influence_helper_intermediate_quantities_influence_function` and `_self_influence_helper_intermediate_quantities_influence_function` helper functions, which both assume the implementation implements the `compute_intermediate_quantities` method.

# Reason for inheritance structure
`InfluenceFunctionBase` refers to any implementation that computes the "infinitesimal" influence score (as opposed to `TracInCPBase`, which computes the checkpoint-based definition of influence score).  Thus the different "base" implementations implement differently-defined influence scores, and children of a base implementation compute the same influence score in different ways.  `IntermediateQuantitiesInfluenceFunction` refers to implementations of `InfluenceFunctionBase` that implement the `compute_intermediate_quantities` method. The reason we don't let `NaiveInfluenceFunction` and `ArnoldiInfluenceFunction` directly inherit from `InfluenceFunctionBase` is that their implementations of `influence` and `self_influence` are actually identical (though for logging reasons, we cannot just move those methods into `IntermediateQuantitiesInfluenceFunction`).  In the future, there may be implementations of `InfluenceFunctionBase` that do *not* inherit from `IntermediateQuantitiesInfluenceFunction`, i.e. the LISSA approach of Koh et al.

# Key helper methods
- `captum._utils._stateless.functional_call` is copy pasted from [Pytorch 13.0 implementation](https://github.com/pytorch/pytorch/blob/17202b363780a06ae07e5cecceffaae6418ad6f8/torch/nn/utils/stateless.py) so that the user does not need to use the latest Pytorch version, and turns a Pytorch `module` into a function whose inputs are the parameters of the `module` (represented as a dictionary).  This function is used to compute the Hessian in `NaiveInfluenceFunction`, and Hessian-vector products in `ArnoldiInfluenceFunction`.
- `_compute_dataset_func` is used by `NaiveInfluenceFunction` to compute the Hessian over `hessian_dataset`.  This is done by calculating the Hessian over individual batches, and then summing them up.  One complication is that `torch.autograd.functional.hessian`, which we use to compute Hessians, does not return the Hessian as a 2D tensor unless the function we seek the Hessian of accepts a 1D tensor.  Therefore, we need to define a function of the model's parameters whose input is the parameters, *flattened* into a 1D tensor (and a batch).  This function is given by the factory returned by `naive_influnce_function._flatten_forward_factory`.
- `_parameter_arnoldi` performs the Arnoldi iteration and is used by `ArnoldiInfluenceFunction`.  It differs from a "traditional" implementation in that the Hessian-vector function it accepts does not map from 1D tensor to 1D tensor.  Instead, it maps from tuple of tensor to tuple of tensor, because the "vector" in this case represents a parameter setting, which Pytorch represents as a tuple of tensor.  Therefore, all the operations work with tuple of tensors, which required defining various operations for tuple of tensors in `captum.influence._utils.common`.  This method returns a basis for the Krylov subspace, and the restriction of the Hessian to it.
- `_parameter_distill` takes the output of `_parameter_distill`, and returns the (approximate) top-k eigenvalues / eigenvectors of the Hessian.  This is what is needed to compute `R`.  It is used by `ArnoldiInfluenceFunction`.

# Tests
We create a new test file `tests.influence._core.test_arnoldi_influence.py`, which defines the class `TestArnoldiInfluence` implementing the following tests:
#### Tests used only by `NaiveInfluenceFunction`, i.e. appear in this diff:
- `test_matches_linear_regression` compares the influence scores and self-influence scores produced by a given implementation with analytically-calculated counterparts for a model where the exact influence scores are known - linear regression.  Different reductions for loss function - 'mean', 'sum', 'none' are tested.  Here, we test the following implementation:
-- `NaiveInfluenceFunction` with `projection_dim=None`, i.e. we use the inverse Hessian, not a low-rank approximation of it.  In this case, the influence scores should equal the analytically calculated ones, modulo numerical issues.
- `test_flatten_unflattener`: a common operation is flattening a tuple of tensors and unflattening it (the inverse operation).  This tests checks that flattening and unflattening a tuple of tensors gives the original tensor.
- `test_top_eigen`: a common operation is finding the the top eigenvectors / eigenvalues of a possibly non-symmetric matrix.  Since `torch.linalg.eig` doesn't sort the eigenvalues, we make a wrapper that does do it.  This checks that the wrapper is working properly.
#### Tests used only by `ArnoldiInfluenceFunction`, i.e. appear in next diff:
- `test_parameter_arnoldi` checks that `_parameter_arnoldi` is correct.  In particular, it checks that the top-`k` eigenvalues of the restriction of `A` to a Krylov subspace (the `H` returned by `_parameter_arnoldi`) agree with those of the original matrix. This is a property we expect of the Arnoldi iteration that `_parameter_arnoldi` implements.
- `test_parameter_distill` checks that `_parameter_distill` is correct. In particular, it checks that the eigenvectors corresponding to the top eigenvalues it returns agree with the top eigenvectors of `A`. This is the property we require of `distill`, because we use the top eigenvectors (and eigenvalues) of (implicitly-defined) `A` to calculate a low-rank approximation of its inverse.
- `test_matches_linear_regression` where the implementation tested is the following:
-- `ArnoldiInfluenceFunction` with `arnoldi_dim` and `projection_dim` set to a large value.  The Krylov subspace should contain the largest eigenvectors because `arnoldi_dim` is large, and `projection_dim` is not too large relative to `arnoldi_dim`, but still large on an absolute level.
- When `projection_dim` is small, `ArnoldiInfluenceFunction` and `NaiveInfluenceFunction` should produce the same influence scores, provided `arnoldi_dim` for `ArnoldiInfluenceFunction` is large, since in this case, the top-k eigenvalues / eigenvectors for the two implementations should agree.  This agreement is tested in `test_compare_implementations_trained_NN_model_and_data` and `test_compare_implementations_random_model_and_data` for a trained and untrained 2-layer NN, respectively.

# Minor changes / functionalities / tests
- `test_tracin_intermediate_quantities_aggregate`, `test_tracin_self_influence`, `test_tracin_identity_regression` are applied to both implementations
- `_set_active_params` now extracts the layers to consider when computing gradients and sets their `requires_grad`.  This refactoring is done since the same logic is used by `TracInCPBase` and `InfluenceFunctionBase`.
- some helpers are moved from `tracincp` to `captum.influence._utils.common`
- a separate `test_loss_fn` initialization argument is supported, and both implementations are now tested in `TestTracinRegression.test_tracin_constant_test_loss_fn`
- `compute_intermediate_quantities` for both implementations support the `aggregate` option.  This means that both implementations can be used with D40386079, the validation influence FAIM workflow.
- given the aforementioned tests, testing now generates multiple kinds of models / data.  The ability to do so is added to `get_random_model_and_data`.  The specific model (and its parameters) are specified by the `model_type` argument.  Before, the method only supports the random 2-layer NN.  Now, it also supports an optimally-trained linear regression, and a 2-layer NN trained with SGD.
- `TracInCP` and implementations of `InfluenceFunctionBase` all accept a `sample_wise_grads_per_batch` option, and have the same requirements on the loss function.  Thus, `_check_loss_fn_tracincp`, which previously performed those checks, is renamed `_check_loss_fn_sample_wise_grads_per_batch` and moved to `captum.influence._utils.common`.  Similarly, those implementations all need to compute the jacobian, with the method depending on `sample_wise_grads_per_batch`.  The jacobian computation is moved to helper function `_compute_jacobian_sample_wise_grads_per_batch`.

Reviewed By: NarineK

Differential Revision: D40541294

fbshipit-source-id: 349efeeba67291baf9ff6538ac145a0da7aa006d
Summary:
Pull Request resolved: meta-pytorch#1187

This diff implements `ArnoldiInfluenceFunction`, which was described, along with `NaiveInfluenceFunction` in D40541294.  Please see that diff for detailed description.  Previously implementations of both methods had been 1 diff.  Now, `ArnoldiInfluenceFunction` is separated out for easier review.

Reviewed By: vivekmig

Differential Revision: D42006733

fbshipit-source-id: 14e82d30d56fb75dcdb5e77db9c93d626430a74f
…eta-pytorch#1224)

Summary:
Default generation in transformers utilizes past_key_values to cache previous key values to speed up forward passes for subsequent tokens. This adds a flag and use of corresponding helpers from transformers generation utils to follow the same approach for using caching.

Using this flag leads to about a 10x speedup with 10 target tokens, and improvement seems to scale with number of target tokens.

Pull Request resolved: meta-pytorch#1224

Reviewed By: aobo-y

Differential Revision: D52240469

Pulled By: vivekmig

fbshipit-source-id: e643458529091fb5540b0b0a374ceb0c2c25e394
Summary:
as title

The tutorial only demonstrate the perturbation-based algorithms. Will add the gradient-based demo later.

rendered notebook:
https://github.com/aobo-y/captum/blob/llm/tutorials/Llama2_LLM_Attribution.ipynb

Pull Request resolved: meta-pytorch#1228

Reviewed By: vivekmig

Differential Revision: D52476602

Pulled By: aobo-y

fbshipit-source-id: 5565fc41c163cff1ddbf32ac8def52aba38b7d1e
Summary: Fix issues causing lint failures for autodeps

Reviewed By: aobo-y

Differential Revision: D53022779

fbshipit-source-id: 86e617b7e14a0bdb98b1552de71940062b55d094
jjuncho and others added 29 commits January 22, 2025 12:52
…ch#1490)

Summary:
Pull Request resolved: meta-pytorch#1490

This diffs adds more testing coverage for attribute_future to ShapleyValueSampling unit tests that handle shapley sampling with boolean inputs

Reviewed By: cyrjano

Differential Revision: D68230069

fbshipit-source-id: 73eef566d8b9bb9baecd48eae8eeb321e1391e1a
…ch#1489)

Summary:
Pull Request resolved: meta-pytorch#1489

This diffs adds more testing coverage for attribute_future to ShapleyValueSampling unit tests that use the BasicModel_MultiLayer_MultiInput model. Since these tests are larger, they will not be parameterized for readability

Reviewed By: csauper

Differential Revision: D68346488

fbshipit-source-id: fe3d6e80df3c2b4ec125cc8cef3efc1122353051
…ch#1488)

Summary:
Pull Request resolved: meta-pytorch#1488

This diffs adds more testing coverage for attribute_future to ShapleyValueSampling unit tests where forward function returns a scalar per batch, as either a float, integer, 0d tensor or 1d tensor for async methods.

Reviewed By: styusuf

Differential Revision: D68346494

fbshipit-source-id: 7063f3a8e1a52ed78d36786f464a4f8d05f0430d
Summary:
Pull Request resolved: meta-pytorch#1502

Resolve various errors regarding pyre typing, mypy typing, ufmt formatting, and flake8 formatting.

Reviewed By: sarahtranfb

Differential Revision: D69695280

fbshipit-source-id: d76b024fbba0cd78f78bf2b6fb7ffd0e92084b30
Summary:
Pull Request resolved: meta-pytorch#1503

Bump tool.black python version to 3.9

Reviewed By: cyrjano

Differential Revision: D69695279

fbshipit-source-id: 94aa5477dc3039ab941f1e44d6e0b1c87791a044
Summary:
Pull Request resolved: meta-pytorch#1501

Add additional relevant keywords to setup.py that might help visibility

https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata-keywords

Reviewed By: cyrjano

Differential Revision: D69695281

fbshipit-source-id: a91cf4c0a4671b8156b4d67900acce2c5effee6d
…1500)

Summary:
Pull Request resolved: meta-pytorch#1500

Reduce redundant major.minor specification in setup.py by reusing required major/minor variables

Reviewed By: cyrjano

Differential Revision: D69695278

fbshipit-source-id: b8949dd844fe78d85d848db811db488e945935f1
Summary:
Pull Request resolved: meta-pytorch#1499

Remove the dated "beta" text in our README.

Reviewed By: cyrjano

Differential Revision: D69695282

fbshipit-source-id: b4278597ff27c991be04cbf5c0de965fbcc43c63
Summary:
Pull Request resolved: meta-pytorch#1498

Add a message about deprecating Captum Insights in an upcoming release. We intend to deprecate it fully but still provide the code for those interested in it.

Reviewed By: cyrjano

Differential Revision: D69695277

fbshipit-source-id: d66ffa9db91dfd0025f286b72fe8aeff62ad5a0b
Summary:
Pull Request resolved: meta-pytorch#1504

Update version as part of v0.8.0 release.

Reviewed By: cyrjano

Differential Revision: D69695416

fbshipit-source-id: 440c99166be54f1aa492feef4ea417c5253c2997
…a-pytorch#1506)

Summary:
`setuptools` is no longer an automatically included dependency of any `host` packages, so it needs to be included. `run` needs to be updated with additional new baseline dependencies of captum as well.

Pull Request resolved: meta-pytorch#1506

Reviewed By: cyrjano

Differential Revision: D69836121

Pulled By: craymichael

fbshipit-source-id: 6ed3c1f7f67f74bb2877a5f84faf4028894abe95
meta-pytorch#1496)

Summary:
Pull Request resolved: meta-pytorch#1496

Got meta-pytorch#1486 when I was oncall a while ago. A user ran into this error:
> TypeError: ShapleyValues.attribute() got an unexpected keyword argument 'skip_tokens'

due to being on a package of Captum where
> LLMAttribution.attribute() doesn't have skip_tokens as a parameter, and therefore it's being passed to ShapleyValues.attribute() as part of **kwarg, though ShapleyValues never supported skip_tokens

It's not sufficient to be on the latest Captum release (v0.7), atp they need to install from Github

Reviewed By: craymichael

Differential Revision: D69566114

fbshipit-source-id: 38f5fdc46c610a8ab1e8a21ef375121fa18c9606
Summary:
Pull Request resolved: meta-pytorch#1508

Update classifier in line with the README Beta text removal.

Reviewed By: sarahtranfb

Differential Revision: D69953558

fbshipit-source-id: 8eb6981d3f0057ff2c7056ce82d9398c5a1ecb6e
…ta-pytorch#1497)

Summary:
Pull Request resolved: meta-pytorch#1497

Basic support; doesn't currently support multiple perturbations per eval

Reviewed By: cyrjano, vivekmig

Differential Revision: D69531512

fbshipit-source-id: 420dac28dcec06c482b3234f919cf87fecda4b08
…torch#1507)

Summary:
Pull Request resolved: meta-pytorch#1507

Most of the logic is in the parent class `FeatureAblation`, but to support feature grouping across input tensors we need to update the permutation utils too

Reviewed By: cyrjano

Differential Revision: D69867208

fbshipit-source-id: 27d2eec3342a0cdce29ebd68b0260e26345c05dd
Summary:
Pull Request resolved: meta-pytorch#1509

See title.

Reviewed By: aobo-y

Differential Revision: D69953942

fbshipit-source-id: 373a6b1838f088fb9566895e2e7d276e4bc6a1ee
Summary:
Pull Request resolved: meta-pytorch#1510

Dependencies updated for conda env file in line with setup.py and meta.yaml.

Reviewed By: aobo-y

Differential Revision: D69954075

fbshipit-source-id: 82d6e16576d617eef1bc860ff9f6007bfaac9b67
…h#1511)

Summary:
Pull Request resolved: meta-pytorch#1511

TSIA

Reviewed By: cyrjano

Differential Revision: D69957243

fbshipit-source-id: 70e0a7ce01ef9c3359f90473137a075f27aad139
Summary:
Pull Request resolved: meta-pytorch#1513

Currently, when a batch of inputs is provided with a forward function that returns a single scalar per batch, Lime and KernelShap still return output matching the input shape.

This behavior is inconsistent with other perturbation based methods, particularly Feature Ablation and Shapley Value Sampling.

This change breaks backward compatibility for OSS users, but since it's a specific case (scalar per batch), should be fine to update with only a documentation update.

Reviewed By: craymichael

Differential Revision: D70096644

fbshipit-source-id: de9207813240cb4a013680854a363df70ee777f9
Summary:
Pull Request resolved: meta-pytorch#1522

Example failure:
https://www.internalfb.com/intern/testinfra/testconsole/testrun/4785074873255877/
Passed and failed on rev 3c307b1e123f2007d69464836099b12fa4656423, so not due to a code change

Running locally at least, I see:
```
E0305 00:39:14.685009 1133092 socket.cpp:1019] [c10d] The client socket has timed out after 600000ms while trying to connect to (127.0.0.1, 29500).
```

Related thread: https://fb.workplace.com/groups/319878845696681/permalink/1241443370206886/

There's only one process in this test (`world_size=1`) so should be ok to use `localhost` instead of `127.0.0.1`

Reviewed By: cyrjano

Differential Revision: D70637306

fbshipit-source-id: 111bc966097dbcccfea57ee152edf4eb39c48179
…d layers. Simple logging for unsupported layers (meta-pytorch#1505)

Summary:
Pull Request resolved: meta-pytorch#1505

We are adding test for unsupported gradient layers. Open to ideas if there is a better way to structure the test.

A bit uncomfortable with removing pyre type validations as we allow anything to be passed into the GradientUnsupportedLayerOutput class.

Reviewed By: craymichael

Differential Revision: D69792994

fbshipit-source-id: 8b8ca70ef5ee83fb00c613f233747e1c19c15088
…eta-pytorch#1525)

Summary:
Pull Request resolved: meta-pytorch#1525

Shapley Values currently have issues with per task importance, since aggregate mode returns more than 1 output with perturbations per eval = 1, which should apply aggregate mode for collating perturbation results.

Updates logic to appropriately handle multiple outputs (not matching batch size) when perturbations per eval = 1

Reviewed By: MarcioPorto

Differential Revision: D70832826

fbshipit-source-id: 52e1e40d599f662ac522eae4830560cf1338f7e1
…ermutation/ablation (meta-pytorch#1527)

Summary:
Pull Request resolved: meta-pytorch#1527

Study: https://docs.google.com/spreadsheets/d/1GyNJJBrNkazGOyJQLv00QV4phX2R3488oNgVPT17qzU/edit?gid=0#gid=0
Saw a regression in the new logic introduced in D69531512 with one of the models for both permutation and ablation methods, potentially due to large sparse features. vivekmig suggested we can avoid creating all these zero tensors

Reviewed By: craymichael

Differential Revision: D71057703

fbshipit-source-id: 3c4acc00b82de3fff7322c4f7cf99ad87fed1d02
…ytorch#1521)

Summary:
Pull Request resolved: meta-pytorch#1521

This is to make sure that we control for when the output is not a 2D tensor

* If the shape of the model output is a 0D, it would fail since LayerGradientXActivation always [assumes](https://www.internalfb.com/code/fbsource/[ffa152e31f81]/fbcode/pytorch/captum/captum/_utils/gradient.py?lines=681) that output (output[0] would raise an index error) for a task is 1D.
  * I propose we raise an assertion error if output is 0D and ask the user to edit output or output accessor to ensure output > 0D.

* If the model output shape is a 1D, it could either be of size (batch_size) when there’s one target or (n_targets) when there’s only one observation with multiple targets or some kind of aggregated batch loss across multiple targets
  * When it’s size (batch_size), we can assume there’s just one target and get attributions without passing in a target.
  * When it’s size (n_targets), there will be an issue when we call LayerGradientXActivation since we will need to pass in the target parameter to get attribution for each target.
    * We cannot pass in a target when the output is a 1D tensor. LayerGradientXActivation [checks that the output dimension is 2D](https://www.internalfb.com/code/fbsource/[ffa152e31f81]/fbcode/pytorch/captum/captum/_utils/common.py?lines=700-701)
    * The output needs to be 2D with the shape (1 x n_targets). That needs to be done on the output_accessor or forward function to make sure LayerGradientXActivation can account for it.
  * We could check whether output.shape[0] = inputs.shape[0]. If this is the case, we know that the 1D tensor is for one target. If not, then it’s for multiple targets. We could throw an error in the latter case to inform the user that output needs to be 2D if attributing over multiple targets. I worry that this is assuming too much and the assumption would break if there are multiple targets for 1D case but batch_size = n_targets. In this case, we would automatically assume that there's only one target when maybe there isn't.
  * I propose that we keep the assumption that 1D tensor is for one target. In the case that the 1D tensor is for multiple targets, it would fail LayerGradientXActivation anyway unless it’s converted to 2D.

We also include an output accessor that parses a dictionary model output to get 1D tensor for testing.

Reviewed By: vivekmig

Differential Revision: D69876980

fbshipit-source-id: 4c64410c1d0a25f2819f2da31f303f5fe710d3e1
…ough layer. (meta-pytorch#1526)

Summary:
Pull Request resolved: meta-pytorch#1526

We are adding tests for different types of unsupported and non-differentiable layer output. Here, we add a test for layer output that is a tensor of integers.

We split by the cases for unsupported layers from the case when the layer output is used by some tasks and not others.

When layer output is not supported (layer output is a List of Tensors or a Tensor of integers), we don't get attributions and return None for those layers.

In the case when a layer output is not used by a task, we should output a tensor of zeros for that task.

Reviewed By: craymichael

Differential Revision: D70919347

fbshipit-source-id: 191d9d69c78bcf00fa3cbbbd5707154e0f221410
Summary:
While packaging this module for Nix (NixOS/nixpkgs#356087), I noticed during the tests that `flask` and `flask-compress` modules were missing from the `setup.py` file.

Pull Request resolved: meta-pytorch#1442

Reviewed By: cyrjano

Differential Revision: D71814035

Pulled By: jjuncho

fbshipit-source-id: 4e1cbc9e2e43dd88657063fade94405094bb4190
…eta-pytorch#1530)

Summary:
Pull Request resolved: meta-pytorch#1530

This was supported in the old path (when constructing ablated inputs over each input tensor individually) to improve compute efficiency by optionally passing in multiple perturbed inputs to the model fwd function.

Reviewed By: craymichael

Differential Revision: D71435704

fbshipit-source-id: 6f80ebc69a7e51614432127e1b9b175353072d60
…ytorch#1531)

Summary:
Pull Request resolved: meta-pytorch#1531

With `enable_cross_tensor_attribution=True` for `FeatureAblation`/`FeaturePermutation`, ids/indices in the masks are now "global"

Reviewed By: cyrjano

Differential Revision: D71778355

fbshipit-source-id: 445bf3813faf7e34432f35500bf98c7c0899cb8a
Summary: Looping over the features has moved up into `_construct_ablated_input_across_tensors` after D71435704, so we don't need this anymore

Reviewed By: cyrjano

Differential Revision: D72064893

fbshipit-source-id: 0f3ac2c967a577f4bc3f688893319aac3e51000d
@ProGamerGov ProGamerGov merged commit 4041121 into master-0-new-1 Mar 30, 2025
1 of 119 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.