docstr: Produces logits tensor for finetuning the model.
  
  Args:
      inputs: Inputs to the model. Can be a dictionary of input names to
          input tensors or a tuple of (inputs, targets) where inputs is
          a dictionary of input names to input tensors and targets is a
          dictionary of target names to target tensors.
      mask: A mask for the inputs.
  
  Returns:
      A dictionary of output {feature name}::{tensor_name} -> output tensor.
docstr_tok: ["Produces","logits","tensor","for","finetuning","the","model",".","Args",":","inputs",":","Inputs","to","the","model",".","Can","be","a","dictionary","of","input","names","to","input","tensors","or","a","tuple","of","(","inputs",",","targets",")","where","inputs","is","a","dictionary","of","input","names","to","input","tensors","and","targets","is","a","dictionary","of","target","names","to","target","tensors",".","mask",":","A","mask","for","the","inputs",".","Returns",":","A","dictionary","of","output","{","feature","name","}",":",":","{","tensor_name","}","-",">","output","tensor","."]
code: def forward(
      self,
      inputs: Union[
          Dict[str, torch.Tensor],
          Dict[str, np.ndarray],
          Tuple[Dict[str, torch.Tensor], Dict[str, torch.Tensor]],
      ],
      mask=None,
  ) -> Dict[str, torch.Tensor]:
      """Produces logits tensor for finetuning the model.
  
      Args:
          inputs: Inputs to the model. Can be a dictionary of input names to
              input tensors or a tuple of (inputs, targets) where inputs is
              a dictionary of input names to input tensors and targets is a
              dictionary of target names to target tensors.
          mask: A mask for the inputs.
  
      Returns:
          A dictionary of output {feature name}::{tensor_name} -> output tensor.
      """
      input_ids, target_ids = self._unpack_inputs(inputs)
  
      # Generate merged input_id, target_id pairs for the model, and create corresponding attention masks
      # We save them as class variables so that we can use them when realigning target and prediction tensors
      self.model_inputs, self.attention_masks = generate_merged_ids(
          input_ids,
          target_ids,
          self.tokenizer,
          self.global_max_sequence_length,
      )
  
      # Wrap with flash attention backend for faster generation
      with torch.backends.cuda.sdp_kernel(
          enable_flash=True,
          enable_math=False,
          enable_mem_efficient=False,
      ) if (
          torch.cuda.is_available() and self.curr_device.type == "cuda"
      ) else contextlib.nullcontext():
          # TODO (jeffkinnison): Determine why the 8-bit `SCB` and `CB` matrices are deleted in the forward pass
          model_outputs = self.model(
              input_ids=self.model_inputs,
              attention_mask=self.attention_masks,
          ).get(LOGITS)
  
      if self.output_feature_type != TEXT:
          # Pass generated tokens through decoder after averaging the token probabilities
          # This is required for the classification head for the classifier decoder
          model_outputs = torch.mean(model_outputs, dim=1)
  
      if self.output_feature_type == TEXT:
          decoder_outputs = model_outputs
      else:
          decoder_outputs = self.output_feature_decoder.decoder_obj(
              model_outputs
          )
  
      # Set the output feature tensor to the decoder outputs (logits)
      outputs = {}
      of_name = self.config_obj.output_features[0].name
      set_output_feature_tensor(
          outputs, of_name, LOGITS, decoder_outputs
      )
  
      # Get predictions, probabilities and logits tensor from the output feature's predictions function
      outputs = self.output_features.get(of_name).predictions(
          outputs, of_name
      )
  
      # Cast to float32 for metric computation incase we're using deespeed with
      # reduced precision such as bfloat16.
      for prediction_key, prediction_tensor in outputs.items():
          if prediction_key != PREDICTIONS:
              # Skipping casting it to float32 since the predictions are tokens and they should be int64
              # (which is already the case)
              outputs[prediction_key] = prediction_tensor.type(
                  torch.float32
              )
  
      # Add token usage.
      outputs[USED_TOKENS] = get_used_tokens_for_llm(
          self.model_inputs, self.tokenizer
      )
      return outputs
  
imports: import contextlib
  import logging
  import os
  from typing import Any, Dict, List, Optional, Tuple, Union
  import numpy
  import torch
  from transformers import AutoConfig, GenerationConfig
  from ludwig.accounting.used_tokens import get_used_tokens_for_llm
  from ludwig.constants import IGNORE_INDEX_TOKEN_ID, LOGITS, MODEL_LLM, PREDICTIONS, TEXT, USED_TOKENS
  from ludwig.features.base_feature import ModuleWrapper, OutputFeature
  from ludwig.features.feature_utils import LudwigFeatureDict
  from ludwig.features.text_feature import TextOutputFeature
  from ludwig.globals import MODEL_WEIGHTS_FILE_NAME
  from ludwig.models.base import BaseModel
  from ludwig.modules.training_hooks import NEFTuneHook
  from ludwig.schema.features.base import BaseOutputFeatureConfig, FeatureCollection
  from ludwig.schema.model_types.llm import LLMModelConfig
  from ludwig.utils.augmentation_utils import AugmentationPipelines
  from ludwig.utils.data_utils import clear_data_cache
  from ludwig.utils.llm_quantization_utils import convert_quantized_linear_to_linear
  from ludwig.utils.llm_utils import add_left_padding, generate_merged_ids, get_context_len, get_realigned_target_and_prediction_tensors_for_inference, initialize_adapter, load_pretrained_from_config, pad_target_tensor_for_fine_tuning, remove_left_padding, to_device
  from ludwig.utils.logging_utils import log_once
  from ludwig.utils.output_feature_utils import set_output_feature_tensor
  from ludwig.utils.tokenizers import HFTokenizer
  from ludwig.utils.torch_utils import reg_loss
label_desc: Use image node_id 12 for calling the LLM obj's underlying member method code with example usage: obj.forward(inputs, mask) and returns: outputs