Reconstruct and mix transformed outputs back into the original input sequence shape. Key operations: 1. Reshapes and transposes `transformed_x` to prepare for scattering. 2. Applies the `mask` to zero out invalid positions. 3. Uses `torch.scatter_add_` to scatter and sum the tr
(
transformed_x,
indices: torch.Tensor,
sorted_indices: torch.Tensor,
batch_size: int,
seq_len: int,
topk: int,
routing_weights: torch.Tensor,
mask: torch.Tensor
)
| 204 | |
| 205 | |
| 206 | def reconstruct( |
| 207 | transformed_x, |
| 208 | indices: torch.Tensor, |
| 209 | sorted_indices: torch.Tensor, |
| 210 | batch_size: int, |
| 211 | seq_len: int, |
| 212 | topk: int, |
| 213 | routing_weights: torch.Tensor, |
| 214 | mask: torch.Tensor |
| 215 | ): |
| 216 | ''' |
| 217 | Reconstruct and mix transformed outputs back into the original input sequence shape. |
| 218 | |
| 219 | Key operations: |
| 220 | 1. Reshapes and transposes `transformed_x` to prepare for scattering. |
| 221 | 2. Applies the `mask` to zero out invalid positions. |
| 222 | 3. Uses `torch.scatter_add_` to scatter and sum the transformed outputs back to their original positions based on `indices`. |
| 223 | 4. Rearranges the scattered outputs using `sorted_indices` to ensure correct ordering. |
| 224 | 5. Applies the `routing_weights` to weight the outputs. |
| 225 | 6. Sums over the `topk` dimension to produce the final reconstructed output. |
| 226 | |
| 227 | Args: |
| 228 | transformed_x (torch.Tensor): |
| 229 | The transformed output tensor from memory units or experts. |
| 230 | Shape: (num_memories, batch_size, capacity_len, hidden_size) |
| 231 | indices (torch.Tensor): |
| 232 | Indices used for scattering the transformed outputs back to their corresponding positions. |
| 233 | Shape: (batch*num_memories, max_len) |
| 234 | sorted_indices (torch.Tensor): |
| 235 | Sorting indices used to rearrange the scattered outputs back into the original sequence order. |
| 236 | Shape: (batch_size*seq_len*topk) |
| 237 | batch_size (int): |
| 238 | The size of the batch. |
| 239 | seq_len (int): |
| 240 | The length of the input sequence. |
| 241 | topk (int): |
| 242 | The number of top elements selected (`topk`) per token during the selection process. |
| 243 | routing_weights (torch.Tensor): |
| 244 | Routing weights assigned to the top-k selected outputs when reconstructing the final output. |
| 245 | Shape: (batch_size, seq_len, topk) |
| 246 | mask (torch.Tensor): |
| 247 | Boolean mask indicating valid positions in the sequence. |
| 248 | Shape: (batch*num_memories, max_len) |
| 249 | |
| 250 | Returns: |
| 251 | restored_x (torch.Tensor): |
| 252 | The reconstructed output tensor in the original input sequence shape. |
| 253 | Shape: (batch_size, seq_len, hidden_size) |
| 254 | ''' |
| 255 | transformed_x = transformed_x.transpose(0, 1).reshape( |
| 256 | (-1, transformed_x.shape[2], transformed_x.shape[3])) |
| 257 | b, s, k, d = batch_size, seq_len, topk, transformed_x.shape[2] |
| 258 | gathered_x = transformed_x.reshape( |
| 259 | (transformed_x.shape[0] * transformed_x.shape[1], transformed_x.shape[2])) |
| 260 | mask_expanded = mask.reshape(-1).unsqueeze(-1).expand_as(gathered_x) |
| 261 | gathered_x = gathered_x * mask_expanded |
| 262 | |
| 263 | assert (indices >= 0).all(), "Indices should be non-negative" |