class_docstr: Class for managing efficient loss computation. Handles
  accumulating multiple loss computations.
  
  Args:
      criterion (:obj:`nn. loss function`) : NLLoss or customed loss
      generator (:obj:`nn.Module`) :
      copy_attn (bool): whether copy attention mechanism is on/off
      lambda_coverage: Hyper-param to apply coverage attention if any
      lambda_align: Hyper-param for alignment loss
      tgt_shift_index (int): 1 for NMT, 0 for LM
      vocab: target vocab (for copy attention score calculation)
           module that maps the output of the decoder to a
           distribution over the target vocabulary.
      lm_generator (:obj:`ctranslate2.Generator`): LM Generator
      lm_prior_lambda (float): weight of LM model in loss
      lm_prior_tau (float): scaler for LM loss
class_docstr_tok: ["Class","for","managing","efficient","loss","computation",".","Handles","accumulating","multiple","loss","computations",".","Args",":","criterion","(",":","obj",":","`","nn",".","loss","function","`",")",":","NLLoss","or","customed","loss","generator","(",":","obj",":","`","nn.Module","`",")",":","copy_attn","(","bool",")",":","whether","copy","attention","mechanism","is","on\/off","lambda_coverage",":","Hyper-param","to","apply","coverage","attention","if","any","lambda_align",":","Hyper-param","for","alignment","loss","tgt_shift_index","(","int",")",":","1","for","NMT",",","0","for","LM","vocab",":","target","vocab","(","for","copy","attention","score","calculation",")","module","that","maps","the","output","of","the","decoder","to","a","distribution","over","the","target","vocabulary",".","lm_generator","(",":","obj",":","`","ctranslate2.Generator","`",")",":","LM","Generator","lm_prior_lambda","(","float",")",":","weight","of","LM","model","in","loss","lm_prior_tau","(","float",")",":","scaler","for","LM","loss"]
docstr: Compute the forward loss, supports truncated BPTT for long
  sequences by taking a range in the decoder output sequence to
  back propagate in.
  Range is from `(trunc_start, trunc_start + trunc_size)`.
  Truncation is an approximate efficiency trick to relieve the
  memory required in the RNN buffers.
  
  Args:
    batch (batch) : batch of labeled examples
    output (:obj:`FloatTensor`) :
        output of decoder model ``(batch, tgt_len, hidden)``
    attns (dict) : dictionary of attention weights
        ``(batch, tgt_len, src_len)``
    trunc_start (int) : starting position of truncation window
    trunc_size (int) : length of truncation window
  
  Returns:
      A tuple with the loss and a :obj:`onmt.utils.Statistics` instance.
