class_docstr: Ecco's central class. A wrapper around language models. We use it to run the language models
  and collect important data like input saliency and neuron activations.
  
  A LM object is typically not created directly by users,
  it is returned by `ecco.from_pretrained()`.
  
  Usage:
  
  ```python
  import ecco
  
  lm = ecco.from_pretrained('distilgpt2')
  output = lm.generate("Hello computer")
  ```
docstr: Creates an LM object given a model and tokenizer.
  
  Args:
      model: HuggingFace Transformers Pytorch language model.
      tokenizer: The tokenizer associated with the model
      model_name: The name of the model. Used to retrieve required settings (like what the embedding layer is called)
      config: Configuration that has the information about the layer whose activations we will collect
      collect_activations_flag: True if we want to collect activations
      collect_activations_layer_nums: If collecting activations, we can use this parameter to indicate which layers
          to track. By default this would be None and we'd collect activations for all layers.
      verbose: If True, model.generate() displays output tokens in HTML as they're generated.
      gpu: Set to False to force using the CPU even if a GPU exists.
code: def __init__(
      self,
      model: transformers.PreTrainedModel,
      tokenizer: transformers.PreTrainedTokenizerFast,
      model_name: str,
      config: Dict[str, Any],
      collect_activations_flag: Optional[bool] = False,
      collect_activations_layer_nums: Optional[
          List[int]
      ] = None,  # None --> collect for all layers
      verbose: Optional[bool] = True,
      gpu: Optional[bool] = True,
  ):
      """
      Creates an LM object given a model and tokenizer.
  
      Args:
          model: HuggingFace Transformers Pytorch language model.
          tokenizer: The tokenizer associated with the model
          model_name: The name of the model. Used to retrieve required settings (like what the embedding layer is called)
          config: Configuration that has the information about the layer whose activations we will collect
          collect_activations_flag: True if we want to collect activations
          collect_activations_layer_nums: If collecting activations, we can use this parameter to indicate which layers
              to track. By default this would be None and we'd collect activations for all layers.
          verbose: If True, model.generate() displays output tokens in HTML as they're generated.
          gpu: Set to False to force using the CPU even if a GPU exists.
      """
      self.model_name = model_name
      self.model = model
      if torch.cuda.is_available() and gpu:
          self.model = model.to("cuda")
  
      self.device = (
          "cuda"
          if torch.cuda.is_available()
          and self.model.device.type == "cuda"
          else "cpu"
      )
  
      self.tokenizer = tokenizer
      self.verbose = verbose
      self._path = os.path.dirname(ecco.__file__)
  
      # Neuron Activation
      self.collect_activations_flag = collect_activations_flag
      self.collect_activations_layer_nums = (
          collect_activations_layer_nums
      )
  
      # For each model, this indicates the layer whose activations
      # we will collect
      self.model_config = config
      try:
          self.model_type = self.model_config["type"]
          embeddings_layer_name = self.model_config["embedding"]
          embed_retriever = attrgetter(embeddings_layer_name)
          if type(embed_retriever(self.model)) == torch.nn.Embedding:
              self.model_embeddings = embed_retriever(self.model).weight
          else:
              self.model_embeddings = embed_retriever(self.model)
          self.collect_activations_layer_name_sig = self.model_config[
              "activations"
          ][0]
      except KeyError:
          raise ValueError(
              f"The model '{self.model_name}' is not correctly configured in Ecco's 'model-config.yaml' file"
          ) from KeyError()
  
      assert self.model_type in [
          "causal",
          "mlm",
          "enc-dec",
      ], f"model type {self.model_type} not found"
  
      self._reset()
  
imports: from collections import defaultdict
  import inspect
  import json
  import os
  import random
  import torch
  import transformers
  from transformers import BatchEncoding
  import ecco
  import numpy
  from IPython import display
  from torch.nn import functional
  from ecco.attribution import compute_primary_attributions_scores
  from ecco.output import OutputSeq
  from typing import Optional, Any, List, Tuple, Dict, Union
  from operator import attrgetter
  import re
  from ecco.util import is_partial_token, strip_tokenizer_prefix
  from packaging import version
label_desc: Use image node_id 1 to create a new LM object from inherited base classes: object with example: obj = LM(model, tokenizer, model_name, config, collect_activations_flag, collect_activations_layer_nums, verbose, gpu)