class_docstr: A complete encoder-decoder model, with optional attention.
  
  A parent class which makes use of the contextual_embedding (such as a charlm)
  can make use of unsaved_modules when saving.
class_docstr_tok: ["A","complete","encoder-decoder","model",",","with","optional","attention",".","A","parent","class","which","makes","use","of","the","contextual_embedding","(","such","as","a","charlm",")","can","make","use","of","unsaved_modules","when","saving","."]
docstr: Decode a step, based on context encoding and source context states.
docstr_tok: ["Decode","a","step",",","based","on","context","encoding","and","source","context","states","."]
code: def decode(self, dec_inputs, hn, cn, ctx, ctx_mask=None, src=None):
      """Decode a step, based on context encoding and source context states."""
      dec_hidden = (hn, cn)
      decoder_output = self.decoder(
          dec_inputs,
          dec_hidden,
          ctx,
          ctx_mask,
          return_logattn=self.copy,
      )
      if self.copy:
          h_out, dec_hidden, log_attn = decoder_output
      else:
          h_out, dec_hidden = decoder_output
  
      h_out_reshape = h_out.contiguous().view(
          h_out.size(0) * h_out.size(1), -1
      )
      decoder_logits = self.dec2vocab(h_out_reshape)
      decoder_logits = decoder_logits.view(
          h_out.size(0), h_out.size(1), -1
      )
      log_probs = self.get_log_prob(decoder_logits)
  
      if self.copy:
          copy_logit = self.copy_gate(h_out)
          if self.use_pos:
              # can't copy the UPOS
              log_attn = log_attn[:, :, 1:]
  
          # renormalize
          log_attn = torch.log_softmax(log_attn, -1)
          # calculate copy probability for each word in the vocab
          log_copy_prob = (
              torch.nn.functional.logsigmoid(copy_logit) + log_attn
          )
          # scatter logsumexp
          mx = log_copy_prob.max(-1, keepdim=True)[0]
          log_copy_prob = log_copy_prob - mx
          copy_prob = torch.exp(log_copy_prob)
          copied_vocab_prob = log_probs.new_zeros(
              log_probs.size()
          ).scatter_add(
              -1,
              src.unsqueeze(1).expand(
                  src.size(0), copy_prob.size(1), src.size(1)
              ),
              copy_prob,
          )
          zero_mask = copied_vocab_prob == 0
          log_copied_vocab_prob = (
              torch.log(copied_vocab_prob.masked_fill(zero_mask, 1e-12))
              + mx
          )
          log_copied_vocab_prob = log_copied_vocab_prob.masked_fill(
              zero_mask, -1e12
          )
  
          # combine with normal vocab probability
          log_nocopy_prob = -torch.log(1 + torch.exp(copy_logit))
          log_probs = log_probs + log_nocopy_prob
          log_probs = torch.logsumexp(
              torch.stack([log_copied_vocab_prob, log_probs]), 0
          )
  
      return log_probs, dec_hidden
  
imports: import logging
  import torch
  from torch import nn
  import torch.nn.functional
  import numpy
  import stanza.models.common.seq2seq_constant
  from stanza.models.common import utils
  from stanza.models.common.seq2seq_modules import LSTMAttention
  from stanza.models.common.beam import Beam
label_desc: Use image node_id 6 for calling the Seq2SeqModel obj's underlying member method code with example usage: obj.decode(dec_inputs, hn, cn, ctx, ctx_mask, src) and returns: log_probs,  dec_hidden