pad_sequence#
- tensordict.pad_sequence(list_of_tensordicts: Sequence[T], pad_dim: int = 0, padding_value: float | Mapping[NestedKey, float] = 0.0, out: T | None = None, return_mask: bool | NestedKey = False, padding_side: str = 'right') T#
Pads tensordicts to a common size along one dimension and stacks them densely.
Use it to batch samples whose entries differ in size along one dimension, such as sequences of different lengths. Every entry is padded along
pad_dimto the largest size among the inputs, then the inputs are stacked along a new first dimension. The inputs must have the same keys, and the entry shapes must match in every dimension other thanpad_dim. To keep the inputs unpadded, uselazy_stack()instead (see Stacking and variable-size data).- Parameters:
list_of_tensordicts (list of TensorDictBase or tensorclass instances) – the tensordicts to pad and stack.
pad_dim (int, optional) – the dimension of the entries to pad, counted from the first dimension of each entry (batch dimensions included). If it is a batch dimension, the batch size of the result is padded too. A negative
pad_dimcounts from the last dimension of each entry. If it lands on a batch dimension of some entries and on another dimension of others, the batch size is not padded, and, unlessoutis given, no entry may be longer along it than the batch of the first sample. Defaults to0.padding_value (float or Mapping[NestedKey, float], optional) – the value of the padded elements. A mapping gives the value of each entry by its key (
"a"or("a", "b")), and the entries it does not name are padded with0. A key of the mapping that names no entry of the inputs raises aKeyError. The masks are always padded withFalse. Whenpad_dimis a batch dimension, non-tensor entries holdNonethere instead, as withpad(). Defaults to0.0.out (TensorDictBase, optional) – a tensordict to write the result into. Defaults to
None.return_mask (bool or NestedKey, optional) – if
True, the result has a"masks"entry. Ifreturn_maskis a nested key (a string or a tuple of strings), the masks are stored under that key. The masks entry is a tensordict with the structure of the stacked tensordict. Each of its entries is the mask of the valid values. Ifpad_dimis a batch dimension, the mask has the output’s batch size. Otherwise, its shape is the output’s batch size followed by the padded length, regardless of the feature dimension’s position. Tensorclass inputs raise aRuntimeError, and inputs that already hold an entry at the masks key raise aValueError. Useunpad_sequence()to turn the result back into the variable-length samples. Defaults toFalse.padding_side (str, optional) –
"right"puts the padding after the data alongpad_dim,"left"puts it before, asget(key, as_padded_tensor=True, padding_side=...)does on a lazy stack. The masks mark the data positions on either side. Defaults to"right".
- Returns:
A
TensorDict(or the tensorclass of the inputs) with batch size[len(list_of_tensordicts), *batch_size].- Raises:
RuntimeError – if
list_of_tensordictsis empty, if the entry shapes differ in a dimension other thanpad_dim, or ifreturn_maskis set for tensorclass inputs.KeyError – if
padding_valueis a mapping with a key that names no entry of the inputs.ValueError – if
padding_sideis neither"left"nor"right", or if a negativepad_dimlands on a batch dimension of some entries and on another dimension of others, and, with noout, an entry is longer along it than the batch of the first sample.IndexError – if
pad_dimis out of range for an entry.
Examples
>>> import torch >>> from tensordict import TensorDict, pad_sequence >>> list_td = [ ... TensorDict({"a": torch.zeros((3, 8)), "b": torch.zeros((6, 8))}, batch_size=[]), ... TensorDict({"a": torch.zeros((5, 8)), "b": torch.zeros((6, 8))}, batch_size=[]), ... ] >>> padded_td = pad_sequence(list_td, return_mask=True) >>> padded_td["a"].shape, padded_td["b"].shape (torch.Size([2, 5, 8]), torch.Size([2, 6, 8])) >>> padded_td["masks", "a"].sum(-1) tensor([3, 5])
A mapping pads each entry with its own value, for example the token ids with the pad id of a tokenizer and the labels with
-100:>>> samples = [ ... TensorDict(ids=torch.ones(n, dtype=torch.long), labels=torch.ones(n, dtype=torch.long)) ... for n in (2, 3) ... ] >>> padded = pad_sequence(samples, padding_value={"ids": 7, "labels": -100}) >>> padded["ids"] tensor([[1, 1, 7], [1, 1, 1]]) >>> padded["labels"] tensor([[ 1, 1, -100], [ 1, 1, 1]])