code: def minibatch_by_words(
      seqs: Iterable[ItemT],
      size: Sizing,
      tolerance=0.2,
      discard_oversize=False,
      get_length=len,
  ) -> Iterable[List[ItemT]]:
      """Create minibatches of roughly a given number of words. If any examples
      are longer than the specified batch length, they will appear in a batch by
      themselves, or be discarded if discard_oversize=True.
  
      seqs (Iterable[Sequence]): The sequences to minibatch.
      size (int or Sequence[int]): The target number of words per batch.
          Can be a single integer, or a sequence, allowing for variable batch sizes.
      tolerance (float): What percentage of the size to allow batches to exceed.
      discard_oversize (bool): Whether to discard sequences that by themselves
          exceed the tolerated size.
      get_length (Callable or None): Function to get the length of a sequence
          item. The `len` function is used by default.
      """
      if isinstance(size, int):
          size_ = itertools.repeat(size)  # type: Iterator[int]
      else:
          size_ = iter(size)
      target_size = next(size_)
      tol_size = target_size * tolerance
      batch = []
      overflow = []
      batch_size = 0
      overflow_size = 0
      for seq in seqs:
          n_words = get_length(seq)
          # if the current example exceeds the maximum batch size, it is returned separately
          # but only if discard_oversize=False.
          if n_words > target_size + tol_size:
              if not discard_oversize:
                  yield [seq]
          # add the example to the current batch if there's no overflow yet and it still fits
          elif (
              overflow_size == 0
              and (batch_size + n_words) <= target_size
          ):
              batch.append(seq)
              batch_size += n_words
          # add the example to the overflow buffer if it fits in the tolerance margin
          elif (batch_size + overflow_size + n_words) <= (
              target_size + tol_size
          ):
              overflow.append(seq)
              overflow_size += n_words
          # yield the previous batch and start a new one. The new one gets the overflow examples.
          else:
              if batch:
                  yield batch
              target_size = next(size_)
              tol_size = target_size * tolerance
              batch = overflow
              batch_size = overflow_size
              overflow = []
              overflow_size = 0
              # this example still fits
              if (batch_size + n_words) <= target_size:
                  batch.append(seq)
                  batch_size += n_words
              # this example fits in overflow
              elif (batch_size + n_words) <= (target_size + tol_size):
                  overflow.append(seq)
                  overflow_size += n_words
              # this example does not fit with the previous overflow: start another new batch
              else:
                  if batch:
                      yield batch
                  target_size = next(size_)
                  tol_size = target_size * tolerance
                  batch = [seq]
                  batch_size = n_words
      batch.extend(overflow)
      if batch:
          yield batch
  
file_path: spacy/spacy/training/batchers.py
imports: import itertools
  from functools import partial
  from typing import Any, Callable, Iterable, Iterator, List, Optional, Sequence, TypeVar, Union
  from ..util import minibatch, registry
label_desc: Use image node_id 5 for calling a global function with example usage: minibatch_by_words(seqs, size, tolerance, discard_oversize, get_length) without return types