def METHOD_NAME(self, frames_BxLxM, seq_lengths_B, testing):
    """
    Input:
        frames_BxLxM: a 3d-tensor representing the input features.
        seq_lengths_B: sequence length of frames_BxLxM.
        testing: a bool indicating training or testing phase.
    Return:
        predicted_BxLxM: the predicted output; used for training.
        hiddens_NxBxLxH: the RNN hidden representations across all layers.
    """
    max_seq_len = frames_BxLxM.size(1)
    # N is the number of RNN layers.
    hiddens_NxBxLxH = []
    # RNN
    # Prepare initial packed RNN input.
    packed_rnn_inputs = pack_padded_sequence(
        frames_BxLxM, seq_lengths_B, batch_first=True, enforce_sorted=False
    )
    for i, rnn_layer in enumerate(self.rnn_layers):
        # https://discuss.pytorch.org/t/rnn-module-weights-are-not-part-of-single-contiguous-chunk-of-memory/6011/14
        rnn_layer.flatten_parameters()
        packed_rnn_outputs, _ = rnn_layer(packed_rnn_inputs)
        # Unpack RNN output of current layer.
        rnn_outputs_BxLxH, _ = pad_packed_sequence(
            packed_rnn_outputs, batch_first=True, total_length=max_seq_len
        )
        # Apply dropout to output.
        rnn_outputs_BxLxH = self.rnn_dropout(rnn_outputs_BxLxH)
        # Apply residual connections.
        if self.rnn_residual and i > 0:
            # Unpack the original input.
            rnn_inputs_BxLxH, _ = pad_packed_sequence(
                packed_rnn_inputs, batch_first=True, total_length=max_seq_len
            )
            rnn_outputs_BxLxH += rnn_inputs_BxLxH
        hiddens_NxBxLxH.append(rnn_outputs_BxLxH)
        # VQ at last layer only
        if self.apply_vq and (i == len(self.rnn_layers) - 1):
            q_feat = []
            offet = 0
            for vq_layer, cd in zip(self.vq_layers, self.vq_code_dims):
                _, q_f = vq_layer(
                    rnn_outputs_BxLxH[:, :, offet : offet + cd], testing
                )
                q_feat.append(q_f)
                offet += cd
            rnn_outputs_BxLxH = torch.cat(q_feat, dim=-1)
        # Prepare packed input for the next layer.
        # Note : enforce sorted = False might lead to CUDNN_STATUS_EXECUTION_FAILED
        if i < len(self.rnn_layers) - 1:
            packed_rnn_inputs = pack_padded_sequence(
                rnn_outputs_BxLxH,
                seq_lengths_B,
                batch_first=True,
                enforce_sorted=False,
            )
    # Only return last layer feature
    feature = hiddens_NxBxLxH[-1]
    # Generate final output from codes.
    predicted_BxLxM = self.postnet(rnn_outputs_BxLxH)
    return predicted_BxLxM, feature