text: import torch.nn as nn
  from torch import Tensor
  from kospeech.models.modules import Linear, LayerNorm
  
  
  class AddNorm(nn.Module):
      """
      Add & Normalization layer proposed in "Attention Is All You Need".
      Transformer employ a residual connection around each of the two sub-layers,
      (Multi-Head Attention & Feed-Forward) followed by layer normalization.
      """
      def __init__(self, sublayer: nn.Module, d_model: int = 512) -> None:
          super(AddNorm, self).__init__()
          self.sublayer = sublayer
          self.layer_norm = LayerNorm(d_model)
  
      def forward(self, *args):
          residual = args[0]
          output = self.sublayer(*args)
  
          if isinstance(output, tuple):
              return self.layer_norm(output[0] + residual), output[1]
          else:
              return self.layer_norm(output + residual)
  
  
  class PoswiseFeedForwardNet(nn.Module):
      """
      Position-wise Feedforward Networks proposed in "Attention Is All You Need".
      Fully connected feed-forward network, which is applied to each position separately and identically.
      This consists of two linear transformations with a ReLU activation in between.
      Another way of describing this is as two convolutions with kernel size 1.
      """
      def __init__(self, d_model: int = 512, d_ff: int = 2048,
                   dropout_p: float = 0.3, ffnet_style: str = 'feed_forward') -> None:
          super(PoswiseFeedForwardNet, self).__init__()
          self.ffnet_style = ffnet_style.lower()
          if self.ffnet_style == 'ff':
              self.feed_forward = nn.Sequential(
                  Linear(d_model, d_ff),
                  nn.Dropout(dropout_p),
                  nn.ReLU(),
                  Linear(d_ff, d_model),
                  nn.Dropout(dropout_p)
              )
  
          elif self.ffnet_style == 'conv':
              self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)
              self.relu = nn.ReLU()
              self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)
  
          else:
              raise ValueError("Unsupported mode: {0}".format(self.mode))
  
      def forward(self, inputs: Tensor) -> Tensor:
          if self.ffnet_style == 'ff':
              output = self.feed_forward(inputs)
  
          else:
              output = self.conv1(inputs.transpose(1, 2))
              output = self.relu(output)
              output = self.conv2(output).transpose(1, 2)
  
          return output
  