docstr: The `MultiHeadAttention` module optionally accepts `kv_cache` which stores the key and value
  tensors calculated for the previous positions. This method returns a dictionary that stores
  all caches, and the necessary hooks for the key and value projection modules that save the
  intermediate tensors to be reused during later calculations.
  
  Returns
  -------
  cache : Dict[nn.Module, torch.Tensor]
      A dictionary object mapping the key/value projection modules to its cache
  hooks : List[RemovableHandle]
      List of PyTorch RemovableHandle objects to stop the hooks to be called
docstr_tok: ["The","`","MultiHeadAttention","`","module","optionally","accepts","`","kv_cache","`","which","stores","the","key","and","value","tensors","calculated","for","the","previous","positions",".","This","method","returns","a","dictionary","that","stores","all","caches",",","and","the","necessary","hooks","for","the","key","and","value","projection","modules","that","save","the","intermediate","tensors","to","be","reused","during","later","calculations",".","Returns","--","--","--","-","cache",":","Dict","[","nn.Module",",","torch.Tensor","]","A","dictionary","object","mapping","the","key\/value","projection","modules","to","its","cache","hooks",":","List","[","RemovableHandle","]","List","of","PyTorch","RemovableHandle","objects","to","stop","the","hooks","to","be","called"]
code: def install_kv_cache_hooks(self, cache: Optional[dict] = None):
      """
      The `MultiHeadAttention` module optionally accepts `kv_cache` which stores the key and value
      tensors calculated for the previous positions. This method returns a dictionary that stores
      all caches, and the necessary hooks for the key and value projection modules that save the
      intermediate tensors to be reused during later calculations.
  
      Returns
      -------
      cache : Dict[nn.Module, torch.Tensor]
          A dictionary object mapping the key/value projection modules to its cache
      hooks : List[RemovableHandle]
          List of PyTorch RemovableHandle objects to stop the hooks to be called
      """
      cache = {**cache} if cache is not None else {}
      hooks = []
  
      def save_to_cache(module, _, output):
          if (
              module not in cache
              or output.shape[1] > self.dims.n_text_ctx
          ):
              # save as-is, for the first token or cross attention
              cache[module] = output
          else:
              cache[module] = torch.cat(
                  [cache[module], output], dim=1
              ).detach()
          return cache[module]
  
      def install_hooks(layer: nn.Module):
          if isinstance(layer, MultiHeadAttention):
              hooks.append(
                  layer.key.register_forward_hook(save_to_cache)
              )
              hooks.append(
                  layer.value.register_forward_hook(save_to_cache)
              )
  
      self.decoder.apply(install_hooks)
      return cache, hooks
  
imports: import base64
  import gzip
  from dataclasses import dataclass
  from typing import Dict, Iterable, Optional
  import numpy
  import torch
  import torch.nn.functional
  from torch import Tensor, nn
  from .decoding import decode
  from .decoding import detect_language
  from .transcribe import transcribe
label_desc: Use image node_id 9 for calling the Whisper obj's underlying member method code with example usage: obj.install_kv_cache_hooks(cache) and returns: cache,  hooks, cache