class_docstr: Attribution class for large language models. It wraps a perturbation-based
  attribution algorthm to produce commonly interested attribution
  results for the use case of text generation.
  The wrapped instance will calculate attribution in the
  same way as configured in the original attribution algorthm, but it will provide a
  new "attribute" function which accepts text-based inputs
  and returns LLMAttributionResult
class_docstr_tok: ["Attribution","class","for","large","language","models",".","It","wraps","a","perturbation-based","attribution","algorthm","to","produce","commonly","interested","attribution","results","for","the","use","case","of","text","generation",".","The","wrapped","instance","will","calculate","attribution","in","the","same","way","as","configured","in","the","original","attribution","algorthm",",","but","it","will","provide","a","new","``","attribute","''","function","which","accepts","text-based","inputs","and","returns","LLMAttributionResult"]
code: def _forward_func(
      self,
      perturbed_tensor,
      inp,
      target_tokens,
      use_cached_outputs=False,
      _inspect_forward=None,
  ):
      perturbed_input = self._format_model_input(
          inp.to_model_input(perturbed_tensor)
      )
      init_model_inp = perturbed_input
  
      model_inp = init_model_inp
      model_kwargs = {
          "attention_mask": torch.tensor([[1] * model_inp.shape[1]])
      }
  
      log_prob_list = []
      outputs = None
      for target_token in target_tokens:
          if use_cached_outputs:
              if outputs is not None:
                  model_kwargs = (
                      self.model._update_model_kwargs_for_generation(
                          outputs, model_kwargs
                      )
                  )
              model_inputs = self.model.prepare_inputs_for_generation(
                  model_inp, **model_kwargs
              )
              outputs = self.model.forward(**model_inputs)
          else:
              outputs = self.model.forward(
                  model_inp,
                  attention_mask=torch.tensor(
                      [[1] * model_inp.shape[1]]
                  ),
              )
          new_token_logits = outputs.logits[:, -1]
          log_probs = torch.nn.functional.log_softmax(
              new_token_logits, dim=1
          )
  
          log_prob_list.append(log_probs[0][target_token].detach())
  
          model_inp = torch.cat(
              (
                  model_inp,
                  torch.tensor([[target_token]]).to(self.device),
              ),
              dim=1,
          )
  
      total_log_prob = sum(log_prob_list)
      # 1st element is the total prob, rest are the target tokens
      # add a leading dim for batch even we only support single instance for now
      if self.include_per_token_attr:
          target_log_probs = torch.stack(
              [total_log_prob, *log_prob_list], dim=0
          ).unsqueeze(0)
      else:
          target_log_probs = total_log_prob
      target_probs = torch.exp(target_log_probs)
  
      if _inspect_forward:
          prompt = self.tokenizer.decode(init_model_inp[0])
          response = self.tokenizer.decode(target_tokens)
  
          # callback for externals to inspect (prompt, response, seq_prob)
          _inspect_forward(prompt, response, target_probs[0].tolist())
  
      return (
          target_probs
          if self.attr_target != "log_prob"
          else target_log_probs
      )
  
imports: from copy import copy
  from typing import Callable, cast, Dict, List, Optional, Union
  import matplotlib.pyplot
  import numpy
  import torch
  from captum.attr._core.feature_ablation import FeatureAblation
  from captum.attr._core.kernel_shap import KernelShap
  from captum.attr._core.layer.layer_integrated_gradients import LayerIntegratedGradients
  from captum.attr._core.lime import Lime
  from captum.attr._core.shapley_value import ShapleyValues, ShapleyValueSampling
  from captum.attr._utils.attribution import Attribution
  from captum.attr._utils.interpretable_input import InterpretableInput, TextTemplateInput, TextTokenInput
  from torch import nn, Tensor
label_desc: Use image node_id 2 for calling the LLMAttribution obj's underlying member method code with example usage: obj._forward_func(perturbed_tensor, inp, target_tokens, use_cached_outputs, _inspect_forward) and returns: unknown