code: def forward(self, sample_list):
      # If we have different combine modes, may need to call in different order
      if self.config.feed_graph_to_vb:
          # Can't be both (would create circular dep)
          assert not self.config.feed_vb_to_graph
  
          # Check mode
          # Can be feed_graph_hid_to_vb, where we pass in some vector
          # rep of graph into vb or feed_top_node_to_vb which is similar,
          # but it feeds in k node hidden states
          assert self.config.feed_mode in [
              "feed_graph_hid_to_vb",
              "feed_top_node_to_vb",
          ]
          if self.config.feed_mode == "feed_graph_hid_to_vb":
              assert self.graph_module.gn.output_special_node
          else:
              raise Exception(
                  "Unknown feed mode %s" % self.config.feed_mode
              )
  
          # Forward through graph module
          graph_output = self.graph_module(sample_list)
  
          # Put graph_output into sample_list
          sample_list["graph_output"] = graph_output
  
          # Forward through vb module
          vb_hidden = self.vb_module(sample_list)
  
          # Get vocab logit preds
          vb_logits = self.vocab_fc(vb_hidden)
  
      else:
          # Check mode
          if self.config.feed_vb_to_graph:
              # Can be feed_vb_hid_to_graph where we feed final
              # vb state into graph as a node input
              # Or feed_vb_logit_to_graph where we feed vg_predicted logits into graph
              assert self.config.feed_mode in [
                  "feed_vb_hid_to_graph",
                  "feed_vb_logit_to_graph",
              ]
  
          # Forward through vb module
          vb_hidden = self.vb_module(sample_list)
  
          # Get vocab logit preds
          vb_logits = self.vocab_fc(vb_hidden)
  
          sample_list["vb_hidden"] = vb_hidden
          sample_list["vb_logits"] = vb_logits
  
          # If we feed seperate Q feats into graph
          if self.config.feed_q_to_graph:
              # Now sample_list has all the processed inputs for us
              attention_mask_q = (sample_list["input_ids"] != 0).float()
              q_enc_out = self.q_enc(
                  input_ids=sample_list["input_ids"],
                  attention_mask=attention_mask_q,
                  token_type_ids=sample_list["token_type_ids"],
              )
              sample_list["q_encoded"] = q_enc_out[
                  1
              ]  # Get pooled output
  
          # Forward through graph module
          graph_output = self.graph_module(sample_list)
  
      # Compute graph logits
      if self.config.graph_logit_mode == "mc4":
          # Use bilinear network
          if self.config.noback_vb_to_blinear:
              graph_logits = self.graph_ptr_net(
                  vb_hidden.detach(), graph_output
              )
          else:
              graph_logits = self.graph_ptr_net(vb_hidden, graph_output)
  
      elif self.config.graph_logit_mode == "in_graph":
          # Logits is already computed
          graph_logits = graph_output
          assert (
              self.config.graph_module.output_type == "graph_prediction"
          )
      elif self.config.graph_logit_mode == "logit_fc":
          # Compute logits from single hidden layer
          graph_logits = self.graph_logit_fc(graph_output)
  
      # Now combine outputs
      if self.config.output_combine == "concat":
          # Output order should be alphabetical
          assert self.config.graph_module.output_order == "alpha"
  
          # Combine both logits
          logits = torch.cat([vb_logits, graph_logits], dim=1)
      elif self.config.output_combine == "add":
          # Output order should be ans
          assert self.config.graph_module.output_order == "ans"
  
          # Set invalid inds to zero here
          assert graph_logits.size(1) == vb_logits.size(1)
          graph_logits[:, self.missing_ans_inds] = 0
          logits = vb_logits + graph_logits
  
      # Do zerobias
      if self.config.zerobias:
          logits -= 6.58
  
      # For loss calculations (automatically done by MMF
      # as per the loss defined in the config),
      # we need to return a dict with "scores" key as logits
      output = {"scores": logits}
  
      # If we're in eval / analysis mode, add more to output
      if self.config.analysis_mode:
          output = self.graph_module.add_analysis_to_output(output)
  
      # MMF will automatically calculate loss
      return output
  
imports: import logging
  import math
  import os
  import torch
  from mmf.common.registry import registry
  from mmf.models import BaseModel
  from mmf.modules.embeddings import BertVisioLinguisticEmbeddings
  from mmf.utils.configuration import get_mmf_cache_dir
  from mmf.utils.file_io import PathManager
  from mmf.utils.modeling import get_optimizer_parameters_for_bert
  from mmf.utils.transform import transform_to_batch_sequence, transform_to_batch_sequence_dim
  from omegaconf import OmegaConf
  from torch import nn
label_desc: Use image node_id 4 for calling the KRISP obj's underlying member method code with example usage: obj.forward(sample_list) and returns: output