class_docstr: Scorer class takes a ScoringModel and uses it to score a stream of parallel sentences.
  It also takes the vocabularies so that the original sentences can be printed out, if desired.
  
  :param model: The model to score with.
  :param batch_scorer: BatchScorer block to score each batch.
  :param source_vocabs: The source vocabularies.
  :param target_vocabs: The target vocabularies.
  :param device: Torch device to load batches to (should be set to model device).
class_docstr_tok: ["Scorer","class","takes","a","ScoringModel","and","uses","it","to","score","a","stream","of","parallel","sentences",".","It","also","takes","the","vocabularies","so","that","the","original","sentences","can","be","printed","out",",","if","desired",".",":","param","model",":","The","model","to","score","with",".",":","param","batch_scorer",":","BatchScorer","block","to","score","each","batch",".",":","param","source_vocabs",":","The","source","vocabularies",".",":","param","target_vocabs",":","The","target","vocabularies",".",":","param","device",":","Torch","device","to","load","batches","to","(","should","be","set","to","model","device",")","."]
code: def score_batch(self, batch: data_io.Batch):
      # TODO: scoring should support multiple devices
      batch = batch.load(self.device)
  
      model_inputs = (
          batch.source,
          batch.source_length,
          batch.target,
          batch.target_length,
      )
      if self.traced_model is None:
          self.traced_model = pt.jit.trace(
              self.model, model_inputs, strict=False
          )
      outputs = self.traced_model(
          *model_inputs
      )  # type: Dict[str, pt.Tensor]
  
      # batch.source_length[:, 0] contains total source length
      scorer_inputs = [
          outputs[C.LOGITS_NAME],
          batch.labels[C.TARGET_LABEL_NAME].long(),
          outputs.get(
              C.LENRATIO_NAME, pt.zeros_like(batch.source_length[:, 0])
          ),
          batch.source_length[:, 0],
          batch.target_length,
      ]  # type: List[Union[pt.Tensor, List[Tuple[pt.Tensor, pt.Tensor]]]]
  
      if self.num_target_factors > 1:
          factor_logits_and_labels = [
              (
                  outputs[C.FACTOR_LOGITS_NAME % i],
                  batch.labels[C.TARGET_FACTOR_LABEL_NAME % i].long(),
              )
              for i in range(1, self.num_target_factors)
          ]
          scorer_inputs.append(factor_logits_and_labels)
  
      if self.traced_batch_scorer is None:
          logger.debug("Tracing batch_scorer")
          self.traced_batch_scorer = pt.jit.trace(
              self.batch_scorer, scorer_inputs, strict=False
          )
      scores = self.traced_batch_scorer(
          *scorer_inputs
      )  # (batch, num_target_factors)
      scores_cpu = scores.cpu()
      if self.model.dtype == pt.bfloat16:
          # NumPy does not currently support bfloat16. Use float32 instead.
          scores_cpu = scores_cpu.to(dtype=pt.float32)
      return scores_cpu.numpy()
  
imports: import logging
  import math
  import time
  from typing import Dict, List, Optional, Tuple, Union
  import numpy
  import torch
  from .None import constants
  from .None import data_io
  from .None import inference
  from .None import vocab
  from .beam_search import CandidateScorer
  from .model import SockeyeModel
  from .output_handler import OutputHandler
label_desc: Use image node_id 2 for calling the Scorer obj's underlying member method code with example usage: obj.score_batch(batch) and returns: scores_cpu