Skip to content

PyTree Traversal

About

The d9d.core.pytree package traverses nested tensor structures (pytrees) recursively. It is a thin wrapper around optree that also descends into dataclasses. d9d uses it wherever it applies an operation to every tensor in a nested structure. Examples are moving a microbatch to the device, moving metric results to the CPU and flattening a metric tree for logging.

Supported Containers

The package traverses the containers that PyTree describes (dict, list, tuple), nested to any depth. It also traverses any dataclass: the fields of a dataclass are its children in the tree.

Nesting works in every direction. A dataclass inside a dict, a list of dataclasses and a dataclass with dicts of tensors as fields are all traversed.

Traversal Order

Traversal order is deterministic:

  • dict keys are traversed in sorted order, whatever the insertion order.
  • Dataclass fields are traversed in declaration order.

Usage

Pass a dataclass, nested in containers or in other dataclasses, to any function of this package.

import dataclasses
import torch
from d9d.core import pytree


@dataclasses.dataclass
class Batch:
    tokens: torch.Tensor
    mask: torch.Tensor
    doc_id: str  # Non-tensor fields are allowed


batch = Batch(tokens=torch.zeros(8), mask=torch.ones(8), doc_id="doc-42")

# Every tensor field moves to the GPU; other fields stay unchanged.
on_cuda = pytree.tree_map_only(torch.Tensor, lambda t: t.cuda(), batch)

API Reference

d9d.core.pytree

Recursive traversal of nested tensor structures (PyTrees).

PyTreeSpec = optree.PyTreeSpec module-attribute

The structure of a PyTree without its leaves. Alias of optree.PyTreeSpec.

tree_flatten(tree, is_leaf=None)

Flattens a PyTree into its leaves and a structure specification.

Parameters:

Name Type Description Default
tree PyTree[TLeaf]

The nested structure to flatten.

required
is_leaf IsLeaf | None

An optional predicate. A node for which it returns True stays a leaf and is not traversed further.

None

Returns:

Type Description
tuple[list[TLeaf], PyTreeSpec]

A tuple of the leaf list and a PyTreeSpec that tree_unflatten can rebuild the structure from.

tree_leaves(tree, is_leaf=None)

Returns the leaves of a PyTree in deterministic (sorted-key) order.

Parameters:

Name Type Description Default
tree PyTree[TLeaf]

The nested structure to flatten.

required
is_leaf IsLeaf | None

An optional predicate. A node for which it returns True stays a leaf and is not traversed further.

None

Returns:

Type Description
list[TLeaf]

The list of leaves.

tree_leaves_with_path(tree, is_leaf=None)

Returns (path, leaf) pairs for every leaf of a PyTree.

Each path is a tuple of keys and indices reaching the leaf from the root: str for dict keys and dataclass field names, int for sequence indices.

Parameters:

Name Type Description Default
tree PyTree[TLeaf]

The nested structure to flatten.

required
is_leaf IsLeaf | None

An optional predicate. A node for which it returns True stays a leaf and is not traversed further.

None

Returns:

Type Description
list[tuple[tuple[Any, ...], TLeaf]]

A list of (path, leaf) tuples in deterministic (sorted-key) order.

tree_map(func, tree)

Applies func to every leaf of a PyTree and returns a tree with the same structure.

Parameters:

Name Type Description Default
func Callable[[TLeaf], TMapped]

The function to apply to each leaf.

required
tree PyTree[TLeaf]

The nested structure to map over.

required

Returns:

Type Description
PyTree[TMapped]

A new tree with func applied to each leaf.

tree_map_only(filters, func, tree)

Applies func only to leaves that are instances of filters.

Leaves of other types stay unchanged. Use it for trees that mix tensors with other data, for example to move only the tensors to a device. The returned tree has the same structure as the input.

Parameters:

Name Type Description Default
filters type | tuple[type, ...]

The leaf type or types to apply func to.

required
func Callable[[Any], Any]

The function to apply to matching leaves.

required
tree TTree

The nested structure to map over.

required

Returns:

Type Description
TTree

A new tree with func applied to matching leaves only.

tree_unflatten(treespec, leaves)

Reconstructs a PyTree from leaves and a structure specification.

Parameters:

Name Type Description Default
treespec PyTreeSpec

A specification produced by tree_flatten.

required
leaves list[TLeaf]

The leaves to place into the structure, in flatten order.

required

Returns:

Type Description
PyTree[TLeaf]

The reconstructed nested structure.