class_docstr: **Star-Transformer** 的 encoder 部分。输入 3d 的文本输入，返回相同长度的文本编码。
  基于论文 `Star-Transformer <https://arxiv.org/abs/1902.09113>`_
  
  :param hidden_size: 输入维度的大小，同时也是输出维度的大小。
  :param num_layers: **Star-Transformer** 的层数
  :param num_head: **多头注意力** head 的数目，需要能被 ``d_model`` 整除
  :param head_dim: 每个 ``head`` 的维度大小。
  :param dropout: dropout 概率
  :param max_len: 如果为 :class:`int` 表示输入序列的最大长度，模型会为输入序列加上 ``position embedding``；
      若为 ``None`` 则会跳过此步骤。
docstr: :param data: 输入序列，形状为 ``[batch_size, length, hidden]``
  :param mask: 输入序列的 padding mask， 形状为 ``[batch_size, length]`` , 为 **0** 的地方为 padding
  :return: 返回一个元组，第一个元素形状为 ``[batch_size, length, hidden]`` ，代表编码后的输出序列；
      第二个元素形状为 ``[batch_size, hidden]``，表示全局 relay 节点, 详见论文。
docstr_tok: [":","param","data",":","\u8f93\u5165\u5e8f\u5217\uff0c\u5f62\u72b6\u4e3a","``","[","batch_size",",","length",",","hidden","]","``",":","param","mask",":","\u8f93\u5165\u5e8f\u5217\u7684","padding","mask\uff0c","\u5f62\u72b6\u4e3a","``","[","batch_size",",","length","]","``",",","\u4e3a","*","*","0","*","*","\u7684\u5730\u65b9\u4e3a","padding",":","return",":","\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u7b2c\u4e00\u4e2a\u5143\u7d20\u5f62\u72b6\u4e3a","``","[","batch_size",",","length",",","hidden","]","``","\uff0c\u4ee3\u8868\u7f16\u7801\u540e\u7684\u8f93\u51fa\u5e8f\u5217\uff1b","\u7b2c\u4e8c\u4e2a\u5143\u7d20\u5f62\u72b6\u4e3a","``","[","batch_size",",","hidden","]","``","\uff0c\u8868\u793a\u5168\u5c40","relay","\u8282\u70b9",",","\u8be6\u89c1\u8bba\u6587\u3002"]
code: def forward(self, data: torch.FloatTensor, mask: torch.ByteTensor):
      r"""
      :param data: 输入序列，形状为 ``[batch_size, length, hidden]``
      :param mask: 输入序列的 padding mask， 形状为 ``[batch_size, length]`` , 为 **0** 的地方为 padding
      :return: 返回一个元组，第一个元素形状为 ``[batch_size, length, hidden]`` ，代表编码后的输出序列；
          第二个元素形状为 ``[batch_size, hidden]``，表示全局 relay 节点, 详见论文。
      """
  
      def norm_func(f, x):
          # B, H, L, 1
          return f(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)
  
      B, L, H = data.size()
      mask = mask.eq(False)  # flip the mask for masked_fill_
      smask = torch.cat(
          [
              torch.zeros(
                  B,
                  1,
              )
              .byte()
              .to(mask),
              mask,
          ],
          1,
      )
  
      embs = data.permute(0, 2, 1)[:, :, :, None]  # B H L 1
      if self.pos_emb:
          P = (
              self.pos_emb(
                  torch.arange(
                      L, dtype=torch.long, device=embs.device
                  ).view(1, L)
              )
              .permute(0, 2, 1)
              .contiguous()[:, :, :, None]
          )  # 1 H L 1
          embs = embs + P
      embs = norm_func(self.emb_drop, embs)
      nodes = embs
      relay = embs.mean(2, keepdim=True)
      ex_mask = mask[:, None, :, None].expand(B, H, L, 1)
      r_embs = embs.view(B, H, 1, L)
      for i in range(self.iters):
          ax = torch.cat([r_embs, relay.expand(B, H, 1, L)], 2)
          nodes = F.leaky_relu(
              self.ring_att[i](norm_func(self.norm[i], nodes), ax=ax)
          )
          # nodes = F.leaky_relu(self.ring_att[i](nodes, ax=ax))
          relay = F.leaky_relu(
              self.star_att[i](
                  relay, torch.cat([relay, nodes], 2), smask
              )
          )
  
          nodes = nodes.masked_fill_(ex_mask, 0)
  
      nodes = nodes.view(B, H, L).permute(0, 2, 1)
  
      return nodes, relay.view(B, H)
  
file_path: fastNLP/fastNLP/modules/torch/encoder/star_transformer.py
imports: import numpy
  import torch
  from torch import nn
  from torch.nn import functional
label_desc: Use image node_id 2 for calling the StarTransformer obj's underlying member method code with example usage: obj.forward(data, mask) and returns: nodes,  relay, f