class_docstr: A trainer for training models. 
class_docstr_tok: ["A","trainer","for","training","models","."]
docstr: Postprocess, mainly for handing edits. 
docstr_tok: ["Postprocess",",","mainly","for","handing","edits","."]
code: def postprocess(self, words, preds, edits=None):
      """Postprocess, mainly for handing edits."""
      assert len(words) == len(
          preds
      ), "Lemma predictions must have same length as words."
      edited = []
      if self.args.get("edit", False):
          assert edits is not None and len(words) == len(edits)
          for w, p, e in zip(words, preds, edits):
              lem = edit.edit_word(w, p, e)
              edited += [lem]
      else:
          edited = preds  # do not edit
      # final sanity check
      assert len(edited) == len(words)
      final = []
      for lem, w in zip(edited, words):
          if len(lem) == 0 or constant.UNK in lem:
              final += [w]  # invalid prediction, fall back to word
          else:
              final += [lem]
      return final
  
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 5 for calling the Trainer obj's underlying member method code with example usage: obj.postprocess(words, preds, edits) and returns: final