Parameters
        ----------
        F
        samples : NDArray or Symbol
            The current samples generated by beam search. Shape (batch_size, beam_size, L)
        valid_length : NDArray or Symbol
            The current valid lengths of the samples
        outputs: NDArray or Symbol
            Decoder output (unnormalized) scores of the current step.
            Shape (batch_size * beam_size, V)
        scores : NDArray or Symbol
            The previous scores. Shape (batch_size, beam_size)
        beam_alive_mask : NDArray or Symbol
            Shape (batch_size, beam_size)
        states : nested structure of NDArrays/Symbols
            Inner NDArrays have shape (batch_size * beam_size, ...)

        Returns
        -------
        new_samples : NDArray or Symbol
            The updated samples. Shape (batch_size, beam_size, L + 1)
        new_valid_length : NDArray or Symbol
            Valid lengths of the samples. Shape (batch_size, beam_size)
        new_scores : NDArray or Symbol
            Shape (batch_size, beam_size)
        chosen_word_ids : NDArray or Symbol
            The chosen word ids of the step. Shape (batch_size, beam_size). If it's negative,
            no word will be appended to the beam.
        beam_alive_mask : NDArray or Symbol
            Shape (batch_size, beam_size)
        new_states : nested structure of NDArrays/Symbols
            Inner NDArrays have shape (batch_size * beam_size, ...)

def hybrid_forward(self, F, samples, valid_length, outputs, scores, beam_alive_mask, states):
        """
        Parameters
        ----------
        F
        samples : NDArray or Symbol
            The current samples generated by beam search. Shape (batch_size, beam_size, L)
        valid_length : NDArray or Symbol
            The current valid lengths of the samples
        outputs: NDArray or Symbol
            Decoder output (unnormalized) scores of the current step.
            Shape (batch_size * beam_size, V)
        scores : NDArray or Symbol
            The previous scores. Shape (batch_size, beam_size)
        beam_alive_mask : NDArray or Symbol
            Shape (batch_size, beam_size)
        states : nested structure of NDArrays/Symbols
            Inner NDArrays have shape (batch_size * beam_size, ...)

        Returns
        -------
        new_samples : NDArray or Symbol
            The updated samples. Shape (batch_size, beam_size, L + 1)
        new_valid_length : NDArray or Symbol
            Valid lengths of the samples. Shape (batch_size, beam_size)
        new_scores : NDArray or Symbol
            Shape (batch_size, beam_size)
        chosen_word_ids : NDArray or Symbol
            The chosen word ids of the step. Shape (batch_size, beam_size). If it's negative,
            no word will be appended to the beam.
        beam_alive_mask : NDArray or Symbol
            Shape (batch_size, beam_size)
        new_states : nested structure of NDArrays/Symbols
            Inner NDArrays have shape (batch_size * beam_size, ...)
        """
        beam_size = self._beam_size
        # outputs: (batch_size, beam_size, vocab_size)
        outputs = outputs.reshape(shape=(-4, -1, beam_size, 0))
        smoothed_probs = (outputs / self._temperature).softmax(axis=2)
        log_probs = F.log_softmax(outputs, axis=2).reshape(-3, -1)

        # (batch_size, beam_size)
        chosen_word_ids = F.sample_multinomial(smoothed_probs, dtype=np.int32)
        chosen_word_ids = F.where(beam_alive_mask,
                                  chosen_word_ids,
                                  -1*F.ones_like(beam_alive_mask))
        chosen_word_log_probs = log_probs[mx.nd.arange(log_probs.shape[0]),
                                          chosen_word_ids.reshape(-1)].reshape(-4, -1, beam_size)

        # Don't update for finished beams
        new_scores = scores + F.where(beam_alive_mask,
                                      chosen_word_log_probs,
                                      F.zeros_like(chosen_word_log_probs))
        new_valid_length = valid_length + beam_alive_mask

        # Update the samples and vaild_length
        new_samples = F.concat(samples, chosen_word_ids.expand_dims(2), dim=2)

        # Update the states
        new_states = states

        # Update the alive mask.
        beam_alive_mask = beam_alive_mask * (chosen_word_ids != self._eos_id)

        return new_samples, new_valid_length, new_scores,\
               chosen_word_ids, beam_alive_mask, new_states