code: def batchfy_by_seq(
      sorted_data,
      batch_size,
      max_length_in,
      max_length_out,
      min_batch_size=1,
      shortest_first=False,
      ikey="input",
      iaxis=0,
      okey="output",
      oaxis=0,
  ):
      """Make batch set from json dictionary
  
      :param Dict[str, Dict[str, Any]] sorted_data: dictionary loaded from data.json
      :param int batch_size: batch size
      :param int max_length_in: maximum length of input to decide adaptive batch size
      :param int max_length_out: maximum length of output to decide adaptive batch size
      :param int min_batch_size: mininum batch size (for multi-gpu)
      :param bool shortest_first: Sort from batch with shortest samples
          to longest if true, otherwise reverse
      :param str ikey: key to access input
          (for ASR ikey="input", for TTS, MT ikey="output".)
      :param int iaxis: dimension to access input
          (for ASR, TTS iaxis=0, for MT iaxis="1".)
      :param str okey: key to access output
          (for ASR, MT okey="output". for TTS okey="input".)
      :param int oaxis: dimension to access output
          (for ASR, TTS, MT oaxis=0, reserved for future research, -1 means all axis.)
      :return: List[List[Tuple[str, dict]]] list of batches
      """
      if batch_size <= 0:
          raise ValueError(f"Invalid batch_size={batch_size}")
  
      # check #utts is more than min_batch_size
      if len(sorted_data) < min_batch_size:
          raise ValueError(
              f"#utts({len(sorted_data)}) is less than min_batch_size({min_batch_size})."
          )
  
      # make list of minibatches
      minibatches = []
      start = 0
      while True:
          _, info = sorted_data[start]
          ilen = int(info[ikey][iaxis]["shape"][0])
          olen = (
              int(info[okey][oaxis]["shape"][0])
              if oaxis >= 0
              else max(map(lambda x: int(x["shape"][0]), info[okey]))
          )
          factor = max(
              int(ilen / max_length_in), int(olen / max_length_out)
          )
          # change batchsize depending on the input and output length
          # if ilen = 1000 and max_length_in = 800
          # then b = batchsize / 2
          # and max(min_batches, .) avoids batchsize = 0
          bs = max(min_batch_size, int(batch_size / (1 + factor)))
          end = min(len(sorted_data), start + bs)
          minibatch = sorted_data[start:end]
          if shortest_first:
              minibatch.reverse()
  
          # check each batch is more than minimum batchsize
          if len(minibatch) < min_batch_size:
              mod = min_batch_size - len(minibatch) % min_batch_size
              additional_minibatch = [
                  sorted_data[i]
                  for i in np.random.randint(0, start, mod)
              ]
              if shortest_first:
                  additional_minibatch.reverse()
              minibatch.extend(additional_minibatch)
          minibatches.append(minibatch)
  
          if end == len(sorted_data):
              break
          start = end
  
      # batch: List[List[Tuple[str, dict]]]
      return minibatches
  
imports: import itertools
  import logging
  import numpy
label_desc: Use image node_id 1 for calling a global function with example usage: batchfy_by_seq(sorted_data, batch_size, max_length_in, max_length_out, min_batch_size, shortest_first, ikey, iaxis, okey, oaxis) and returns: minibatches