VLAAction#
- class torchrl.data.vla.VLAAction(chunk: Tensor | None = None, tokens: Tensor | None = None, raw_tokens: Tensor | None = None, logits: Tensor | None = None, log_probs: Tensor | None = None, mask: Tensor | None = None, padded: bool | None = None, *, batch_size, device=None, names=None)[source]#
Container for VLA policy outputs.
- Parameters:
chunk (torch.Tensor | None) – Continuous action chunk.
tokens (torch.Tensor | None) – Action-token ids in the policy vocabulary.
raw_tokens (torch.Tensor | None) – Backend-native token ids when they differ from action-token window ids.
logits (torch.Tensor | None) – Token logits with a trailing vocabulary dim.
log_probs (torch.Tensor | None) – Log-probabilities of the selected tokens.
mask (torch.Tensor | None) – Optional valid-token/action mask.
padded (bool | None) – Whether variable-length outputs were padded.
Examples
>>> import torch >>> from torchrl.data.vla import VLAAction >>> action = VLAAction(chunk=torch.zeros(2, 4, 7), batch_size=[2]) >>> action.chunk.shape torch.Size([2, 4, 7])
- cat(dim: int = 0, *, out=None)#
Concatenates tensordicts along an existing batch dimension
dim.It is equivalent to
torch.cat(), and also works undertorch.compile(). The tensordicts must have the same keys, or aKeyErroris raised, and the same batch size except alongdim.- Parameters:
input (sequence of TensorDictBase) – the tensordicts to concatenate.
dim (int, optional) – the batch dimension to concatenate along. Defaults to
0.
- Keyword Arguments:
out (TensorDictBase, optional) – a tensordict to write the result into. Defaults to
None.
Examples
>>> import torch >>> from tensordict import TensorDict >>> a = TensorDict(x=torch.zeros(3), batch_size=[3]) >>> b = TensorDict(x=torch.ones(3), batch_size=[3]) >>> TensorDict.cat([a, b]).batch_size torch.Size([6])
- property device: torch.device#
The device of the tensorclass, or
Noneif its leaves may be on different devices.It is read-only: use
to()to move the tensorclass to another device.
- classmethod fields() tuple[dataclasses.Field, ...]#
Returns the fields of the tensorclass.
Deprecated since version 0.15: Use
dataclasses.fields(cls)instead. It returns the same tuple ofdataclasses.Fieldobjects.
- from_any(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None)#
Converts a dict, tuple, dataclass, array or file to a tensordict, recursively.
from_anypicks the conversion from the type ofobj, and applies it to the values insideobjtoo. It accepts more types than theTensorDictconstructor, at the cost of some overhead and of opinionated choices about how each type maps to entries:a dict or
collections.UserDict:from_dict();a named tuple:
from_namedtuple();a tuple:
from_tuple(), with the keys"0","1", … This includes the results oftorch.return_types(max,sort,topk, …), which also emit aFutureWarning. Starting with TensorDict 0.17, the default will change to their field names ("values","indices", …), asfrom_namedtuple()gives;a dataclass instance:
from_dataclass()(the result is a tensordict, not a tensorclass). A dataclass type whose fields all have defaults gives a tensordict of the defaults too, with aFutureWarning. Starting with TensorDict 0.17, the default will change to returning the type unchanged, as for any other class;a NumPy structured array:
from_struct_array();a pandas DataFrame:
from_pandas();an open
h5py.File: aPersistentTensorDict(seefrom_h5()).
A tensor or a tensor collection is returned as it is. A list becomes a tensor if
torch.tensor()takes it, and aNonTensorStackotherwise. Any other object is returned unchanged.- Parameters:
obj – the object to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size, except for a dict, wherebatch_sizewins, and for anh5py.File, whereauto_batch_sizewins. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size, except for a dict, wherebatch_sizewins and no batch size is computed, and for anh5py.File, whereauto_batch_sizewins andbatch_sizeis ignored. Defaults toNone.
- Returns:
A tensordict (a
PersistentTensorDictfor an HDF5 file), a tensor or aNonTensorStackfor a list, orobjitself for the other types.
Examples
>>> import dataclasses >>> import torch >>> from tensordict import TensorDict >>> @dataclasses.dataclass ... class Data: ... obs: torch.Tensor ... extra: tuple >>> data = Data(obs=torch.zeros(3, 4), extra=(torch.ones(3), {"x": torch.ones(3)})) >>> td = TensorDict.from_any(data, auto_batch_size=True) >>> td.batch_size torch.Size([3]) >>> sorted(td.keys(include_nested=True, leaves_only=True), key=str) [('extra', '0'), ('extra', '1', 'x'), 'obs'] >>> TensorDict.from_any([1, 2, 3]) tensor([1, 2, 3])
- from_consolidated()#
Reconstructs a tensordict from a file written by
consolidate(filename=...).The result is consolidated: its leaves are views into one copy-on-write memory map of the file, so in-place writes into them do not reach the file. It is not locked. The batch sizes and names are as they were when the file was written. Same as
from_consolidated().- Parameters:
filename (str or Path) – the file to read.
Examples
>>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> td = TensorDict(a=torch.zeros(3), b={"c": torch.ones(3)}, batch_size=[3]) >>> with tempfile.TemporaryDirectory() as path: ... _ = td.consolidate(filename=f"{path}/td.bin") ... loaded = TensorDict.from_consolidated(f"{path}/td.bin") ... print(loaded["b", "c"], loaded.is_consolidated()) tensor([1., 1., 1.]) True
- from_csv(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None, separator: str | None = None, dtype: torch.dtype | None = None, **kwargs) Self#
Reads a CSV file into a tensordict, with one entry per column.
Requires pandas or pyarrow: the file is read with
pandas.read_csv()when pandas is installed, and withpyarrow.csv.read_csvotherwise. The columns are converted as infrom_pandas().to_csv()writes such a file. Through pandas, a string column is one value for the whole batch (see the note infrom_pandas()); through pyarrow, it is aNonTensorStackwith one value per row.- Parameters:
path (str or Path) – the path of the CSV file.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which gives[num_rows].separator (str, optional) – if given, splits the column names on it to build nested entries: with
separator=".", the column"obs.x"becomes the entry("obs", "x"). Defaults toNone, which keeps the column names as keys.dtype (torch.dtype, optional) – if given, casts the numeric and boolean columns to it. Defaults to
None, which keeps the dtype of each column.**kwargs – passed to the CSV reader.
- Returns:
A tensordict of the class this method is called on (
TensorDictforTensorDictBase).
Examples
>>> import os >>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> data = TensorDict(obs=torch.arange(3.0), reward=torch.ones(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as tmpdir: ... path = os.path.join(tmpdir, "data.csv") ... data.to_csv(path) ... td = TensorDict.from_csv(path) ... td32 = TensorDict.from_csv(path, dtype=torch.float32) >>> td.batch_size, td["obs"].dtype, td32["obs"].dtype (torch.Size([3]), torch.float64, torch.float32)
- from_dataclass(*, dest_cls: Type | None = None, auto_batch_size: bool = False, batch_dims: int | None = None, as_tensorclass: bool = False, device: torch.device | None = None, batch_size: torch.Size | None = None)#
Converts a dataclass instance to a tensordict, with one entry per field.
Each field value is converted with
from_any(), so a nested dataclass or dict becomes a nested tensordict and a number becomes a tensor. Withas_tensorclass=True, the conversion is that of the functionfrom_dataclass()instead, which returns a tensorclass.- Parameters:
dataclass – the dataclass instance to convert. With
as_tensorclass=True, it can also be a dataclass type. Without it, a dataclass type whose fields all have defaults gives a tensordict of the defaults, with aFutureWarning. Starting with TensorDict 0.17, the default will change to raising aTypeErrorfor it.- Keyword Arguments:
dest_cls (type, optional) – with
as_tensorclass=True, the tensorclass to convert to. Ignored otherwise. Defaults toNone, which creates a new tensorclass with the fields of the dataclass.auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.as_tensorclass (bool, optional) – if
True, returns a tensorclass instance (or a tensorclass type, for a dataclass type) throughfrom_dataclass(). Defaults toFalse.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, an empty batch size.
- Returns:
A
TensorDict, or a tensorclass instance or type ifas_tensorclass=True.- Raises:
TypeError – if
dataclassis not a dataclass andas_tensorclass=False, if it is a dataclass type with a field that cannot be read from the class (a field without a default, or a field of a tensorclass type) andas_tensorclass=False, or if bothauto_batch_size=Trueandbatch_sizeare given.
Examples
>>> import dataclasses >>> import torch >>> from tensordict import TensorDict >>> @dataclasses.dataclass ... class Data: ... obs: torch.Tensor ... reward: torch.Tensor >>> data = Data(obs=torch.zeros(3, 4), reward=torch.ones(3)) >>> td = TensorDict.from_dataclass(data, auto_batch_size=True) >>> type(td).__name__, td.batch_size ('TensorDict', torch.Size([3])) >>> tc = TensorDict.from_dataclass(data, as_tensorclass=True, batch_size=[3]) >>> type(tc).__name__, tc.batch_size ('Data_tc', torch.Size([3]))
- from_h5(*, mode: str = 'r', auto_batch_size: bool = False, batch_dims: int | None = None, batch_size: torch.Size | None = None, non_tensor_as_stack: bool = False)#
Opens an HDF5 file as a
PersistentTensorDict.The data stays in the file: entries are read when they are accessed. Requires
h5py. See Save and load tensordicts andPersistentTensorDict.- Parameters:
filename (str or path) – the path to the HDF5 file.
- Keyword Arguments:
mode (str, optional) – how the file is opened, as in
h5py.File:"r"(read only),"r+"(read and write), and so on. Defaults to"r".auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which gives each nested tensordict the largest batch size that its entries share, and every nested tensordictbatch_sizewhen it is passed. A file written byto_h5()stores the batch sizes and the dim names. Starting with TensorDict 0.17, the default will change to restoring the stored ones, asfrom_zarrdoes: withbatch_size, the nested tensordicts get their stored batch sizes, and withauto_batch_size=True, the stored names are kept and the batch sizes are inferred from the stored ones, which an empty tensordict or a non-tensor entry keeps.from_h5warns when this changes its result.non_tensor_as_stack (bool, optional) – if
True, a non-tensor dataset that tensordict did not write, such as a string column with one string per row, reads as aNonTensorStackof its rows when its leading dimensions equal the batch size. Otherwise it reads as oneNonTensorDatathat holds the whole dataset. Defaults toFalse.
- Returns:
A
PersistentTensorDictbacked by the file.- Raises:
TypeError – if both
auto_batch_size=Trueandbatch_sizeare given.
Examples
>>> import os >>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> data = TensorDict(key1=torch.zeros(3), key2=torch.ones(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as tmpdir: ... path = os.path.join(tmpdir, "file.h5") ... _ = data.to_h5(path) ... td = TensorDict.from_h5(path) ... print(td) PersistentTensorDict(batch_size=[3], fields={key1: f32[], key2: f32[]})
- from_json(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None, separator: str | None = None, dtype: torch.dtype | None = None, lines: bool = False, **kwargs) Self#
Reads a JSON file of records into a tensordict, with one entry per field.
The file holds an array of records (
[{"a": 1, "b": 2.0}, ...]), or one record per line withlines=True(JSON Lines). Each field becomes an entry with one value per record. The file is read withpandas.read_json()when pandas is installed, and with thejsonmodule otherwise. Through pandas, a string field is one value for the whole batch (see the note infrom_pandas()); through thejsonmodule, it is aNonTensorStackwith one value per record. To convert a single JSON object, load it withjson.load()and pass it tofrom_dict().to_json()writes such a file.- Parameters:
path (str or Path) – the path of the JSON file.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which gives[num_rows].separator (str, optional) – if given, splits the column names on it to build nested entries: with
separator=".", the column"obs.x"becomes the entry("obs", "x"). Defaults toNone, which keeps the column names as keys.dtype (torch.dtype, optional) – if given, casts the numeric and boolean columns to it. Defaults to
None, which keeps the dtype of each column.lines (bool, optional) – if
True, reads the file as JSON Lines, one record per line. Defaults toFalse.**kwargs – passed to
pandas.read_json(). Ignored without pandas.
- Returns:
A tensordict of the class this method is called on (
TensorDictforTensorDictBase).
Examples
>>> import os >>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> data = TensorDict(obs=torch.arange(3.0), reward=torch.ones(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as tmpdir: ... path = os.path.join(tmpdir, "data.json") ... data.to_json(path) ... td = TensorDict.from_json(path) ... path_lines = os.path.join(tmpdir, "data.jsonl") ... data.to_json(path_lines, lines=True) ... td_lines = TensorDict.from_json(path_lines, lines=True) >>> td.batch_size, td_lines.batch_size (torch.Size([3]), torch.Size([3]))
- from_list(*, auto_batch_size: bool | None = None, batch_size: torch.Size | None = None, device: torch.device | None = None, batch_dims: int | None = None, names: list[str] | None = None, lazy: bool | None = None) Self#
Builds a tensordict by stacking a list of dicts or tensor collections.
Each dict is converted with
from_dict()and the results are stacked along a new leading dimension. A tensordict or tensorclass in the list is stacked as it is: the keyword arguments do not apply to it. When the result does not get thebatch_sizeordeviceasked for, aFutureWarningis emitted: starting with TensorDict 0.17, the default will change to applying them to the result, which raises if the batch size does not fit, as for a list of dicts.- Parameters:
input (list) – the dicts or tensor collections to stack.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size of each element to the largest leading shape that all its entries share. Defaults toNone, which behaves likeFalseunlessbatch_dimsis given.batch_size (torch.Size or list of int, optional) – the batch size of the result, with the length of the list first. Each element gets
batch_size[1:]. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_dims (int, optional) – the maximum number of batch dimensions of the result, the list dimension included. Turns on
auto_batch_sizewhen that isNone. Exclusive withbatch_size. Defaults toNone.names (list of str, optional) – the names of the batch dimensions of the result, one per dimension, with the name of the list dimension first. Defaults to
None.lazy (bool, optional) – if
True, the result is a lazy stack; ifFalse, a dense stack. Defaults toNone, which builds a dense stack when the elements have the same shape and a lazy stack otherwise. See Stacking and variable-size data.
- Raises:
ValueError – if
batch_size[0]is not the length of the list.
Examples
>>> import torch >>> from tensordict import TensorDict >>> td = TensorDict.from_list( ... [{"a": torch.zeros(3)}, {"a": torch.zeros(3)}], ... batch_size=[2, 3], ... names=["x", "y"], ... ) >>> td.batch_size torch.Size([2, 3]) >>> td.names ['x', 'y']
- from_module(as_module: bool = False, lock: bool = False, use_state_dict: bool = False, filter_empty: bool = True)#
Returns a tensordict that holds the parameters and buffers of a module.
The entries are the parameters and buffers of the module themselves, not copies. Submodules become nested tensordicts.
Note
This method does not lock the result by default (
lock=False). The functiontensordict.from_module()locks it by default (lock=True).- Parameters:
module (torch.nn.Module) – the module to get the parameters from.
as_module (bool, optional) – if
True, aTensorDictParamsinstance is returned, which can be used to store parameters within atorch.nn.Module. Defaults toFalse.lock (bool, optional) – if
True, the resulting tensordict is locked. Defaults toFalse.use_state_dict (bool, optional) – if
True, the state-dict from the module is used and unflattened into a TensorDict with the tree structure of the model. Use it when the module has state-dict hooks. Defaults toFalse.filter_empty (bool, optional) – if
True, submodules without parameters or buffers (nn.ReLU, for example) get no entry. IfFalse, they get an empty tensordict. Defaults toTrue.
- Returns:
A
TensorDict, or aTensorDictParamsifas_module=True.
Examples
>>> from torch import nn >>> from tensordict import TensorDict >>> module = nn.Sequential(nn.Linear(3, 4), nn.ReLU()) >>> params = TensorDict.from_module(module) >>> params["0", "weight"] is module[0].weight True >>> list(params.keys()) ['0'] >>> params.is_locked False
- from_modules(*, as_module: bool = False, lock: bool = True, use_state_dict: bool = False, lazy_stack: bool = False, expand_identical: bool = False)#
Stacks the parameters and buffers of several modules in one tensordict.
The result has one batch dimension, with one element per module, and the structure that
from_module()gives. Use it to run an ensemble of modules that have the same structure withtorch.vmap()andto_module()(see the example).The default, dense result holds new parameters and buffers: the stacks of those of the modules, with the same
requires_grad. Pass these new parameters to the optimizer: gradients reach them, not the parameters of the modules. Withlazy_stack=True, the result is a lazy stack of the parameters of the modules, which receive the gradients.- Parameters:
*modules (nn.Module) – the modules to get the parameters from. With a dense stack, they must have the same parameters and buffers, with the same shapes.
- Keyword Arguments:
as_module (bool, optional) – if
True, returns aTensorDictParams, which can be stored as a submodule of atorch.nn.Module. Exclusive withlazy_stack. Defaults toFalse.lock (bool, optional) – if
True, the result is locked (see Locking and temporary changes). Defaults toTrue.use_state_dict (bool, optional) – if
True, reads thestate_dict()of each module, so that its state-dict hooks run. Defaults toFalse.lazy_stack (bool, optional) –
if
True, returns aLazyStackedTensorDictof the parameters of the modules; ifFalse, stacks them into new parameters. Exclusive withas_module, and not compatible with lazy modules. Defaults toFalse.Warning
A lazy stack stacks the parameters each time an entry is read with
get(), which costs memory (Ntimes the size of the parameters, more if a graph is built) and time, and the optimizer holdsNtimes more parameters. Uselazy_stack=Trueonly when you need to train the parameters of the modules themselves.expand_identical (bool, optional) – if
True, a parameter that is the same object in every module is expanded instead of stacked, so that the result shares its memory. Ignored whenlazy_stack=True. Defaults toFalse.
- Raises:
RuntimeError – if
lazy_stack=Trueandas_module=True, or iflazy_stack=Trueand a module has uninitialized (lazy) parameters.
Examples
>>> import torch >>> from torch import nn >>> from tensordict import TensorDict >>> _ = torch.manual_seed(0) >>> modules = [nn.Linear(3, 4) for _ in range(2)] >>> params = TensorDict.from_modules(*modules) >>> params.batch_size, params["weight"].shape (torch.Size([2]), torch.Size([2, 4, 3]))
Run the two modules on one input with
torch.vmap(), through a module on the"meta"device that holds no data. The gradients reach the stacked parameters, not those of the modules:>>> empty_module = nn.Linear(3, 4, device="meta") >>> def exec_module(params, x): ... with params.to_module(empty_module): ... return empty_module(x) >>> x = torch.randn(3) >>> y = torch.vmap(exec_module, (0, None))(params, x) >>> y.shape torch.Size([2, 4]) >>> y.sum().backward() >>> params["weight"].grad is not None, modules[0].weight.grad is None (True, True)
With
lazy_stack=True, the gradients reach the parameters of the modules:>>> params = TensorDict.from_modules(*modules, lazy_stack=True) >>> type(params).__name__ 'LazyStackedTensorDict' >>> y = torch.vmap(exec_module, (0, None))(params, x) >>> y.sum().backward() >>> modules[0].weight.grad is not None True
- from_namedtuple(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None)#
Converts a named tuple to a tensordict whose keys are its field names.
Each field value is converted with
from_any(), so a nested named tuple or dict becomes a nested tensordict and a number becomes a tensor. Thetorch.return_typesresults oftorch.max,torch.sortand the like are accepted too.to_namedtuple()converts back.- Parameters:
named_tuple (NamedTuple) – the named tuple to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. It applies to the nested tensordicts too. Exclusive with
auto_batch_size. Defaults toNone, an empty batch size.
- Returns:
A
TensorDict.- Raises:
TypeError – if both
auto_batch_size=Trueandbatch_sizeare given.
Examples
>>> from tensordict import TensorDict >>> import torch >>> data = TensorDict({ ... "a_tensor": torch.zeros((3)), ... "nested": {"a_tensor": torch.zeros((3)), "a_string": "zero!"}}, [3]) >>> nt = data.to_namedtuple() >>> nt GenericDict(a_tensor=tensor([0., 0., 0.]), nested=GenericDict(a_tensor=tensor([0., 0., 0.]), a_string='zero!')) >>> td = TensorDict.from_namedtuple(nt, auto_batch_size=True) >>> td.batch_size, td["nested", "a_string"] (torch.Size([3]), 'zero!') >>> sorted(TensorDict.from_namedtuple(torch.tensor([2, 0, 1]).max(0)).keys()) ['indices', 'values']
- from_pandas(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None, separator: str | None = None, dtype: torch.dtype | None = None) Self#
Converts a pandas DataFrame to a tensordict, with one entry per column.
The batch size is
[num_rows]. Numeric and boolean columns become tensors, a string or object column becomes oneNonTensorDatathat holds the whole column, a categorical column becomes the tensor of its codes, and a datetime column becomes anint64tensor of nanoseconds.to_pandas()converts back.Note
A string or object column is one value for the whole batch, so
td[i]["name"]gives the values of every row, not the value of rowi. To get one value per row, set the column again as a list:td["name"] = df["name"].tolist()stores aNonTensorStack, whosetd[i]["name"]is the value of rowi. It builds one object per row, about 20 microseconds each, so it is much slower than reading the column for large frames.- Parameters:
dataframe (pd.DataFrame) – the DataFrame to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which gives[num_rows].separator (str, optional) – if given, splits the column names on it to build nested entries: with
separator=".", the column"obs.x"becomes the entry("obs", "x"). Defaults toNone, which keeps the column names as keys.dtype (torch.dtype, optional) – if given, casts the numeric and boolean columns to it. Defaults to
None, which keeps the dtype of each column.
- Returns:
A tensordict of the class this method is called on (
TensorDictforTensorDictBase).
Examples
>>> from tensordict import TensorDict >>> import pandas as pd >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> td = TensorDict.from_pandas(df) >>> print(td) TensorDict(batch_size=[3], fields={a: i64[], b: f64[]})
- from_parquet(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None, separator: str | None = None, dtype: torch.dtype | None = None, columns: list[str] | None = None, **kwargs) Self#
Reads a Parquet file into a tensordict, with one entry per column.
Requires pyarrow or pandas: the file is read with
pyarrow.parquet.read_tablewhen pyarrow is installed, and withpandas.read_parquet()otherwise. The columns are converted as infrom_pandas().to_parquet()writes such a file. Through pyarrow, a string column is aNonTensorStackwith one value per row; through pandas, it is one value for the whole batch (see the note infrom_pandas()).- Parameters:
path (str or Path) – the path of the Parquet file.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which gives[num_rows].separator (str, optional) – if given, splits the column names on it to build nested entries: with
separator=".", the column"obs.x"becomes the entry("obs", "x"). Defaults toNone, which keeps the column names as keys.dtype (torch.dtype, optional) – if given, casts the numeric and boolean columns to it. Defaults to
None, which keeps the dtype of each column.columns (list of str, optional) – the columns to read. Defaults to
None, which reads all the columns.**kwargs – passed to the Parquet reader.
- Returns:
A tensordict of the class this method is called on (
TensorDictforTensorDictBase).
Examples
>>> import os >>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> data = TensorDict(obs=torch.arange(3.0), reward=torch.ones(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as tmpdir: ... path = os.path.join(tmpdir, "data.parquet") ... data.to_parquet(path) ... td = TensorDict.from_parquet(path) ... td_obs = TensorDict.from_parquet(path, columns=["obs"]) >>> sorted(td.keys()), sorted(td_obs.keys()) (['obs', 'reward'], ['obs'])
- from_pytree(*, batch_size: torch.Size | None = None, auto_batch_size: bool = False, batch_dims: int | None = None)#
Converts a pytree to a tensordict that
to_pytree()converts back.Each list, tuple, named tuple and dict of the pytree becomes a nested tensordict, and its type is stored in a
"_pytree_type"entry so thatto_pytree()can rebuild the pytree. The elements of a list or tuple get the keys"0","1", … The subclasses of these types, such ascollections.OrderedDict,collections.defaultdictand thetorch.return_typesresults oftorch.maxand the like, are accepted too. Adefaultdictis rebuilt without itsdefault_factory.A tensor or a tensor collection is returned as it is. Python ints and floats and NumPy arrays become tensors, so
to_pytree()returns them as tensors. A dict key that is not aNestedKey(such as an int or an object) is stored in aNonTensorDataentry next to its value. Other types raise aNotImplementedError.- Parameters:
pytree – the pytree to convert: a list, tuple, named tuple or dict, nested to any depth, whose leaves are tensors, tensor collections, Python numbers or NumPy arrays.
- Keyword Arguments:
batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Defaults to
None, which gives an empty batch size unlessauto_batch_size=True.auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.
Note
A module
state_dict()round-trips throughfrom_pytree, and itsmemmap()output loads withload_memmap(path, allow_pickle=False). The state dicts of an optimizer and of a learning-rate scheduler holdNone,strvalues and Python numbers, whichfrom_pytreerejects (Noneandstr) or returns as tensors (numbers): save them withtorch.save(sd, path)and load them withtorch.load(path, weights_only=True), which round-trips them exactly without unpickling arbitrary objects.Note
The list fields of a named tuple, and some of its dict and tuple fields, are converted with
from_any()and do not round-trip throughto_pytree():a list of numbers comes back as a tensor;
an empty tuple, an empty dict or named tuple, and a dict that holds a str or a list come back as a
GenericDictnamed tuple;a dict that holds a tuple, a tuple subclass (such as a
torch.return_typesresult), and a tuple that holds anything other than tensors, Python numbers, dicts and named tuples maketo_pytree()raise aValueError.
The other dict, named tuple and tuple fields come back with their own type.
Examples
>>> import torch >>> from tensordict import TensorDict >>> pytree = {"obs": torch.zeros(3, 4), "pair": (torch.zeros(3), torch.ones(3))} >>> td = TensorDict.from_pytree(pytree, auto_batch_size=True) >>> td.batch_size torch.Size([3]) >>> sorted(td.keys()), sorted(td["pair"].keys()) (['_pytree_type', 'obs', 'pair'], ['0', '1', '_pytree_type']) >>> type(td.to_pytree()["pair"]).__name__ 'tuple'
A pytree with lists, dicts, a named tuple and a dict key that is not a string round-trips:
>>> class Key: ... pass >>> key = Key() >>> pytree = ( ... [torch.arange(3), torch.zeros(2)], ... {"tensor": torch.ones(2), key: torch.arange(2), "list": [1, 2, 3]}, ... {"named_tuple": TensorDict(two=torch.ones(1)).to_namedtuple()}, ... ) >>> pytree_recon = TensorDict.from_pytree(pytree).to_pytree() >>> def check(v1, v2): ... assert (v1 == v2).all() >>> _ = torch.utils._pytree.tree_map(check, pytree, pytree_recon) >>> key in pytree_recon[1] True
- from_schema(*, batch_size: Sequence[int] | torch.Size | None = None, storage: str | None = None, device=None, **kwargs) TensorDictBase#
Allocates a zero-filled tensordict from a schema of shapes and dtypes.
Each entry of
schemamaps a key to an(element_shape, dtype)pair, and the entry gets the shape[*batch_size, *element_shape].storageselects where the zeros are stored, so that a buffer on disk or on a server can be created without building it in memory first.- Parameters:
schema (dict) – maps each key (a
str) to a pair(element_shape, dtype), whereelement_shape(a list of int or atorch.Size) is the shape of the entry after the batch dimensions.- Keyword Arguments:
batch_size (torch.Size or list of int, optional) – the batch size of the result, prepended to every element shape. Defaults to
None, an empty batch size.storage (str, optional) –
where the entries are stored:
None: aTensorDictof regular tensors."memmap": memory-mapped tensors, in the directory given byprefix=<dir>(seememmap_like())."h5": aPersistentTensorDictin the HDF5 file given byfilename=<path>."zarr": aPersistentTensorDictin the zarr store given byfilename=<path or store>(requireszarr>=3.1.1)."shared": tensors in shared memory (seeshare_memory_())."redis"or"dragonfly": aTensorDictStoreon a server, throughTensorDictStore.from_schema.
Defaults to
None.device (torch.device, str or int, optional) – the device of the result. The
"memmap"storage ignores it. Defaults toNone.**kwargs – passed to the backend:
prefixand the other arguments ofmemmap_like()for"memmap",filenamefor"h5"and"zarr",host,portand the like for"redis"and"dragonfly".
- Returns:
A new tensordict of the type that
storageselects, filled with zeros.- Raises:
ValueError – if
storageis not one of the values above.
Examples
>>> import torch >>> from tensordict import TensorDict >>> td = TensorDict.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> td["obs"].shape torch.Size([1000, 84, 84, 3])
>>> import tempfile >>> with tempfile.TemporaryDirectory() as d: ... td_mm = TensorDict.from_schema( ... {"obs": ([4], torch.float32)}, ... batch_size=[8], ... storage="memmap", ... prefix=d, ... ) ... print(td_mm.is_memmap()) True
- from_struct_array(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None) Self#
Converts a NumPy structured array to a tensordict, with one entry per field.
The batch size is the shape of the array, and each entry holds a field. The conversion is zero-copy: the tensors share memory with the array, so an in-place change to the array changes the tensordict, and the other way around. Two cases copy the data: a
deviceother than the CPU, and a field whose item size does not divide the size of a record, such as the"i8"field of a packed array of"i8"and"f4"fields (12 bytes per record), which torch cannot view. String fields become non-tensor data.to_struct_array()converts back.- Parameters:
struct_array (np.ndarray) – the structured array to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share, which can add the dimensions of array fields. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which uses the shape of the array.
- Returns:
A tensordict of the class this method is called on (
TensorDictforTensorDictBase).- Raises:
TypeError – if both
auto_batch_size=Trueandbatch_sizeare given.
Examples
>>> import numpy as np >>> from tensordict import TensorDict >>> x = np.array( ... [("Rex", 9, 81.0), ("Fido", 3, 27.0)], ... dtype=[("name", "U10"), ("age", "i4"), ("weight", "f4")], ... ) >>> td = TensorDict.from_struct_array(x) >>> td.batch_size, td["age"] (torch.Size([2]), tensor([9, 3], dtype=torch.int32)) >>> x["age"] += 1 # the tensordict shares memory with the array >>> td["age"] tensor([10, 4], dtype=torch.int32) >>> bool((td.to_struct_array() == x).all()) True
- classmethod from_tensordict(tensordict: TensorDictBase, non_tensordict: dict | None = None, safe: bool | None = None) Self#
Wraps a tensordict in a new instance of the tensorclass, without copying the leaves.
If
tensordictis aTensorDict, the entries of the fields annotated with a tensorclass (orOptionalof one) that are tensordicts become instances of that tensorclass, recursively. They are set in a shallow copy oftensordict, which keeps its own entries. An entry with keys that the annotated class does not declare stays a tensordict. Other backends are wrapped as they are: setting a tensorclass in them would write to their storage (e.g. an H5 file).- Parameters:
tensordict (TensorDictBase) – the tensordict that holds the tensor fields.
non_tensordict (dict, optional) – the values of the non-tensor fields. The fields that neither argument holds are set to
None. Defaults toNone.safe (bool, optional) – deprecated in 0.15, will be removed in TensorDict 0.17. If
False, skips the check thattensordictis aTensorDictBase. By default, the check runs, and another type raises aRuntimeError.
- Returns:
A new instance of the class, whose fields are the entries of
tensordict.
Examples
>>> import torch >>> from tensordict import TensorClass >>> class Pose(TensorClass): ... q: torch.Tensor >>> class Obs(TensorClass): ... a: Pose >>> obs = Obs(a=Pose(q=torch.zeros(5, 4), batch_size=[5]), batch_size=[5]) >>> type(Obs.from_tensordict(obs.to_tensordict()).a).__name__ 'Pose'
- from_tuple(*, auto_batch_size: bool = False, batch_dims: int | None = None, device: torch.device | None = None, batch_size: torch.Size | None = None)#
Converts a tuple to a tensordict with the keys
"0","1", …Each element is converted with
from_any(), so a nested tuple or dict becomes a nested tensordict and a number becomes a tensor.- Parameters:
obj (tuple) – the tuple to convert.
- Keyword Arguments:
auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.device (torch.device, str or int, optional) – the device of the result. Leaves on another device are moved to it.
Noneleaves each leaf where it is, and the result has no device. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. It applies to the nested tensordicts too. Exclusive with
auto_batch_size. Defaults toNone, an empty batch size.
- Returns:
A
TensorDict.- Raises:
TypeError – if both
auto_batch_size=Trueandbatch_sizeare given.
Examples
>>> import torch >>> from tensordict import TensorDict >>> td = TensorDict.from_tuple((torch.zeros(3, 4), 1), auto_batch_size=True) >>> td["0"].shape, td["1"], td.batch_size (torch.Size([3, 4]), tensor(1), torch.Size([])) >>> td = TensorDict.from_tuple((torch.zeros(3, 4), torch.ones(3)), auto_batch_size=True) >>> td.batch_size torch.Size([3])
- from_zarr(*, mode: str = 'r', auto_batch_size: bool = False, batch_dims: int | None = None, batch_size: torch.Size | None = None, non_tensor_as_stack: bool = False, allow_pickle: bool | None = None)#
Opens a zarr store as a
PersistentTensorDict.The data stays in the store: entries are read when they are accessed. Requires
zarr>=3.1.1. See Save and load tensordicts andPersistentTensorDict.- Parameters:
filename (str, path or zarr store) – the path to the zarr store (a directory), or a
zarr.abc.store.Storeinstance (e.g. azarr.storage.ZipStore).- Keyword Arguments:
mode (str, optional) – how the store is opened:
"r"(read only),"r+"(read and write), and so on, as inzarr.open_group(). Defaults to"r".auto_batch_size (bool, optional) – if
True, sets the batch size to the largest leading shape that all the entries share. Exclusive withbatch_size. Defaults toFalse.batch_dims (int, optional) – with
auto_batch_size, the maximum number of batch dimensions. Ignored withoutauto_batch_size, with aFutureWarningwhen it would change the result. Starting with TensorDict 0.17, the default will change to turning onauto_batch_sizewhenbatch_dimsis given, asfrom_dictdoes. Defaults toNone.batch_size (torch.Size or list of int, optional) – the batch size of the result: the leading dimensions that all its entries share. Exclusive with
auto_batch_size. Defaults toNone, which reads the batch size and the names of the batch dimensions thatto_zarr()stored, or, for a store written by another tool, gives each nested tensordict the largest batch size that its entries share.non_tensor_as_stack (bool, optional) – if
True, a non-tensor array that tensordict did not write, such as a string column with one string per row, reads as aNonTensorStackof its rows when its leading dimensions equal the batch size. Otherwise it reads as oneNonTensorDatathat holds the whole array. Defaults toFalse.allow_pickle (bool, optional) – whether to decode pickled non-tensor values.
Falserejects them before decoding.Truepermits them: use it only for data you trust.Nonepermits them with aFutureWarningwhen read. Starting with TensorDict 0.17, the default will change toallow_pickle=False. Tensor and JSON entries are unaffected. Defaults toNone.
- Returns:
A
PersistentTensorDictbacked by the store.- Raises:
TypeError – if both
auto_batch_size=Trueandbatch_sizeare given.
Examples
>>> import os >>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> data = TensorDict(key1=torch.zeros(3), key2=torch.ones(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as tmpdir: ... path = os.path.join(tmpdir, "store.zarr") ... _ = data.to_zarr(path) ... td = TensorDict.from_zarr(path) ... print(td) PersistentTensorDict(batch_size=[3], fields={key1: f32[], key2: f32[]})
- fromkeys(value: Any = 0)#
Creates a tensordict with the same value for every key, like
dict.fromkeys().The result is a
TensorDictwith an empty batch size. A nested key creates nested tensordicts. A Python number becomes a tensor for each key, and a tensor is stored as it is: every key then holds the same tensor object.- Parameters:
keys (list of NestedKey) – the keys of the result.
value (Any, optional) – the value of every key: a tensor, a number, or any value that the
TensorDictconstructor takes. Defaults to0.
Examples
>>> import torch >>> from tensordict import TensorDict >>> td = TensorDict.fromkeys(["a", ("b", "c")], torch.zeros(3)) >>> td["b", "c"] tensor([0., 0., 0.]) >>> td["a"] is td["b", "c"] True
- lazy_stack(dim: int = 0, *, out=None, **kwargs)#
Stacks tensordicts into a lazy stack.
A lazy stack keeps the tensordicts as they are and stacks their values only when you read them. The tensordicts can have different keys and different feature shapes. See Stacking and variable-size data.
- Parameters:
input (sequence of TensorDictBase) – the tensordicts to stack.
dim (int, optional) – the new batch dimension. Defaults to
0.
- Keyword Arguments:
out (TensorDictBase, optional) – a lazy stack to write the result into. Defaults to
None.**kwargs – passed to
LazyStackedTensorDict.lazy_stack, for examplestack_dim_nameorstrict_shape.
Examples
>>> import torch >>> from tensordict import TensorDict >>> a = TensorDict(x=torch.zeros(3), batch_size=[3]) >>> b = TensorDict(y=torch.ones(3), batch_size=[3]) >>> stack = TensorDict.lazy_stack([a, b]) >>> type(stack).__name__, stack.batch_size ('LazyStackedTensorDict', torch.Size([2, 3]))
- load(*args, **kwargs) Self#
Loads a tensordict that
save()ormemmap()wrote to disk.loadcallsload_memmap(), which documents the other arguments, such asdevice,mode,subpathandallow_pickle. The leaves of the result read the files lazily. See Save and load tensordicts.- Parameters:
prefix (str or Path) – the directory, or the archive file, to read.
*args – passed to
load_memmap().**kwargs – passed to
load_memmap().
Examples
>>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> td = TensorDict(a=torch.arange(3), batch_size=[3]) >>> with tempfile.TemporaryDirectory() as path: ... _ = td.save(path) ... loaded = TensorDict.load(path) ... print(loaded["a"], loaded.batch_size) MemoryMappedTensor([0, 1, 2]) torch.Size([3])
- load_memmap(device: torch.device | None = None, non_blocking: bool = False, *, out: TensorDictBase | None = None, robust_key: bool | None = True, subpath: NestedKey | None = None, mode: str | None = None, num_threads: int = 0, allow_pickle: bool | None = None) Self#
Loads a tensordict that
memmap()orsave()wrote, from a directory or an archive.The leaves of the result read the files lazily: from a directory, each leaf is a
MemoryMappedTensorof its file, and from an archive, each leaf is a view into one memory map of the archive. Only the pages of the leaves that you use are read from disk. The result has the class that was saved (a tensorclass is loaded as that tensorclass), and it is not locked.load()is this method. See Save and load tensordicts.- Parameters:
prefix (str or Path) – the directory to read, or an archive file written by
save(..., archive=True), by a".tdz"prefix, or bypack_memmap().device (torch.device, str or int, optional) – the device of the result. The leaves are copied to it, which reads the files, unless it is the CPU. With
"meta", no file is read: the leaves are meta tensors, which show the structure and size of the data. Defaults toNone, which keeps the leaves on the CPU, memory-mapped.non_blocking (bool, optional) – if
True, does not synchronize the device after the copies todevice. Defaults toFalse.
- Keyword Arguments:
out (TensorDictBase, optional) – a tensordict to load the data into. Its nested tensordicts are reused, but its leaves are replaced by the loaded tensors, so their storage is not reused. Its keys that are not in the saved data are removed. If
outhas a device, the data is loaded on it, and anotherdeviceraises aValueError. To write the data into the storage ofout, useout.update_(TensorDict.load_memmap(prefix, device=device)). Defaults toNone.robust_key (bool, optional) – if
True, reads the percent-encoded file names thatmemmap()writes by default, and falls back to the legacy names of keys that are safe file names. IfFalse, reads the legacy layout only.Noneis the same asTrue. Defaults toTrue.subpath (NestedKey or str, optional) – the nested tensordict to load, as a nested key (
("module", "0")) or as a"/"-separated path ("module/0"). Only that subtree is read, from a directory or an archive. A nested key reaches the entries of a saved tensorclass asobj.get(key)does. Defaults toNone, which loads the whole tensordict.mode (str, optional) – how the files are mapped. With
"r", the mapping is copy-on-write: in-place writes into the leaves stay in the memory of this process, and the files do not change. For a directory, a pickled copy (amultiprocessingqueue, a spawned worker) or atorch.save()of the result reads the files, without these writes: send or saveclone()to keep them. With"r+", in-place writes reach the files, and a file that the process cannot write raises aPermissionError. Defaults toNone, which maps an archive as with"r", and each file of a directory as with"r+"if the process can write it, and as with"r"otherwise. See the note below.num_threads (int, optional) – the number of threads that decompress the leaves of a compressed archive. It has no effect on an uncompressed archive or a directory. Defaults to
0, which decompresses them one after the other.allow_pickle (bool, optional) – whether non-tensor data saved with
picklemay be loaded. Pickle can run arbitrary code: passTrueonly for data you trust, andFalsefor other data, which raises aRuntimeErroron pickled data. Defaults toNone, which loads pickled data with aFutureWarning. Starting with TensorDict 0.16, the default will change toFalse. Data saved without pickle loads with any value.
- Returns:
The loaded tensordict, or
outif it is given.- Raises:
ValueError – if
prefixis a file that is not an archive, ifsubpathnames no saved tensordict, or ifmodeis notNone,"r"or"r+".
Note
Load with
mode="r"data that you only read: on some network file systems (for example Lustre), page faults on a shared writable mapping take write locks, so readers on different nodes block each other. On Linux, a copy-on-write mapping counts against the memory commit limit, so a file larger than RAM plus swap can fail to map with"r". With"r",memmap_()without a prefix does not write back toprefix.Note
An archive opened with
mode="r+"must have uncompressed, aligned payloads (as written by tensordict withoutcompression) and no nested tensor. In-place writes do not update the CRC-32 checksums of its entries:load_memmapdoes not check them, but callrefresh_archive_checksums()before you give the archive to a tool that does, such asunzip.Examples
>>> import tempfile >>> import torch >>> from tensordict import TensorDict >>> td = TensorDict(a=torch.zeros(3), nested=TensorDict(b=torch.ones(3))) >>> with tempfile.TemporaryDirectory() as path: ... _ = td.memmap(path) ... loaded = TensorDict.load_memmap(path) ... print((loaded == td).all(), type(loaded["a"]).__name__) ... # load one nested tensordict ... print(TensorDict.load_memmap(path, subpath="nested")["b"]) ... # read the structure without reading the data ... print(TensorDict.load_memmap(path, device="meta")["a"].device) True MemoryMappedTensor MemoryMappedTensor([1., 1., 1.]) meta
With a
FakeTensorModeactive, the leaves are fake tensors and no file is read:>>> from torch._subclasses import FakeTensorMode >>> with tempfile.TemporaryDirectory() as path: ... _ = td.memmap(path) ... with FakeTensorMode(): ... print(type(TensorDict.load_memmap(path)["a"]).__name__) FakeTensor
- maybe_dense_stack(dim: int = 0, *, out=None, **kwargs)#
Stacks tensordicts densely if possible, or into a lazy stack otherwise.
The result is a
TensorDictif the tensordicts have the same keys and shapes, and aLazyStackedTensorDictotherwise. See Stacking and variable-size data.- Parameters:
input (sequence of TensorDictBase) – the tensordicts to stack.
dim (int, optional) – the new batch dimension. Defaults to
0.
- Keyword Arguments:
out (TensorDictBase, optional) – a tensordict to write the result into. Defaults to
None.**kwargs – passed to
LazyStackedTensorDict.maybe_dense_stack, for examplestrict.
Examples
>>> import torch >>> from tensordict import TensorDict >>> a = TensorDict(x=torch.zeros(3), batch_size=[3]) >>> b = TensorDict(x=torch.ones(3), batch_size=[3]) >>> c = TensorDict(y=torch.ones(3), batch_size=[3]) >>> type(TensorDict.maybe_dense_stack([a, b])).__name__ 'TensorDict' >>> type(TensorDict.maybe_dense_stack([a, c])).__name__ 'LazyStackedTensorDict'
- stack(dim: int = 0, *, out=None)#
Stacks tensordicts into one dense tensordict along a new dimension
dim.It is equivalent to
torch.stack(), and also works undertorch.compile(). The tensordicts must have the same batch size and the same keys, or aRuntimeErroris raised. To stack tensordicts with different keys or shapes, uselazy_stack(). See Stacking and variable-size data.- Parameters:
input (sequence of TensorDictBase) – the tensordicts to stack.
dim (int, optional) – the new batch dimension. Defaults to
0.
- Keyword Arguments:
out (TensorDictBase, optional) – a tensordict to write the result into. Defaults to
None.
Examples
>>> import torch >>> from tensordict import TensorDict >>> a = TensorDict(x=torch.zeros(3), batch_size=[3]) >>> b = TensorDict(x=torch.ones(3), batch_size=[3]) >>> TensorDict.stack([a, b]).batch_size torch.Size([2, 3])