ttnn.all_to_all_combine
- ttnn.all_to_all_combine(input_tensor: ttnn.Tensor, expert_metadata_tensor: ttnn.Tensor, expert_mapping_tensor: ttnn.Tensor, *, local_reduce: bool = False, num_links: number = None, topology: ttnn.Topology = None, memory_config: ttnn.MemoryConfig = None, cluster_axis: int = None, subdevice_id: ttnn.SubDeviceId = None, output_tensor: ttnn.Tensor = None, output_shard_dim: int = 1) ttnn.Tensor
-
All to all combine operation for combining the output tokens from the experts, based on the expert metadata and expert mapping tensors. If cluster axis is specified then we combine the tokens only on that axis. This operation is the inverse of the all-to-all dispatch operation, used for returning the results of the experts back to the input tokens’ originating devices. B = batch size S = sequence length H = hidden size K = selected experts per token D = total number of devices A = cluster axis to combine along D[A] = number of devices along the cluster axis, just D if cluster axis is not specified. E = number of experts T = total number of tokens = B * S
- Parameters:
-
input_tensor (ttnn.Tensor) – the input tensor containing the tokens to combine. The tensor is expected to be [B, S, 1, H] ([B/D[A], S, 1, H] per device) where each row is a token. The tensor is expected to be in Row Major, Interleaved format. It is duplicated on the non-cluster axis.
expert_metadata_tensor (ttnn.Tensor) – the expert metadata tensor containing the ranking of the experts for each token. The tensor is expected to be [B, S, 1, K] ([B/D[A], S, 1, K] per device) where each value in the row is the expert index inside the mapping table. The tensor is expected to be in Row Major, Interleaved format. It is duplicated on the non-cluster axis.
expert_mapping_tensor (ttnn.Tensor) – the one-hot encoded expert to device mapping tensor containing the location of the experts among each device and each mesh. The tensor is expected to be [D, 1, E, D] ([1, 1, E, D] per device) where each value in the row is 1 if the expert is on the device, 0 otherwise. The tensor is expected to be in Row Major, Interleaved format. This tensor is expected to be the same across all devices.
- Keyword Arguments:
-
local_reduce (bool, optional) – whether or not the tokens are locally reduce prior to combining. The expectation is that the expert output tokens corresponding to the dispatched token are already reduced. Defaults to False.
num_links (number, optional) – the number of cross-device links to use for combining the tokens. Defaults to None, for which the number of links is determined automatically.
topology (ttnn.Topology, optional) – the topology to use when combining the tokens. Defaults to None, for which the topology is determined automatically.
memory_config (ttnn.MemoryConfig, optional) – Output memory configuration for the output tensors. Defaults to None.
cluster_axis (int, optional) – the cluster axis to combine along. Defaults to None, though we assert out when it is not specified.
subdevice_id (ttnn.SubDeviceId, optional) – the subdevice id for the subdevice on which we allocate the worker cores. Defaults to None.
output_tensor (ttnn.Tensor, optional) – the optional output tensor to use for the combined tokens. Defaults to None.
output_shard_dim (int, optional) – the dimension to shard the output tokens along. Defaults to 1, which is the batch dimension.
- Returns:
-
ttnn.Tensor – The combined tokens tensor. The tensor is expected to be [K, B, S, H] sharded along the output_shard_dim dimension across the number of devices along the cluster axis if it was set, or all devices if it was not set, (e.g. [K, B/D[A], S, H] per device if output_shard_dim is 1 or [K, B, S/D[A], H] per device if output_shard_dim is 2). The tensor is expected to be in Row Major, Interleaved format. The rows are sparsely populated such that each row is either a token if that token was dispatched to that device, or a placeholder row if that token was not dispatched to that device.
Supported dtypes and layouts:
Tensor
Dtypes
Layouts
input_tensor
BFLOAT16
ROW_MAJOR
expert_metadata_tensor
UINT16
ROW_MAJOR
expert_mapping_tensor
UINT16
ROW_MAJOR
All input tensors must be rank 4 and
cluster_axisis required.expert_mapping_tensormust be fully replicated across the mesh. Additional input-spec constraints enforced by the op:The number of experts must be evenly divisible by the number of devices.
Unless
local_reduceis set,input_tensor’s leading (expert) dimension must equalexperts / num_devices.output_shard_dimmust be 1 or 2. When it is 1, the metadata batch dimension must be divisible by the cluster-axis device count; when it is 2, the metadata sequence dimension must be divisible by the cluster-axis device count.
The output preserves the input dtype (BFLOAT16) and is ROW_MAJOR.
- Memory Support:
-
Interleaved: DRAM and L1
Sharded: not supported (output memory config must not be sharded)
Example
devices = 8 experts = 8 # must be divisible by the number of devices select_experts_k = 2 hidden_size = 128 batch, seq = 8, 2 # Expert contributions to combine: [experts, batch, seq, hidden], bfloat16, row-major, # sharded on dim 0 so each device holds its experts // devices slice. contributions = ttnn.from_torch( torch.randn([experts, batch, seq, hidden_size], dtype=torch.bfloat16), dtype=ttnn.bfloat16, layout=ttnn.ROW_MAJOR_LAYOUT, device=mesh_device, mesh_mapper=ttnn.ShardTensorToMesh(mesh_device, dim=0), ) # Expert metadata (indices per token), replicated per device: [devices, batch, seq, k], # uint16, sharded on dim 0 so each device receives a full [1, batch, seq, k] copy. expert_metadata = ttnn.from_torch( torch.randint(0, experts, [devices, batch, seq, select_experts_k], dtype=torch.int16), dtype=ttnn.uint16, layout=ttnn.ROW_MAJOR_LAYOUT, device=mesh_device, mesh_mapper=ttnn.ShardTensorToMesh(mesh_device, dim=0), ) # Expert-to-device mapping: [1, 1, experts, devices], uint16, fully replicated. mapping_torch = torch.zeros([1, 1, experts, devices], dtype=torch.int16) for e in range(experts): mapping_torch[0, 0, e, e % devices] = 1 expert_mapping = ttnn.from_torch( mapping_torch, dtype=ttnn.uint16, layout=ttnn.ROW_MAJOR_LAYOUT, device=mesh_device, mesh_mapper=ttnn.ShardTensor2dMesh(mesh_device, mesh_shape=(2, 4), dims=(None, None)), ) # cluster_axis is required for all_to_all_combine. output = ttnn.all_to_all_combine(contributions, expert_metadata, expert_mapping, cluster_axis=1, num_links=1) logger.info(output.shape)