class_docstr: Visual-lang Fusion Module.
class_docstr_tok: ["Visual-lang","Fusion","Module","."]
code: def forward(
      self, visual_feats: Tuple[Tensor], language_feats: dict
  ) -> Tuple:
      feat_inputs = {"visual": visual_feats, "lang": language_feats}
      dyhead_tower = self.dyhead_tower(feat_inputs)
  
      if self.early_fuse:
          embedding = dyhead_tower["lang"]["hidden"]
      else:
          embedding = language_feats["embedded"]
  
      embedding = F.normalize(embedding, p=2, dim=-1)
      dot_product_proj_tokens = self.dot_product_projection_text(
          embedding / 2.0
      )
      dot_product_proj_tokens_bias = (
          torch.matmul(embedding, self.bias_lang) + self.bias0
      )
  
      bbox_preds = []
      centerness = []
      cls_logits = []
  
      for i, feature in enumerate(visual_feats):
          visual = dyhead_tower["visual"][i]
          B, C, H, W = visual.shape
  
          bbox_pred = self.scales[i](self.bbox_pred(visual))
          bbox_preds.append(bbox_pred)
          centerness.append(self.centerness(visual))
  
          dot_product_proj_queries = permute_and_flatten(
              visual, B, self.num_base_priors, C, H, W
          )
  
          bias = dot_product_proj_tokens_bias.unsqueeze(1).repeat(
              1, self.num_base_priors, 1
          )
          dot_product_logit = (
              torch.matmul(
                  dot_product_proj_queries,
                  dot_product_proj_tokens.transpose(-1, -2),
              )
              / self.log_scale.exp()
          ) + bias
          dot_product_logit = torch.clamp(
              dot_product_logit, max=MAX_CLAMP_VALUE
          )
          dot_product_logit = torch.clamp(
              dot_product_logit, min=-MAX_CLAMP_VALUE
          )
          cls_logits.append(dot_product_logit)
  
      return bbox_preds, centerness, cls_logits
  
imports: import copy
  import math
  from typing import Callable, List, Optional, Sequence, Tuple, Union
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import Scale
  from mmcv.ops.modulated_deform_conv import ModulatedDeformConv2d
  from mmengine.config import ConfigDict
  from mmengine.model import BaseModel
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.registry import MODELS
  from mmdet.structures.bbox import cat_boxes
  from mmdet.utils import InstanceList, OptInstanceList, reduce_mean
  from ..utils import BertEncoderLayer, VLFuse, filter_scores_and_topk, permute_and_flatten, select_single_mlvl, unpack_gt_instances
  from ..utils.vlfuse_helper import MAX_CLAMP_VALUE
  from .atss_head import ATSSHead
label_desc: Use image node_id 3 for calling the VLFusionModule obj's underlying member method code with example usage: obj.forward(visual_feats, language_feats) and returns: bbox_preds,  centerness,  cls_logits