TensorDictStore#
TensorDictStore has the methods of TensorDictBase,
listed by task in Methods by task. This page lists only the
methods that TensorDictStore adds, and the overrides that have their own
documentation.
- class tensordict.store.TensorDictStore(*, backend: Literal['redis', 'dragonfly'] = 'redis', host: str = 'localhost', port: int = 6379, db: int = 0, unix_socket_path: str | None = None, prefix: str = 'tensordict', batch_size=None, device=None, client=None, td_id: str | None = None, cache_metadata: bool = True, **redis_kwargs)#
Bases:
_StoreConnection,_StoreUnsupported,TensorDictBaseA TensorDict whose entries live on a Redis-compatible server.
Supports Redis, Dragonfly, KeyDB, and any other Redis-wire-compatible server.
Use it to share data between processes or machines, or to keep data out of the RAM of the training process. Each tensor entry is stored as one string of raw bytes on the server. Its shape and dtype are stored next to it, so that
keys()andshapedo not download the data. See Large datasets and storage backends for a guide.Each read or write blocks until the server answers. Internally, the client is a
redis.asyncio.Redisclient that runs on a background event loop, so that one call can send many commands in one round-trip.Lifecycle and limits
The store needs a running server. By default it connects to
localhost:6379. To start a local Redis server, rundocker run -d -p 6379:6379 redis.The data stays on the server after
close(), after the object is garbage collected, and after the process ends. The server keeps it in its memory until you delete it.To reconnect from another process, pass the
td_idof the store tofrom_store(), which also reads the batch size and the device. The id is in the private attribute_td_id, and is shown byrepr. There is no public accessor.close()closes the connection and stops the background loop. The object cannot read or write after that, and the data stays on the server.clear_redis()deletes the data and keeps the connection open.Each tensor entry is one string on the server. Redis limits a string to 512 MB by default (
proto-max-bulk-len), and a larger write raisesredis.exceptions.ResponseError. For larger entries, raise the limit on the server, or split the entry.Non-tensor values are stored as JSON. A value that JSON cannot encode is stored with
pickle, and each read unpickles it. Any client that can write to the server can then run code in the readers, so connect only to a server that you trust.
- Keyword Arguments:
backend (str) – Name of the server backend. Accepted values include
"redis"(default),"dragonfly","keydb", or any other string. It is a label, kept in the object and shown byrepr. All servers use the same wire protocol, so the value does not change how the store connects.host (str) – Server hostname. Defaults to
"localhost".port (int) – Server port. Defaults to
6379.db (int) – Database number. Defaults to
0.unix_socket_path (str, optional) – Path to a Unix domain socket, for a server on the same machine. If set,
hostandportare ignored.prefix (str, optional) – A namespace prefix for all keys. Defaults to
"tensordict".batch_size (Size or compatible) – The TensorDict batch size. Defaults to
torch.Size(()).device (device or compatible, optional) – Target device for retrieved tensors. Defaults to
None(CPU).client – An existing
redis.asyncio.Redisclient instance. If provided,host/port/db/unix_socket_pathare ignored.td_id (str, optional) – A unique identifier for this TensorDict in the store. Defaults to a new UUID. Pass an existing ID to reconnect to previously stored data. The constructor does not read the stored batch size: use
from_store()to reconnect.cache_metadata (bool) – If
True(default), cache tensor metadata locally to reduce round-trips.**redis_kwargs – Additional keyword arguments passed to
redis.asyncio.Redis.
Examples
The example needs a Redis server on
localhost:6379.>>> import torch >>> from tensordict.store import TensorDictStore >>> # Redis backend (default) >>> td = TensorDictStore(batch_size=[100]) >>> td["obs"] = torch.randn(100, 84) >>> td["obs"].shape # fetched from the store torch.Size([100, 84]) >>> local_td = td.to_tensordict() >>> type(local_td).__name__ 'TensorDict' >>> td.clear_redis() # delete the data on the server >>> td.close()
To connect to a Dragonfly server (same wire protocol as Redis) on another host, pass its address, for example
TensorDictStore(backend="dragonfly", host="dragonfly-host", batch_size=[100]).Note
Requires
redispackage:pip install redis.Note
Tensors are stored as CPU contiguous bytes. The
deviceattribute controls the device tensors are cast to upon retrieval.- flatten_keys(separator='.', inplace=False, is_leaf=None)#
Returns an in-memory copy where the nested keys are joined by
separator.The content is first loaded with
to_tensordict().- Parameters:
separator (str, optional) – the separator between the nested items. Defaults to
".".inplace (bool, optional) – must be
False;Trueraises aValueError. Defaults toFalse.is_leaf (callable, optional) – see
flatten_keys().
See
flatten_keys().
- classmethod from_dict(input_dict, *, backend: Literal['redis', 'dragonfly'] = 'redis', host: str = 'localhost', port: int = 6379, db: int = 0, unix_socket_path: str | None = None, prefix: str = 'tensordict', auto_batch_size: bool = False, batch_size=None, device=None, batch_dims: int | None = None, names: Sequence[str] | None = None, **kwargs)#
Create a TensorDictStore from a dictionary or TensorDict.
- Parameters:
input_dict – A dictionary or TensorDict to store.
- Keyword Arguments:
backend (str) – Store backend (
"redis","dragonfly", etc.). A label only (seeTensorDictStore).host (str) – Server hostname. Defaults to
"localhost".port (int) – Server port. Defaults to
6379.db (int) – Database number. Defaults to
0.unix_socket_path (str, optional) – Unix socket path. If set,
hostandportare ignored.prefix (str) – Key namespace. Defaults to
"tensordict".auto_batch_size (bool) – if
True, a dictinput_dictwithoutbatch_sizegives the store the largest leading shape that all its entries share, asauto_batch_size_()gives. Defaults toFalse.batch_size – Explicit batch_size. Defaults to the batch size of
input_dictif it is a TensorDict. For a dict, defaults to[], or to the inferred batch size withauto_batch_size=True.device – Target device for tensor retrieval.
batch_dims (int, optional) – for a dict
input_dictwithoutbatch_size, the number of leading dims of the inferred batch size; impliesauto_batch_size=True. Exclusive withbatch_size.names (list of str, optional) – the dimension names of the store.
**kwargs – Additional connection kwargs.
- Returns:
A new TensorDictStore.
Examples
The example needs a Redis server on
localhost:6379.>>> import torch >>> from tensordict.store import TensorDictStore >>> store = TensorDictStore.from_dict({"a": torch.zeros(5, 3)}, batch_size=[5]) >>> store.batch_size torch.Size([5]) >>> store.clear_redis() >>> store.close()
- classmethod from_schema(schema: dict[str, tuple[list[int] | Size, dtype]], *, batch_size: Sequence[int] | Size | None = None, backend: Literal['redis', 'dragonfly'] = 'redis', host: str = 'localhost', port: int = 6379, db: int = 0, unix_socket_path: str | None = None, prefix: str = 'tensordict', device=None, **kwargs) TensorDictStore#
Creates a store with zero-filled entries of known shapes, without sending any data from Python.
Creates a new
TensorDictStoreand registers each key inschemawith its shape and dtype. The server allocates each entry withSETRANGEand fills it with zeros. No tensor data goes through the Python process, but the server allocates the full size in its memory at once.Use it for a replay buffer or another shared buffer whose schema you know before you fill it.
Each entry is one string on the server. Redis limits a string to 512 MB by default (
proto-max-bulk-len). A larger entry raisesredis.exceptions.ResponseError: raise the limit on the server, or split the entry.- Parameters:
schema – Mapping from field name (a str, or a tuple of str for a nested entry) to
(element_shape, dtype).element_shapeis the per-element shape (excludingbatch_size). The full stored shape is[*batch_size, *element_shape].- Keyword Arguments:
batch_size – Overall batch size of the store.
backend (str) – Store backend. Defaults to
"redis".host (str) – Server hostname. Defaults to
"localhost".port (int) – Server port. Defaults to
6379.db (int) – Database number. Defaults to
0.unix_socket_path (str, optional) – Unix socket path.
prefix (str) – Key namespace. Defaults to
"tensordict".device – Device override for retrieved tensors.
**kwargs – Extra connection kwargs passed to the Redis client.
- Returns:
A new
TensorDictStorewith pre-allocated (zero-filled) keys.
Examples
The example needs a Redis server on
localhost:6379. Theobsentry takes 21 MB on the server.>>> import torch >>> from tensordict import TensorDict >>> from tensordict.store import TensorDictStore >>> store = TensorDictStore.from_schema( ... {"obs": ([84, 84, 3], torch.uint8), ... "action": ([4], torch.float32), ... "reward": ([], torch.float32)}, ... batch_size=[1000], ... ) >>> store["obs"].shape torch.Size([1000, 84, 84, 3]) >>> store[0] = TensorDict( ... obs=torch.ones(84, 84, 3, dtype=torch.uint8), ... action=torch.ones(4), ... reward=torch.ones(()), ... batch_size=[], ... ) >>> store["action"][:2] tensor([[1., 1., 1., 1.], [0., 0., 0., 0.]]) >>> store.clear_redis() >>> store.close()
- classmethod from_store(*, backend: Literal['redis', 'dragonfly'] = 'redis', host: str = 'localhost', port: int = 6379, db: int = 0, unix_socket_path: str | None = None, prefix: str = 'tensordict', td_id: str, device=None, tensorclass_cls: type | str | None = None, **kwargs) TensorDictStore#
Connect to an existing TensorDictStore on a remote server.
This is the cross-node entry point: one process stores data with
from_tensordict()(or regular__setitem__), and another process on any machine that can reach the same server reconstructs the handle by passing the sametd_id.Batch size and device are read from the metadata already persisted in the store by the original writer.
If the original writer was a TensorClass instance, the class path is stored automatically. On retrieval, the TensorClass is reconstructed by importing the class. You can also pass
tensorclass_clsexplicitly to override or skip the auto-import.- Keyword Arguments:
backend (str) – Store backend (
"redis","dragonfly", etc.).host (str) – Server hostname. Defaults to
"localhost".port (int) – Server port. Defaults to
6379.db (int) – Database number. Defaults to
0.unix_socket_path (str, optional) – Unix socket path.
prefix (str) – Key namespace. Defaults to
"tensordict".td_id (str) – The unique identifier of the TensorDict to reconnect to. Obtain this from a previously created instance via
td._td_id(a private attribute: there is no public accessor), or read it in itsrepr.device (device, optional) – Device override for retrieved tensors. If
None, uses the device stored in the server.tensorclass_cls (type | str | None) – TensorClass to wrap the result with. If a class, used directly via
cls._from_tensordict. If a string, interpreted as a fully-qualified class path ("module.ClassName") and imported. IfNone(default), the class path stored in the server (if any) is used automatically.**kwargs – Extra keyword arguments for the constructor, such as
cache_metadata, and connection kwargs for the Redis client.
- Returns:
A TensorDictStore (or TensorClass wrapping one) connected to the existing data.
Examples
On node A (writer):
td = TensorDictStore(host="my-server", batch_size=[100]) td["obs"] = torch.randn(100, 84) print(td._td_id) # e.g. "a1b2c3d4-..."
On node B (reader):
td = TensorDictStore.from_store( host="my-server", td_id="a1b2c3d4-...", ) td["obs"] # fetched from the shared store
- classmethod from_tensordict(td: TensorDictBase, *, backend: Literal['redis', 'dragonfly'] = 'redis', host: str = 'localhost', port: int = 6379, db: int = 0, unix_socket_path: str | None = None, prefix: str = 'tensordict', device=None, **kwargs) TensorDictStore#
Upload a TensorDict to a key-value store.
Creates a new
TensorDictStoreand copies all tensor data from the provided TensorDict into the store.- Parameters:
td (TensorDictBase) – The source TensorDict whose data will be stored.
- Keyword Arguments:
backend (str) – Store backend (
"redis","dragonfly", etc.).host (str) – Server hostname. Defaults to
"localhost".port (int) – Server port. Defaults to
6379.db (int) – Database number. Defaults to
0.unix_socket_path (str, optional) – Unix socket path.
prefix (str) – Key namespace. Defaults to
"tensordict".device (device, optional) – Device override for retrieved tensors. If
None, uses the source TensorDict’s device.**kwargs – Extra connection kwargs.
- Returns:
A new TensorDictStore backed by the uploaded data.
A
LazyStackedTensorDictgives aLazyStackedTensorDictStore, which keeps the entries of different shapes.Examples
The example needs a Redis server on
localhost:6379. For a server on another machine, passhost.>>> import torch >>> from tensordict import TensorDict >>> from tensordict.store import TensorDictStore >>> local = TensorDict({"obs": torch.randn(10, 84)}, [10]) >>> remote = TensorDictStore.from_tensordict(local) >>> remote["obs"].shape torch.Size([10, 84]) >>> remote.clear_redis() >>> remote.close()
- to_local() TensorDict#
Pull the entire Redis-backed dict into local RAM.
Alias for
to_tensordict().Deprecated since version 0.15: Use
to_tensordict()instead.