import torch


def pad(seq_batch, pad_token=0, min_len=None):
  """Pads a list[list[Object]] so that each inner list is the same length.

  Args:
    seq_batch (list[list[Object]]): batch of sequences to pad.
    pad_token (Object): object to pad sequences with.
    min_len (int | None): all sequences padded to at least min_length if
      provided.

  Returns:
    padded (list[list[Object]]): seq_batch with inner lists padded with
      the pad token, if necessary.
    mask (torch.ByteTensor): tensor of shape (batch_size, padded_length).
      mask[i][j] = 0 if padded[i][j] is a padded element and 1 otherwise.
  """
  max_len = max(len(seq) for seq in seq_batch)
  if min_len is not None:
    max_len = max(max_len, min_len)

  batch_size = len(seq_batch)
  mask = torch.ones(batch_size, max_len).byte()

  padded = []
  for i, seq in enumerate(seq_batch):
    padding = max_len - len(seq)
    padded.append(seq + [pad_token] * padding)
    if padding > 0:
      mask[i, -padding:] = 0
  return padded, mask