class_docstr: Allows the model to jointly attend to information
  from different representation subspaces.
  See reference: Attention Is All You Need
  
  .. math::
              ext{MultiHead}(Q, K, V) =       ext{Concat}(head_1,\dots,head_h)W^O
              ext{where} head_i =     ext{Attention}(QW_i^Q, KW_i^K, VW_i^V)
  
  Args:
      embed_dim: total dimension of the model
      num_heads: parallel attention layers, or heads
class_docstr_tok: ["Allows","the","model","to","jointly","attend","to","information","from","different","representation","subspaces",".","See","reference",":","Attention","Is","All","You","Need","..","math",":",":","ext","{","MultiHead","}","(","Q",",","K",",","V",")","=","ext","{","Concat","}","(","head_1",",","\\dots",",","head_h",")","W^O","ext","{","where","}","head_i","=","ext","{","Attention","}","(","QW_i^Q",",","KW_i^K",",","VW_i^V",")","Args",":","embed_dim",":","total","dimension","of","the","model","num_heads",":","parallel","attention","layers",",","or","heads"]
code: def forward(self, query, key=None, attn_mask=None):
      qN = query.shape[1]
  
      if self.self_attn:
          qkv = (
              self.qkv(query)
              .reshape((0, qN, 3, self.num_heads, self.head_dim))
              .transpose((2, 0, 3, 1, 4))
          )
          q, k, v = qkv[0], qkv[1], qkv[2]
      else:
          kN = key.shape[1]
          q = (
              self.q(query)
              .reshape([0, qN, self.num_heads, self.head_dim])
              .transpose([0, 2, 1, 3])
          )
          kv = (
              self.kv(key)
              .reshape((0, kN, 2, self.num_heads, self.head_dim))
              .transpose((2, 0, 3, 1, 4))
          )
          k, v = kv[0], kv[1]
  
      attn = (q.matmul(k.transpose((0, 1, 3, 2)))) * self.scale
  
      if attn_mask is not None:
          attn += attn_mask
  
      attn = F.softmax(attn, axis=-1)
      attn = self.attn_drop(attn)
  
      x = (
          (attn.matmul(v))
          .transpose((0, 2, 1, 3))
          .reshape((0, qN, self.embed_dim))
      )
      x = self.out_proj(x)
  
      return x
  
imports: import math
  import paddle
  from paddle import nn
  import paddle.nn.functional
  from paddle.nn import LayerList
  from paddle.nn import Dropout, Linear, LayerNorm
  import numpy
  from ppocr.modeling.backbones.rec_svtrnet import Mlp, zeros_, ones_
  from paddle.nn.initializer import XavierNormal
label_desc: Use image node_id 2 for calling the MultiheadAttention obj's underlying member method code with example usage: obj.forward(query, key, attn_mask) and returns: x