Download code/models/tt_transformers/tt/multimodal/llama_positional_embedding.py from tt-hous/clef: direct link, hf CLI and curl.
- Browser
- Download file 4.97 kB
-
https://huggingface.co/tt-hous/clef/resolve/main/code/models/tt_transformers/tt/multimodal/llama_positional_embedding.py
- Command line
-
hf download hf://tt-hous/clef/code/models/tt_transformers/tt/multimodal/llama_positional_embedding.py
-
curl -L -o llama_positional_embedding.py https://huggingface.co/tt-hous/clef/resolve/main/code/models/tt_transformers/tt/multimodal/llama_positional_embedding.py
4.97 kB
| # SPDX-FileCopyrightText: © 2023 Tenstorrent USA, Inc. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| import itertools | |
| import torch | |
| import ttnn | |
| from models.common.lightweightmodule import LightweightModule | |
| TILE_SIZE = 32 | |
| class TtLlamaPositionalEmbedding(LightweightModule): | |
| """Positional Embedding layer. | |
| Adds positional embeddings corresponding to each patch | |
| and tile location in the input tensor. | |
| """ | |
| def __init__( | |
| self, | |
| mesh_device, | |
| state_dict, | |
| state_dict_prefix, | |
| weight_cache_path, | |
| dtype, | |
| configuration, | |
| ): | |
| super().__init__() | |
| self.mesh_device = mesh_device | |
| positional_embedding = state_dict[f"{state_dict_prefix}positional_embedding"] | |
| gated_positional_embedding = state_dict[f"{state_dict_prefix}gated_positional_embedding"] | |
| gated_positional_embedding_gate = state_dict[f"{state_dict_prefix}gated_positional_embedding_gate"] | |
| positional_embedding = positional_embedding.unsqueeze(0) # Add batch dimensions | |
| pos_embed_device = ttnn.as_tensor( | |
| positional_embedding, | |
| dtype=dtype, | |
| layout=ttnn.TILE_LAYOUT, | |
| device=self.mesh_device, | |
| memory_config=ttnn.DRAM_MEMORY_CONFIG, | |
| mesh_mapper=ttnn.ReplicateTensorToMesh(self.mesh_device), | |
| ) | |
| # as_tensor returns (padded_shape, dim) which is incorrect, this reshape updates the padded size to the correct size | |
| self.positional_embedding = ttnn.reshape(pos_embed_device, positional_embedding.shape, pos_embed_device.shape) | |
| padded_gated_embeddings, self.ar_mapping = self.generate_padded_gated_embeddings( | |
| gated_positional_embedding, gated_positional_embedding_gate | |
| ) | |
| padded_gated_embed = ttnn.as_tensor( | |
| padded_gated_embeddings, | |
| dtype=dtype, | |
| layout=ttnn.TILE_LAYOUT, | |
| device=self.mesh_device, | |
| memory_config=ttnn.DRAM_MEMORY_CONFIG, | |
| mesh_mapper=ttnn.ReplicateTensorToMesh(self.mesh_device), | |
| ) | |
| # as_tensor returns (padded_shape, dim) which is incorrect, this reshape updates the padded size to the correct size | |
| self.padded_gated_positional_embedding = ttnn.reshape( | |
| padded_gated_embed, padded_gated_embeddings.shape, padded_gated_embed.shape | |
| ) | |
| # Add batch and ntok dimensions | |
| gated_positional_embedding_gate = gated_positional_embedding_gate.unsqueeze(0).unsqueeze(0) | |
| self.gated_positional_embedding_gate = ttnn.as_tensor( | |
| ( | |
| 1 - gated_positional_embedding_gate.tanh() | |
| ), # NOTE: The reference code has does the 1 - gate.tanh() at inference time | |
| dtype=ttnn.bfloat16, | |
| layout=ttnn.TILE_LAYOUT, | |
| device=self.mesh_device, | |
| memory_config=ttnn.DRAM_MEMORY_CONFIG, | |
| mesh_mapper=ttnn.ReplicateTensorToMesh(self.mesh_device), | |
| ) | |
| def generate_padded_gated_embeddings(self, gated_embedding, gate): | |
| num_tiles = gated_embedding.shape[0] | |
| # Generate all possible aspect ratios (H * W must be less than or equal to num_tiles) | |
| ratios = list(itertools.product(range(1, num_tiles + 1), repeat=2)) | |
| ratios = [x for x in ratios if x[0] * x[1] <= num_tiles] | |
| # Used to select the correct embedding for a given aspect ratio | |
| ar_mapping = {value: index for index, value in enumerate(ratios)} | |
| padded_embeds = [] | |
| for h, w in ratios: | |
| out_pos_embed = torch.zeros( | |
| 1, num_tiles, *gated_embedding.shape[2:] | |
| ) # 0th dim holds all possible embeddings for different aspect ratios | |
| out_pos_embed[0, : w * h] = gated_embedding[:h, :w].reshape(1, w * h, *gated_embedding.shape[2:]) | |
| padded_embeds.append(out_pos_embed * gate.tanh()) | |
| return torch.cat(padded_embeds, dim=0), ar_mapping | |
| def forward(self, x: ttnn.Tensor, ar: torch.Tensor): | |
| bsz, num_chunks, num_tokens, dim = x.shape | |
| x = ttnn.reshape(x, [bsz * num_chunks, num_tokens, dim]) | |
| pos_embed_ = self.positional_embedding * self.gated_positional_embedding_gate | |
| # Broadcast in batch dim # NOTE: TTNN broadcast add gives PCC issues | |
| pos_embed_ = ttnn.concat([pos_embed_] * x.shape[0], dim=0) | |
| x = x + pos_embed_ | |
| x = ttnn.reshape(x, [bsz, num_chunks, num_tokens, dim]) | |
| # Get the correct embeddings for the given aspect ratios | |
| gated_pos_embed_ = [] | |
| for [h, w] in ar: | |
| if isinstance(h, torch.Tensor): | |
| h, w = h.item(), w.item() | |
| idx = self.ar_mapping[(h, w)] | |
| gated_pos_embed_.append( | |
| self.padded_gated_positional_embedding[idx : idx + 1], # Select the correct embedding | |
| ) | |
| gated_pos_embed_ = ttnn.concat(gated_pos_embed_, dim=0) # Concat batch | |
| x = x + gated_pos_embed_ | |
| return x | |