class_docstr: Yield batch from (multiple) plain text corpus.
  
  Args:
      corpora (dict[str, ParallelCorpus]): collections of corpora to iterate;
      corpora_info (dict[str, dict]): corpora infos correspond to corpora;
      transforms (dict[str, Transform]): transforms may be used by corpora;
      vocabs (dict[str, Vocab]): vocab dict for convert corpora into Tensor;
      task (str): CorpusTask.TRAIN/VALID/INFER;
      batch_type (str): batching type to count on, choices=[tokens, sents];
      batch_size (int): numbers of examples in a batch;
      batch_size_multiple (int): make batch size multiply of this;
      data_type (str): input data type, currently only text;
      bucket_size (int): accum this number of examples in a dynamic dataset;
      bucket_size_init (int): initialize the bucket with this
      amount of examples;
      bucket_size_increment (int): increment the bucket
      size with this amount of examples;
      copy (Bool): if True, will add specific items for copy_attn
      skip_empty_level (str): security level when encouter empty line;
      stride (int): iterate data files with this stride;
      offset (int): iterate data files with this offset.
  
  Attributes:
      sort_key (function): functions define how to sort examples;
      mixer (MixingStrategy): the strategy to iterate corpora.
docstr: Yield elements from data in chunks of batch_size,
  where each chunk size is a multiple of batch_size_multiple.
code: def batch_iter(
      self, data, batch_size, batch_type="sents", batch_size_multiple=1
  ):
      """Yield elements from data in chunks of batch_size,
      where each chunk size is a multiple of batch_size_multiple.
      """
  
      def batch_size_fn(nbsents, maxlen):
          if batch_type == "sents":
              return nbsents
          elif batch_type == "tokens":
              return nbsents * maxlen
          else:
              raise ValueError(
                  f"Invalid argument batch_type={batch_type}"
              )
  
      def max_src_tgt(ex):
          """return the max tokens btw src and tgt in the sequence."""
          if ex["tgt"]:
              return max(
                  len(ex["src"]["src_ids"]), len(ex["tgt"]["tgt_ids"])
              )
          return len(ex["src"]["src_ids"])
  
      minibatch, maxlen, size_so_far, seen = [], 0, 0, set()
      for ex, indice in data:
          src = ex["src"]["src"]
          if src not in seen or (self.task != CorpusTask.TRAIN):
              seen.add(src)
              minibatch.append((ex, indice))
              nbsents = len(minibatch)
              maxlen = max(max_src_tgt(ex), maxlen)
              size_so_far = batch_size_fn(nbsents, maxlen)
              if size_so_far >= batch_size:
                  overflowed = 1 if size_so_far > batch_size else 0
                  if batch_size_multiple > 1:
                      overflowed += (
                          nbsents - overflowed
                      ) % batch_size_multiple
                  if overflowed == 0:
                      yield minibatch
                      minibatch, maxlen, size_so_far, seen = (
                          [],
                          0,
                          0,
                          set(),
                      )
                  else:
                      if overflowed == nbsents:
                          logger.warning(
                              "The batch will be filled until we reach"
                              " %d, its size may exceed %d tokens"
                              % (batch_size_multiple, batch_size)
                          )
                      else:
                          yield minibatch[:-overflowed]
                          minibatch = minibatch[-overflowed:]
                          maxlen = max(
                              [max_src_tgt(ex) for ex, ind in minibatch]
                          )
                          size_so_far = batch_size_fn(
                              len(minibatch), maxlen
                          )
                          seen = set()
  
      if minibatch:
          yield minibatch
  
imports: import torch
  from itertools import cycle
  from onmt.constants import CorpusTask, ModelTask
  from onmt.inputters.text_corpus import get_corpora, build_corpora_iters
  from onmt.inputters.text_utils import text_sort_key, process, numericalize, tensorify, _addcopykeys
  from onmt.transforms import make_transforms
  from onmt.utils.logging import init_logger, logger
  from onmt.utils.misc import RandomShuffler
  from torch.utils.data import DataLoader
label_desc: Use image node_id 7 for calling the DynamicDatasetIter obj's underlying member method code with example usage: obj.batch_iter(data, batch_size, batch_type, batch_size_multiple) and returns: len, nbsents, max, unknown