def get_training_batch(inputs, batch_size, random_permute=False, random_seed=RANDOM_SEED):
    """
    Generator that yields data in batches. The last batch may be incomplete, yield it as well.
    :param inputs: tuple of numpy arrays, for example (contexts_ids, responses_ids, conditions_ids)
    :param batch_size: length of numpy arrays to be yielded for each input
    :param random_permute: if True input arrays data will be synchronously shuffled before yielding
    :param random_seed: seed to ensure the identical shuffling of input data for experiments reproducibility
    :return: generator that yields tuples of numpy arrays with batch_size length
    """
    n_samples = inputs[0].shape[0]
    n_batches = n_samples // batch_size
    batches_seq = np.arange(n_batches)
    samples_seq = np.arange(n_samples)

    if random_permute:
        np.random.seed(random_seed)
        np.random.shuffle(samples_seq)

    for i in batches_seq:
        start = i * batch_size
        end = (i + 1) * batch_size
        samples_ids = samples_seq[start:end]
        # yield batch_size selected sequences of x and y ids
        yield tuple(inp[samples_ids] for inp in inputs)

    seen_samples_num = len(batches_seq) * batch_size

    if seen_samples_num < n_samples:
        samples_ids = samples_seq[seen_samples_num:]
        # yield the rest of x and y sequences
        yield tuple(inp[samples_ids] for inp in inputs)

    Generator that yields data in batches. The last batch may be incomplete, yield it as well.
    :param inputs: tuple of numpy arrays, for example (contexts_ids, responses_ids, conditions_ids)
    :param batch_size: length of numpy arrays to be yielded for each input
    :param random_permute: if True input arrays data will be synchronously shuffled before yielding
    :param random_seed: seed to ensure the identical shuffling of input data for experiments reproducibility
    :return: generator that yields tuples of numpy arrays with batch_size length
    
cakechat/dialog_model/model_utils.py