class_docstr: A trainer for training models. 
class_docstr_tok: ["A","trainer","for","training","models","."]
code: def update(self, batch, eval=False):
      device = next(self.model.parameters()).device
      inputs, orig_idx, text = unpack_batch(batch, device)
      src, src_mask, tgt_in, tgt_out, pos, edits = inputs
  
      if eval:
          self.model.eval()
      else:
          self.model.train()
          self.optimizer.zero_grad()
      log_probs, edit_logits = self.model(
          src, src_mask, tgt_in, pos, raw=text
      )
      if self.args.get("edit", False):
          assert edit_logits is not None
          loss = self.crit(
              log_probs.view(-1, self.vocab["char"].size),
              tgt_out.view(-1),
              edit_logits,
              edits,
          )
      else:
          loss = self.crit(
              log_probs.view(-1, self.vocab["char"].size),
              tgt_out.view(-1),
          )
      loss_val = loss.data.item()
      if eval:
          return loss_val
  
      loss.backward()
      torch.nn.utils.clip_grad_norm_(
          self.model.parameters(), self.args["max_grad_norm"]
      )
      self.optimizer.step()
      return loss_val
  
imports: import os
  import sys
  import numpy
  from collections import Counter
  import logging
  import torch
  from torch import nn
  import torch.nn.init
  import stanza.models.common.seq2seq_constant
  from stanza.models.common.foundation_cache import load_charlm
  from stanza.models.common.seq2seq_model import Seq2SeqModel
  from stanza.models.common.char_model import CharacterLanguageModelWordAdapter
  from stanza.models.common import utils, loss
  from stanza.models.lemma import edit
  from stanza.models.lemma.vocab import MultiVocab
label_desc: Use image node_id 3 for calling the Trainer obj's underlying member method code with example usage: obj.update(batch, eval) and returns: loss_val, loss_val