class_docstr: Multi-head attention module
class_docstr_tok: ["Multi-head","attention","module"]
code: def forward(self, inp, batch_idxs, qk_inp=None):
      residual = inp
  
      # While still using a packed representation, project to obtain the
      # query/key/value for each head
      q_s, k_s, v_s = self.split_qkv_packed(inp, qk_inp=qk_inp)
      # n_head x len_inp x d_kv
  
      # Switch to padded representation, perform attention, then switch back
      (
          q_padded,
          k_padded,
          v_padded,
          attn_mask,
          output_mask,
      ) = self.pad_and_rearrange(q_s, k_s, v_s, batch_idxs)
      # (n_head * batch) x len_padded x d_kv
  
      outputs_padded, attns_padded = self.attention(
          q_padded,
          k_padded,
          v_padded,
          attn_mask=attn_mask,
      )
      outputs = outputs_padded[output_mask]
      # (n_head * len_inp) x d_kv
      outputs = self.combine_v(outputs)
      # len_inp x d_model
  
      outputs = self.residual_dropout(outputs, batch_idxs)
  
      return self.layer_norm(outputs + residual), attns_padded
  
imports: import numpy
  import functools
  import sys
  import torch
  from torch.autograd import Variable
  import torch.nn
  import torch.nn.init
label_desc: Use image node_id 5 for calling the MultiHeadAttention obj's underlying member method code with example usage: obj.forward(inp, batch_idxs, qk_inp) and returns: self,  attns_padded