code: def process(self, document):
      if not self.use_identity:
          batch = DataLoader(
              document,
              self.config["batch_size"],
              self.config,
              vocab=self.vocab,
              evaluation=True,
          )
      else:
          batch = DataLoader(
              document,
              self.config["batch_size"],
              self.config,
              evaluation=True,
              conll_only=True,
          )
      if self.use_identity:
          preds = [
              word.text
              for sent in batch.doc.sentences
              for word in sent.words
          ]
      elif self.config.get("dict_only", False):
          preds = self.trainer.predict_dict(
              batch.doc.get([doc.TEXT, doc.UPOS])
          )
      else:
          if self.config.get("ensemble_dict", False):
              # skip the seq2seq model when we can
              skip = self.trainer.skip_seq2seq(
                  batch.doc.get([doc.TEXT, doc.UPOS])
              )
              seq2seq_batch = DataLoader(
                  document,
                  self.config["batch_size"],
                  self.config,
                  vocab=self.vocab,
                  evaluation=True,
                  skip=skip,
              )
          else:
              seq2seq_batch = batch
  
          with torch.no_grad():
              preds = []
              edits = []
              for i, b in enumerate(seq2seq_batch):
                  ps, es = self.trainer.predict(
                      b, self.config["beam_size"]
                  )
                  preds += ps
                  if es is not None:
                      edits += es
  
          if self.config.get("ensemble_dict", False):
              word_tags = batch.doc.get(WORD_TAGS)
              words = [x[0] for x in word_tags]
              preds = self.trainer.postprocess(
                  [x for x, y in zip(words, skip) if not y],
                  preds,
                  edits=edits,
              )
              if self.store_results:
                  new_word_tags = compress(
                      word_tags, map(lambda x: not x, skip)
                  )
                  new_predictions = [
                      (x[0], x[1], y)
                      for x, y in zip(new_word_tags, preds)
                  ]
                  self.trainer.train_dict(
                      new_predictions, update_word_dict=False
                  )
              # expand seq2seq predictions to the same size as all words
              i = 0
              preds1 = []
              for s in skip:
                  if s:
                      preds1.append("")
                  else:
                      preds1.append(preds[i])
                      i += 1
              preds = self.trainer.ensemble(word_tags, preds1)
          else:
              preds = self.trainer.postprocess(
                  batch.doc.get([doc.TEXT]), preds, edits=edits
              )
  
      # map empty string lemmas to '_'
      preds = [max([(len(x), x), (0, "_")])[1] for x in preds]
      batch.doc.set([doc.LEMMA], preds)
      return batch.doc
  
file_path: stanza/stanza/pipeline/lemma_processor.py
imports: from itertools import compress
  import torch
  from stanza.models.common import doc
  from stanza.models.lemma.data import DataLoader
  from stanza.models.lemma.trainer import Trainer
  from stanza.pipeline._constants import *
  from stanza.pipeline.processor import UDProcessor, register_processor
label_desc: Use image node_id 5 for calling the LemmaProcessor obj's underlying member method code with example usage: obj.process(document) and returns: batch