docstr_tok: ["Compute","the","forward","loss",",","supports","truncated","BPTT","for","long","sequences","by","taking","a","range","in","the","decoder","output","sequence","to","back","propagate","in",".","Range","is","from","`","(","trunc_start",",","trunc_start","+","trunc_size",")","`",".","Truncation","is","an","approximate","efficiency","trick","to","relieve","the","memory","required","in","the","RNN","buffers",".","Args",":","batch","(","batch",")",":","batch","of","labeled","examples","output","(",":","obj",":","`","FloatTensor","`",")",":","output","of","decoder","model","``","(","batch",",","tgt_len",",","hidden",")","``","attns","(","dict",")",":","dictionary","of","attention","weights","``","(","batch",",","tgt_len",",","src_len",")","``","trunc_start","(","int",")",":","starting","position","of","truncation","window","trunc_size","(","int",")",":","length","of","truncation","window","Returns",":","A","tuple","with","the","loss","and","a",":","obj",":","`","onmt.utils.Statistics","`","instance","."]
code: def forward(
      self, batch, output, attns, trunc_start=0, trunc_size=None
  ):
      """Compute the forward loss, supports truncated BPTT for long
      sequences by taking a range in the decoder output sequence to
      back propagate in.
      Range is from `(trunc_start, trunc_start + trunc_size)`.
      Truncation is an approximate efficiency trick to relieve the
      memory required in the RNN buffers.
  
      Args:
        batch (batch) : batch of labeled examples
        output (:obj:`FloatTensor`) :
            output of decoder model ``(batch, tgt_len, hidden)``
        attns (dict) : dictionary of attention weights
            ``(batch, tgt_len, src_len)``
        trunc_start (int) : starting position of truncation window
        trunc_size (int) : length of truncation window
  
      Returns:
          A tuple with the loss and a :obj:`onmt.utils.Statistics` instance.
      """
  
      if trunc_size is None:
          trunc_size = batch["tgt"].size(1) - trunc_start
      # take into account here the tgt_shift_index (0 / 1 = LM/NMT)
      trunc_range = (
          trunc_start + self.tgt_shift_index,
          trunc_start + trunc_size,
      )
  
      target = batch["tgt"][:, trunc_range[0] : trunc_range[1], :]
      output = output[:, trunc_start : trunc_range[1], :].contiguous()
  
      flat_tgt = target[:, :, 0].contiguous().view(-1)
  
      if self.copy_attn:
          align = (
              batch["alignment"][:, trunc_range[0] : trunc_range[1]]
              .contiguous()
              .view(-1)
          )
          loss, scores = self._compute_copy_loss(
              batch, output, flat_tgt, align, attns
          )
          scores_data = collapse_copy_scores(
              self._unbottle(scores.clone(), len(batch["srclen"])),
              batch,
              self.vocab,
          )
          scores_data = self._bottle(scores_data)
          # Correct target copy token instead of <unk>
          # tgt[i] = align[i] + len(tgt_vocab)
          # for i such that tgt[i] == 0 and align[i] != 0
          target_data = flat_tgt.clone()
          unk = self.criterion.unk_index
          correct_mask = (target_data == unk) & (align != unk)
          offset_align = align[correct_mask] + len(self.vocab)
          target_data[correct_mask] += offset_align
          scores = scores_data
          flat_tgt = target_data
  
      else:
          scores = self.generator(self._bottle(output))
          if isinstance(self.criterion, SparsemaxLoss):
              scores = LogSparsemax(scores.to(torch.float32), dim=-1)
          loss = self.criterion(scores.to(torch.float32), flat_tgt)
  
          if self.lambda_align != 0.0:
              align_head = attns["align"]
              if align_head.dtype != loss.dtype:  # Fix FP16
                  align_head = align_head.to(loss.dtype)
              align_idx = batch["align"]
              batch_size, pad_tgt_size, _ = batch["tgt"].size()
              _, pad_src_size, _ = batch["src"].size()
              align_matrix_size = [
                  batch_size,
                  pad_tgt_size,
                  pad_src_size,
              ]
              ref_align = onmt.utils.make_batch_align_matrix(
                  align_idx, align_matrix_size, normalize=True
              )
              ref_align = ref_align[
                  :, trunc_range[0] : trunc_range[1], :
              ]
              if ref_align.dtype != loss.dtype:
                  ref_align = ref_align.to(loss.dtype)
              align_loss = self._compute_alignement_loss(
                  align_head=align_head, ref_align=ref_align
              )
              loss += align_loss
  
      if self.lambda_coverage != 0.0:
          coverage_loss = self._compute_coverage_loss(
              attns["std"], attns["coverage"], flat_tgt
          )
          loss += coverage_loss
  
      if self.lm_generator is not None:
          lm_loss = self._compute_lm_loss_ct2(output, batch["tgt"])
          loss = loss + lm_loss * self.lm_prior_lambda
  
      if self.lm_prior_model is not None:
          lm_loss = self._compute_lm_loss(output, batch["tgt"])
          loss = loss + lm_loss * self.lm_prior_lambda
  
      n_sents = len(batch["srclen"]) if trunc_start == 0 else 0
      stats = self._stats(n_sents, loss.sum().item(), scores, flat_tgt)
  
      return loss, stats
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  import onmt
  from onmt.modules.sparse_losses import SparsemaxLoss
  from onmt.modules.sparse_activations import LogSparsemax
  from onmt.constants import ModelTask, DefaultTokens
  from onmt.modules.copy_generator import collapse_copy_scores
  from onmt.model_builder import load_test_model
label_desc: Use image node_id 12 for calling the LossCompute obj's underlying member method code with example usage: obj.forward(batch, output, attns, trunc_start, trunc_size) and returns: loss,  stats