code: def transformer_encoder_ffn_unit(x,
                                   hparams,
                                   nonpadding_mask=None,
                                   pad_remover=None):
    
  
    with tf.variable_scope("ffn"):
      if hparams.transformer_ffn_type == "fc":
        y = transformer.transformer_ffn_layer(
            common_layers.layer_preprocess(x, hparams),
            hparams,
            pad_remover,
            conv_padding="SAME",
            nonpadding_mask=nonpadding_mask)
  
      if hparams.transformer_ffn_type == "sepconv":
        assert nonpadding_mask is not None, (
            "The nonpadding_mask should be provided, otherwise the model uses "
            "the leaked padding information to estimate the length!")
        y = common_layers.sepconv_relu_sepconv(
            common_layers.layer_preprocess(x, hparams),
            filter_size=hparams.filter_size,
            output_size=hparams.hidden_size,
            first_kernel_size=(3, 1),
            second_kernel_size=(5, 1),
            padding="SAME",
            nonpadding_mask=nonpadding_mask,
            dropout=hparams.relu_dropout)
  
      x = common_layers.layer_postprocess(x, y, hparams)
  
    return x
docs: Applies a feed-forward function which is parametrised for encoding.
  
    Args:
      x: input
      hparams: model hyper-parameters
      nonpadding_mask: optional Tensor with shape [batch_size, encoder_length]
      indicating what positions are not padding.  This is used
      to mask out padding in convoltutional layers.  We generally only
      need this mask for "packed" datasets, because for ordinary datasets,
      no padding is ever followed by nonpadding.
      pad_remover: to mask out padding in convolutional layers (efficiency).
  
    Returns:
      the output tensor