Named Tensors#
Created On: Oct 08, 2019 | Last Updated On: Jun 14, 2025
Named Tensors allow users to give explicit names to tensor dimensions.In most cases, operations that take dimension parameters will acceptdimension names, avoiding the need to track dimensions by position.In addition, named tensors use names to automatically check that APIsare being used correctly at runtime, providing extra safety. Names canalso be used to rearrange dimensions, for example, to support“broadcasting by name” rather than “broadcasting by position”.
Warning
The named tensor API is a prototype feature and subject to change.
Creating named tensors#
Factory functions now take a newnames argument that associates a namewith each dimension.
>>>torch.zeros(2,3,names=('N','C'))tensor([[0.,0.,0.],[0.,0.,0.]],names=('N','C'))
Named dimensions, like regular Tensor dimensions, are ordered.tensor.names[i] is the name of dimensioni oftensor.
The following factory functions support named tensors:
Named dimensions#
Seenames for restrictions on tensor names.
Usenames to access the dimension names of a tensor andrename() to rename named dimensions.
>>>imgs=torch.randn(1,2,2,3,names=('N','C','H','W'))>>>imgs.names('N','C','H','W')>>>renamed_imgs=imgs.rename(H='height',W='width')>>>renamed_imgs.names('N','C','height','width)
Named tensors can coexist with unnamed tensors; named tensors are instances oftorch.Tensor. Unnamed tensors haveNone-named dimensions. Namedtensors do not require all dimensions to be named.
>>>imgs=torch.randn(1,2,2,3,names=(None,'C','H','W'))>>>imgs.names(None,'C','H','W')
Name propagation semantics#
Named tensors use names to automatically check that APIs are being calledcorrectly at runtime. This occurs in a process calledname inference.More formally, name inference consists of the following two steps:
Check names: an operator may perform automatic checks at runtime thatcheck that certain dimension names must match.
Propagate names: name inference propagates names to output tensors.
All operations that support named tensors propagate names.
>>>x=torch.randn(3,3,names=('N','C'))>>>x.abs().names('N','C')
match semantics#
Two namesmatch if they are equal (string equality) or if at least one isNone.Nones are essentially a special “wildcard” name.
unify(A,B) determines which of the namesA andB to propagate to the outputs.It returns the morespecific of the two names, if they match. If the names do not match,then it errors.
Note
In practice, when working with named tensors, one should avoid having unnameddimensions because their handling can be complicated. It is recommended to liftall unnamed dimensions to be named dimensions by usingrefine_names().
Basic name inference rules#
Let’s see howmatch andunify are used in name inference in the case ofadding two one-dim tensors with no broadcasting.
x=torch.randn(3,names=('X',))y=torch.randn(3)z=torch.randn(3,names=('Z',))
Check names: check that the names of the two tensorsmatch.
For the following examples:
>>># x + y # match('X', None) is True>>># x + z # match('X', 'Z') is False>>># x + x # match('X', 'X') is True>>>x+zErrorwhenattemptingtobroadcastdims['X']anddims['Z']:dim'X'anddim'Z'areatthesamepositionfromtherightbutdonotmatch.
Propagate names:unify the names to select which one to propagate.In the case ofx+y,unify('X',None)='X' because'X' is morespecific thanNone.
>>>(x+y).names('X',)>>>(x+x).names('X',)
For a comprehensive list of name inference rules, seeNamed Tensors operator coverage.Here are two common operations that may be useful to go over:
Binary arithmetic ops:Unifies names from inputs
Matrix multiplication ops:Contracts away dims
Explicit alignment by names#
Usealign_as() oralign_to() to align tensor dimensionsby name to a specified ordering. This is useful for performing “broadcasting by names”.
# This function is agnostic to the dimension ordering of `input`,# as long as it has a `C` dimension somewhere.defscale_channels(input,scale):scale=scale.refine_names('C')returninput*scale.align_as(input)>>>num_channels=3>>>scale=torch.randn(num_channels,names=('C',))>>>imgs=torch.rand(3,3,3,num_channels,names=('N','H','W','C'))>>>more_imgs=torch.rand(3,num_channels,3,3,names=('N','C','H','W'))>>>videos=torch.randn(3,num_channels,3,3,3,names=('N','C','H','W','D')>>>scale_channels(imgs,scale)>>>scale_channels(more_imgs,scale)>>>scale_channels(videos,scale)
Manipulating dimensions#
Usealign_to() to permute large amounts of dimensions withoutmentioning all of them as in required bypermute().
>>>tensor=torch.randn(2,2,2,2,2,2)>>>named_tensor=tensor.refine_names('A','B','C','D','E','F')# Move the F (dim 5) and E dimension (dim 4) to the front while keeping# the rest in the same order>>>tensor.permute(5,4,0,1,2,3)>>>named_tensor.align_to('F','E',...)
Useflatten() andunflatten() to flatten and unflattendimensions, respectively. These methods are more verbose thanview()andreshape(), but have more semantic meaning to someone reading the code.
>>>imgs=torch.randn(32,3,128,128)>>>named_imgs=imgs.refine_names('N','C','H','W')>>>flat_imgs=imgs.view(32,-1)>>>named_flat_imgs=named_imgs.flatten(['C','H','W'],'features')>>>named_flat_imgs.names('N','features')>>>unflattened_named_imgs=named_flat_imgs.unflatten('features',[('C',3),('H',128),('W',128)])>>>unflattened_named_imgs.names('N','C','H','W')
Autograd support#
Autograd currently supports named tensors in a limited manner: autograd ignoresnames on all tensors. Gradient computation is still correct but we lose thesafety that names give us.
>>>x=torch.randn(3,names=('D',))>>>weight=torch.randn(3,names=('D',),requires_grad=True)>>>loss=(x-weight).abs()>>>grad_loss=torch.randn(3)>>>loss.backward(grad_loss)>>>weight.grad# Unnamed for now. Will be named in the futuretensor([-1.8107,-0.6357,0.0783])>>>weight.grad.zero_()>>>grad_loss=grad_loss.refine_names('C')>>>loss=(x-weight).abs()# Ideally we'd check that the names of loss and grad_loss match but we don't yet.>>>loss.backward(grad_loss)>>>weight.gradtensor([-1.8107,-0.6357,0.0783])
Currently supported operations and subsystems#
Operators#
SeeNamed Tensors operator coverage for a full list of the supported torch andtensor operations. We do not yet support the following that is not covered by the link:
indexing, advanced indexing.
Fortorch.nn.functional operators, we support the following:
Subsystems#
Autograd is supported, seeAutograd support.Because gradients are currently unnamed, optimizers may work but are untested.
NN modules are currently unsupported. This can lead to the following when callingmodules with named tensor inputs:
NN module parameters are unnamed, so outputs may be partially named.
NN module forward passes have code that don’t support named tensors and willerror out appropriately.
We also do not support the following subsystems, though some may work outof the box:
distributions
serialization (
torch.load(),torch.save())multiprocessing
JIT
distributed
ONNX
If any of these would help your use case, pleasesearch if an issue has already been filedand if not,file one.
Named tensor API reference#
In this section please find the documentation for named tensor specific APIs.For a comprehensive reference for how names are propagated through other PyTorchoperators, seeNamed Tensors operator coverage.
- classtorch.Tensor
- names#
Stores names for each of this tensor’s dimensions.
names[idx]corresponds to the name of tensor dimensionidx.Names are either a string if the dimension is named orNoneif thedimension is unnamed.Dimension names may contain characters or underscore. Furthermore, a dimensionname must be a valid Python variable name (i.e., does not start with underscore).
Tensors may not have two named dimensions with the same name.
Warning
The named tensor API is experimental and subject to change.
- rename(*names,**rename_map)[source]#
Renames dimension names of
self.There are two main usages:
self.rename(**rename_map)returns a view on tensor that has dimsrenamed as specified in the mappingrename_map.self.rename(*names)returns a view on tensor, renaming alldimensions positionally usingnames.Useself.rename(None)to drop names on a tensor.One cannot specify both positional args
namesand keyword argsrename_map.Examples:
>>>imgs=torch.rand(2,3,5,7,names=('N','C','H','W'))>>>renamed_imgs=imgs.rename(N='batch',C='channels')>>>renamed_imgs.names('batch', 'channels', 'H', 'W')>>>renamed_imgs=imgs.rename(None)>>>renamed_imgs.names(None, None, None, None)>>>renamed_imgs=imgs.rename('batch','channel','height','width')>>>renamed_imgs.names('batch', 'channel', 'height', 'width')
Warning
The named tensor API is experimental and subject to change.
- refine_names(*names)[source]#
Refines the dimension names of
selfaccording tonames.Refining is a special case of renaming that “lifts” unnamed dimensions.A
Nonedim can be refined to have any name; a named dim can only berefined to have the same name.Because named tensors can coexist with unnamed tensors, refining namesgives a nice way to write named-tensor-aware code that works with bothnamed and unnamed tensors.
namesmay contain up to one Ellipsis (...).The Ellipsis is expanded greedily; it is expanded in-place to fillnamesto the same length asself.dim()using names from thecorresponding indices ofself.names.Python 2 does not support Ellipsis but one may use a string literalinstead (
'...').- Parameters
names (iterable ofstr) – The desired names of the output tensor. Maycontain up to one Ellipsis.
Examples:
>>>imgs=torch.randn(32,3,128,128)>>>named_imgs=imgs.refine_names('N','C','H','W')>>>named_imgs.names('N', 'C', 'H', 'W')>>>tensor=torch.randn(2,3,5,7,11)>>>tensor=tensor.refine_names('A',...,'B','C')>>>tensor.names('A', None, None, 'B', 'C')
Warning
The named tensor API is experimental and subject to change.
- align_as(other)→Tensor#
Permutes the dimensions of the
selftensor to match the dimension orderin theothertensor, adding size-one dims for any new names.This operation is useful for explicit broadcasting by names (see examples).
All of the dims of
selfmust be named in order to use this method.The resulting tensor is a view on the original tensor.All dimension names of
selfmust be present inother.names.othermay contain named dimensions that are not inself.names;the output tensor has a size-one dimension for each of those new names.To align a tensor to a specific order, use
align_to().Examples:
# Example 1: Applying a mask>>>mask=torch.randint(2,[127,128],dtype=torch.bool).refine_names('W','H')>>>imgs=torch.randn(32,128,127,3,names=('N','H','W','C'))>>>imgs.masked_fill_(mask.align_as(imgs),0)# Example 2: Applying a per-channel-scale>>>defscale_channels(input,scale):>>>scale=scale.refine_names('C')>>>returninput*scale.align_as(input)>>>num_channels=3>>>scale=torch.randn(num_channels,names=('C',))>>>imgs=torch.rand(32,128,128,num_channels,names=('N','H','W','C'))>>>more_imgs=torch.rand(32,num_channels,128,128,names=('N','C','H','W'))>>>videos=torch.randn(3,num_channels,128,128,128,names=('N','C','H','W','D'))# scale_channels is agnostic to the dimension order of the input>>>scale_channels(imgs,scale)>>>scale_channels(more_imgs,scale)>>>scale_channels(videos,scale)
Warning
The named tensor API is experimental and subject to change.
- align_to(*names)[source]#
Permutes the dimensions of the
selftensor to match the orderspecified innames, adding size-one dims for any new names.All of the dims of
selfmust be named in order to use this method.The resulting tensor is a view on the original tensor.All dimension names of
selfmust be present innames.namesmay contain additional names that are not inself.names;the output tensor has a size-one dimension for each of those new names.namesmay contain up to one Ellipsis (...).The Ellipsis is expanded to be equal to all dimension names ofselfthat are not mentioned innames, in the order that they appearinself.Python 2 does not support Ellipsis but one may use a string literalinstead (
'...').- Parameters
names (iterable ofstr) – The desired dimension ordering of theoutput tensor. May contain up to one Ellipsis that is expandedto all unmentioned dim names of
self.
Examples:
>>>tensor=torch.randn(2,2,2,2,2,2)>>>named_tensor=tensor.refine_names('A','B','C','D','E','F')# Move the F and E dims to the front while keeping the rest in order>>>named_tensor.align_to('F','E',...)
Warning
The named tensor API is experimental and subject to change.
- flatten(dims,out_dim)→Tensor
Flattens
dimsinto a single dimension with nameout_dim.All ofdims must be consecutive in order in the
selftensor,but not necessary contiguous in memory.Examples:
>>>imgs=torch.randn(32,3,128,128,names=('N','C','H','W'))>>>flat_imgs=imgs.flatten(['C','H','W'],'features')>>>flat_imgs.names,flat_imgs.shape(('N', 'features'), torch.Size([32, 49152]))
Warning
The named tensor API is experimental and subject to change.