CoolFace
Modelpublic

numind/NuExtract-large

sourceHugging Facemitupdated 4mo agoView on Hugging Face
122likes152downloads
modeling_phi3_small.py1141 linesDownload Raw Back to root
1import math2from typing import Any, Dict, Optional, List, Tuple, Union3import torch4import torch.nn as nn5import torch.nn.functional as F6 7 8from einops import rearrange9 10from transformers.modeling_outputs import SequenceClassifierOutputWithPast, CausalLMOutputWithPast, BaseModelOutputWithPast11from transformers.modeling_utils import PreTrainedModel12from transformers.utils import logging13 14from transformers.cache_utils import Cache, DynamicCache15 16from .triton_flash_blocksparse_attn import BlockSparseParams17from .triton_blocksparse_attention_layer import BlockSparseAttentionLayer18from .positional_embedding import RotaryEmbedding19 20from .configuration_phi3_small import Phi3SmallConfig21 22# Flash Attention Related Imports23is_flash_attention_available = False24try:25    import flash_attn26    if int(flash_attn.__version__.split('.')[0]) < 2:27        from flash_attn.flash_attn_interface import (28            flash_attn_func,29            flash_attn_unpadded_kvpacked_func as flash_attn_varlen_kvpacked_func,30            )31 32        # rename `max_seqlen`33        def flash_attn_varlen_qkvpacked_func(qkv, cu_seqlens, max_seqlen, dropout_p=0.0, **kwargs):34            return flash_attn_func(qkv, cu_seqlens, dropout_p=dropout_p, max_s=max_seqlen, **kwargs)35 36    else:37        from flash_attn.flash_attn_interface import (38            flash_attn_varlen_kvpacked_func,39        )40        from flash_attn.bert_padding import index_first_axis, pad_input, unpad_input41    is_flash_attention_available = True42except ImportError:43    pass44 45logger = logging.get_logger(__name__)46 47LegacyCache = Tuple[Tuple[torch.FloatTensor]]48 49# Taken from https://github.com/allenai/allennlp/blob/main/allennlp/nn/util.py50def info_value_of_dtype(dtype: torch.dtype):51    """52    Returns the `finfo` or `iinfo` object of a given PyTorch data type. Does not allow torch.bool.53    """54    if dtype == torch.bool:55        raise TypeError("Does not support torch.bool")56    elif dtype.is_floating_point:57        return torch.finfo(dtype)58    else:59        return torch.iinfo(dtype)60 61 62# Taken from https://github.com/allenai/allennlp/blob/main/allennlp/nn/util.py63def min_value_of_dtype(dtype: torch.dtype):64    """65    Returns the minimum value of a given PyTorch data type. Does not allow torch.bool.66    """67    return info_value_of_dtype(dtype).min68 69# Copied from transformers.models.llama.modeling_llama._get_unpad_data70def _get_unpad_data(attention_mask):71    seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)72    indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()73    max_seqlen_in_batch = seqlens_in_batch.max().item()74    cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.int32), (1, 0))75    return (76        indices,77        cu_seqlens,78        max_seqlen_in_batch,79    )80 81 82@torch.jit.script83def quick_gelu(x):84    return x * torch.sigmoid(1.702 * x)85 86 87@torch.jit.script88def gegelu(input, limit: Optional[float] = None):89    a_gelu, a_linear = input[..., ::2], input[..., 1::2]90    if limit is not None:91        a_gelu = torch.where(92            torch.isinf(a_gelu), a_gelu, a_gelu.clamp(min=None, max=limit)93        )94        a_linear = torch.where(95            torch.isinf(a_linear), a_linear, a_linear.clamp(min=-limit, max=limit)96        )97    out_gelu = quick_gelu(a_gelu)98    return out_gelu * (a_linear + 1)99 100def collapse_first_n_dims(x: torch.Tensor, n: int) -> torch.Tensor:101    """102    Collapse the first `n` dimensions of a tensor into a single dimension.103 104    Args:105        x (torch.Tensor): The input tensor.106        n (int): The number of dimensions to collapse.107 108    Returns:109        torch.Tensor: The output tensor.110    """111    return x.view(-1, *x.shape[n:])112 113def pad_tensor_to_next_mult_of(114    tensor: torch.Tensor,115    dim: int,116    n: int,117) -> Tuple[torch.Tensor, int]:118    """119    Pads a tensor along a specified dimension to the next multiple of a given number.120 121    Args:122        tensor (torch.Tensor): The input tensor.123        dim (int): The dimension along which to pad the tensor.124        n (int): The number to pad the tensor to the next multiple of.125 126    Returns:127        Tuple[torch.Tensor, int]: A tuple containing the padded tensor and the amount of padding added.128    """129    residual = tensor.size(dim) % n130    if residual == 0:131        return tensor, 0132    padding = n - residual133    padding_tensor = torch.zeros((*tensor.size()[:dim], padding, *tensor.size()[dim + 1:]), device=tensor.device, dtype=tensor.dtype)134    return torch.cat([tensor, padding_tensor], dim=dim), padding135 136def strip_padding_from_tensor(137    tensor: torch.Tensor,138    dim: int,139    residual: int,140) -> torch.Tensor:141    """142    Removes padding from a tensor along a specified dimension.143 144    Args:145        tensor (torch.Tensor): The input tensor.146        dim (int): The dimension along which to remove padding.147        residual (int): The amount of padding to remove.148 149    Returns:150        torch.Tensor: The tensor with padding removed along the specified dimension.151    """152    return torch.narrow(tensor, dim, 0, tensor.size(dim) - residual)153 154class Phi3SmallMLP(nn.Module):155    def __init__(self, config: Phi3SmallConfig):156        super().__init__()157        self.config = config158        assert self.config.hidden_act == "gegelu", "Only `gegelu` is supported for the Phi-3-small model .."159        self.hidden_size = config.hidden_size160        self.gegelu_limit = config.gegelu_limit161        self.intermediate_size = config.intermediate_size162 163        self.up_proj = nn.Linear(self.hidden_size, 2 * self.intermediate_size)164        self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size)165        self.dropout = nn.Dropout(config.ffn_dropout_prob)166    167    def forward(self, x: torch.Tensor) -> torch.Tensor:168        return self.dropout(169            self.down_proj(170                gegelu(self.up_proj(x), limit=self.gegelu_limit)171            )172        )173 174 175class Phi3SmallSelfAttention(nn.Module):176    def __init__(self, config: Phi3SmallConfig, layer_idx: Optional[int] = None) -> None:177        super().__init__()178        self.config = config179        self.layer_idx = layer_idx180        if layer_idx is None:181            logger.warning_once(182                f"Instantiating {self.__class__.__name__} without passing a `layer_idx` is not recommended and will "183                "lead to errors during the forward call if caching is used. Please make sure to provide a `layer_idx` "184                "when creating this class."185            )186        187        self.hidden_size = config.hidden_size188        # Number of Query Heads189        self.num_heads = config.num_attention_heads190        self.head_dim = self.hidden_size // self.num_heads191        # Number of Key Value Heads192        self.num_key_value_heads = config.num_key_value_heads193        self.num_q_per_kv = self.num_heads // self.num_key_value_heads194        self.max_position_embeddings = config.max_position_embeddings195        self.rope_embedding_base = config.rope_embedding_base196        self.rope_position_scale = config.rope_position_scale197        self.is_causal = True198 199        self.attention_dropout_rate = config.attention_dropout_prob200 201        norm_factor = None202        if config.mup_use_scaling:203            norm_factor = self.head_dim / config.mup_attn_multiplier204        else:205            norm_factor = math.sqrt(self.head_dim)206        self.softmax_scale = 1.0 / norm_factor207 208        self.query_key_value = nn.Linear(self.hidden_size, (self.num_heads + 2 * self.num_key_value_heads) * self.head_dim)209        self.dense = nn.Linear(self.hidden_size, self.hidden_size)210 211        self.blocksparse_params = None212        # layer_idx is 0 indexed because that's what the KV Cache expects.213        if self.config.dense_attention_every_n_layers and ((self.layer_idx + 1) % self.config.dense_attention_every_n_layers == 0):214            logger.info(215                f"Layer {layer_idx + 1} is using dense attention since it is divisible by "216                f"{self.config.dense_attention_every_n_layers}"217            )218            assert is_flash_attention_available, "Flash Attention is not available, but is needed for dense attention"219        else:220            # BlockSparse related Parameters221            self.blocksparse_params = BlockSparseParams.from_config(config)222 223        if self.blocksparse:224            active_head_range = None225            """226                ... note(bapatra)::227 228                    In case of tensor parallelism and while using the heterogeneous head patterns,229                    the active head range needs to be modified based on the tensor parallel rank230                    and the tensor parallel world size.231 232                    This is because in the case of heterogeneous head patterns, the kernel needs to know233                    which head is on which device, so that it can pick the corresponding blocksparse head234                    pattern correctly.235 236                    Example:237                    ```python238 239                        if not self.blocksparse_params.homo_head_pattern:240                            tp_rank = torch.distributed.get_rank() % tp_world_size241                            num_heads_per_partition = num_heads // tp_world_size242                            active_head_range = (tp_rank * num_heads_per_partition, (tp_rank + 1) * num_heads_per_partition)243 244                    ```245 246            """247            248            self._blocksparse_layer = BlockSparseAttentionLayer(249                n_heads=self.num_heads,250                max_seq_len=self.max_position_embeddings,251                sparse_block_size=self.blocksparse_params.block_size,252                local_blocks=self.blocksparse_params.num_local_blocks,253                vert_stride=self.blocksparse_params.vert_stride,254                kernel_block_size=self.blocksparse_params.kernel_block_size,255                homo_head=self.blocksparse_params.homo_head_pattern,256                active_head_range=active_head_range,257            )258        self.rotary_emb = RotaryEmbedding.from_config(config)259 260 261    @property262    def blocksparse(self):263        return self.blocksparse_params is not None264 265    def _split_heads(self, mixed_x_layer: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:266        bs, sq, _ = mixed_x_layer.size()267        r"""268        The main idea is that we group tensors as269        [bs, sq, (q00, q01, ... q0m, k0, v0), (q10, q11, ... q1m, k1, v1), ... (qn0, qn1, ... qnm, kn, vn)]270        That ways, when the MP column sharding happens, this tensor will be sharded keeping all the271        queries and keys intact. In order to get the correct qkv, we first break into groups, and then272        index into the groups.273        """274 275        intermediate_shape = (bs, sq, -1, (self.num_q_per_kv + 2), self.head_dim)276        mixed_x_layer = mixed_x_layer.view(*intermediate_shape)277        q = mixed_x_layer[:, :, :, :-2]278        k = mixed_x_layer[:, :, :, [-2]]279        v = mixed_x_layer[:, :, :, [-1]]280        q, k, v = [281            rearrange(282                x,283                "bs sq group nh hn -> bs sq (group nh) hn"284            ) for x in (q, k, v)285        ]286        return q, k, v287 288    # Copied from transformers.models.mistral.modeling_mistral.MistralFlashAttention2._unpad_input289    def _upad_input(self, query_layer, key_layer, value_layer, attention_mask, query_length):290        batch_size, kv_seq_len, num_heads, head_dim = key_layer.shape291 292 293        indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)294 295        key_layer = index_first_axis(key_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k)296        value_layer = index_first_axis(value_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k)297 298        if query_length == kv_seq_len:299            query_layer = index_first_axis(300                query_layer.reshape(batch_size * kv_seq_len, num_heads, head_dim), indices_k301            )302            cu_seqlens_q = cu_seqlens_k303            max_seqlen_in_batch_q = max_seqlen_in_batch_k304            indices_q = indices_k305        elif query_length == 1:306            max_seqlen_in_batch_q = 1307            cu_seqlens_q = torch.arange(308                batch_size + 1, dtype=torch.int32, device=query_layer.device309            )  # There is a memcpy here, that is very bad.310            indices_q = cu_seqlens_q[:-1]311            query_layer = query_layer.squeeze(1)312        else:313            # The -q_len: slice assumes left padding.314            attention_mask = attention_mask[:, -query_length:]315            query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(query_layer, attention_mask)316 317        return (318            query_layer,319            key_layer,320            value_layer,321            indices_q,322            (cu_seqlens_q, cu_seqlens_k),323            (max_seqlen_in_batch_q, max_seqlen_in_batch_k),324        )325 326    def _apply_blocksparse_attention(327        self,328        q: torch.Tensor,329        k: torch.Tensor,330        v: torch.Tensor,331        attention_mask: Optional[torch.LongTensor],332        return_attention_probs: bool = False,333    ) -> torch.Tensor:334        """335        Applies blocksparse attention to the input tensors.336 337        Args:338            q (torch.Tensor): The query tensor of shape (bs, nqp, seq_len, hn).339            k (torch.Tensor): The key tensor of shape (bs, nkp, seq_len, hn).340            v (torch.Tensor): The value tensor of shape (bs, nkp, seq_len, hn).341            attention_mask (Optional[torch.LongTensor]): The attention mask tensor of shape (bs, seq_len).342            return_attention_probs (bool, optional): Whether to return attention probabilities. Defaults to False.343 344        Returns:345            torch.Tensor: The context layer tensor of shape (bs, nqp, seq_len, hn).346        """347        assert not return_attention_probs, "return_attention_probs is not supported for blocksparse attention"348        q, k, v = q.contiguous(), k.contiguous(), v.contiguous()349        # shape: (bs, nqp, seq_len, hn)350        if torch.is_grad_enabled():351            # Training or non-batched inference352            context_layer = self._blocksparse_layer(353                q=q, k=k, v=v, sm_scale=self.softmax_scale354            )355        elif attention_mask is None:356            if q.size(0) != 1:357                logger.warning_once(358                    "You are attempting to do batched inference without passing the attention mask.\n"359                    "This is okay if you are running loglikelihood requests. However, if you want to do generation, "360                    "this probably won't work as expected. Please pass the attention mask to the forward function."361                )362            context_layer = self._blocksparse_layer(363                q=q, k=k, v=v, sm_scale=self.softmax_scale364            )365        else:366            """367                Shapes of tensors are as follows:368                    q: (bs, nqp, seq_len, hdim)369                    k: (bs, nkp, seq_len, hdim)370                    v: (bs, nkp, seq_len, hdim)371                We first need to transpose the shapes to fit what the372                kernel needs, and the reinvert it back at the end of the operations373            """374            assert attention_mask.ndim == 2, "The kernel, like flash-attention-2, only supports 2d attention masks ..."375            left_paddings = attention_mask.shape[1] - attention_mask.sum(dim=-1)376            # shape: (bs, seq_len, nqp, hdim)377            q = q.transpose(1, 2).contiguous()378            # shape: (bs, seq_len, nkp, hdim)379            k = k.transpose(1, 2).contiguous()380            # shape: (bs, seq_len, nkp, hdim)381            v = v.transpose(1, 2).contiguous()382            context_layer = self._blocksparse_layer(383                q=q, k=k, v=v, sm_scale=self.softmax_scale, left_paddings=left_paddings.to(torch.int32)384            )385            # shape: (bs, nqp, seq_len, hdim)386            context_layer = context_layer.transpose(1, 2).contiguous()387        return context_layer388 389    def _apply_dense_attention(390        self,391        q: torch.Tensor,392        k: torch.Tensor,393        v: torch.Tensor,394        attention_mask: torch.Tensor,395        return_attention_probs: bool = False,396    ) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:397        """398        Apply dense attention399 400        Args:401            q (torch.Tensor):402                The query tensor, shape: (bs, num_query_heads, seq_len, head_size)403            k (torch.Tensor):404                The key tensor, shape: (bs, num_query_heads, seq_len, head_size)405            v (torch.Tensor):406                The value tensor, shape: (bs, num_query_heads, seq_len, head_size)407 408            return_attention_probs (bool, optional):409                Return the attention probabilities. Defaults to False.410 411        Returns:412            Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:413                Return the output of the attention aggregation. If `return_attention_probs` is True, then414                also return the attention probabilities415 416        .. note::417            Right now, am assuming the expansion for the query key values is already done418            outside. But ideally, since Flash attention handles the GQA correctly, we can419            avoid doing that.420 421        """422        attention_dropout_prob = self.attention_dropout_rate if self.training else 0.0423        # Get into the correct shape for the Flash Attention API424        # shape: (bs, seq_len, nqp, hn)425        q = q.transpose(1, 2).contiguous()426        query_length = q.size(1)427        # shape: (bs, seq_len, npq, hn)428        k = k.transpose(1, 2).contiguous()429        # shape: (bs, seq_len, npq, hn)430        v = v.transpose(1, 2).contiguous()431 432        if attention_mask is not None:433            causal = q.size(2) == k.size(2)434            batch_size = q.shape[0]435            flat_q, flat_k, flat_v, indices_q, cu_seq_lens, max_seq_lens = self._upad_input(436                q, k, v, attention_mask, query_length437            )438            cu_seqlens_q, cu_seqlens_k = cu_seq_lens439            max_seqlen_q, max_seqlen_k = max_seq_lens440            flat_kv = torch.cat((flat_k.unsqueeze(1), flat_v.unsqueeze(1)), dim=1)441            attn_output_unpad = flash_attn_varlen_kvpacked_func(442                q=flat_q,443                kv=flat_kv,444                cu_seqlens_q=cu_seqlens_q,445                cu_seqlens_k=cu_seqlens_k,446                max_seqlen_q=max_seqlen_q,447                max_seqlen_k=max_seqlen_k,448                dropout_p=attention_dropout_prob,449                softmax_scale=self.softmax_scale,450                causal=causal,451                return_attn_probs=return_attention_probs452            )453            attention_output = pad_input(454                attn_output_unpad, indices_q, batch_size, query_length455            )456        else:457            kv = torch.cat((k.unsqueeze(2), v.unsqueeze(2)), dim=2)458            cu_seqlens_q = torch.arange(459                0, (q.size(0) + 1), device=q.device, dtype=torch.int32460            ) * q.size(1)461            cu_seqlens_kv = torch.arange(462                0, (kv.size(0) + 1), device=kv.device, dtype=torch.int32463            ) * kv.size(1)464            max_seqlen_q = q.size(1)465            max_seqlen_k = kv.size(1)466            attention_output = flash_attn_varlen_kvpacked_func(467                q=collapse_first_n_dims(q, 2),468                kv=collapse_first_n_dims(kv, 2),469                cu_seqlens_q=cu_seqlens_q,470                cu_seqlens_k=cu_seqlens_kv,471                max_seqlen_q=max_seqlen_q,472                max_seqlen_k=max_seqlen_k,473                dropout_p=attention_dropout_prob,474                softmax_scale=self.softmax_scale,475                causal=q.size(1) == kv.size(1),476                return_attn_probs=return_attention_probs477            )478        if return_attention_probs:479            (context_layer, attn_probs) = attention_output480            context_layer = context_layer.view(q.size(0), q.size(1), -1, q.size(3)).transpose(1, 2).contiguous()481            return (context_layer, attn_probs)482        context_layer = attention_output483        context_layer = context_layer.view(q.size(0), q.size(1), -1, q.size(3)).transpose(1, 2).contiguous()484        return context_layer485 486    487    def expand_kv_to_q_size(self, kv: torch.Tensor, num_q_per_kv: int) -> torch.Tensor:488        """489        Expand the key-value tensor to match the size of the query tensor.490 491        Args:492            kv (torch.Tensor): The key-value tensor of shape (bsz, nkp, 2, seq_len, hdim).493            num_q_per_kv (int): The number of queries per key-value.494 495        Returns:496            torch.Tensor: The expanded key-value tensor of shape (bsz, nqp, 2, seq_len, hdim).497            Where nqp = num_q_per_kv * nkp498 499        .. note(bapatra)::500            Right now, I am using a repeat_interleave to expand the kv to the size of q.501            This incurs a memory penalty, since the tensors are actually copied.502            TODO: If this does yield benefits, then potentially we can use the re-written503            flash attention kernel that can handle GQA.504        """505 506        repeats = torch.tensor([num_q_per_kv] * kv.size(1)).to(kv.device)507        total = repeats.sum()508        expanded_kv = torch.repeat_interleave(509            kv,510            repeats=repeats,511            dim=1,512            output_size=total513        )514        return expanded_kv515 516    def forward(517        self,518        hidden_states: torch.Tensor,519        attention_mask: Optional[torch.Tensor] = None,520        position_ids: Optional[torch.LongTensor] = None,521        past_key_values: Optional[Cache] = None,522        output_attentions: bool = False,523        use_cache: bool = False,524        **kwargs,525    ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:526        """527        The forward function of the Self Attention Layer.528 529        Args:530            hidden_states (torch.Tensor):531                The input tensor of shape (bs, q_len, h).532            attention_mask (Optional[torch.Tensor], optional):533                The attention mask tensor of shape (bs, seq_len). This is the 2D attention mask tensor as is standard in the flash-attention534                kernel.535                Defaults to None.536            position_ids (Optional[torch.LongTensor], optional):537                The position ids tensor of shape (bs, q_len). Defaults to None. Unused by the function.538            past_key_value (Optional[Cache], optional): 539                The previous kv cache values. Defaults to None.540            output_attentions (bool, optional): 541                Whether to return the attention scores. Defaults to False.542                    .. note::543                        For the blocksparse attention kernel, we do not support returning the attention scores.544            use_cache (bool, optional): 545                Whether to use the cache for storing the kv. Defaults to False.546 547        Returns:548            Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:549                The output tensor of shape (bs, q_len, h), 550                the attention scores tensor of shape (bs, nqp, q_len, seq_len) if `output_attentions` is True, 551                and the updated cache values if `use_cache` is True.552        553        Notations:554        ------------555            bs: batch size556            sq_len: sequence length of the entire sequence557            q_len: sequence length of the query558            cache_sq: sequence length in the cache559                If there is no cache then cache_sq = 0560                and sq_len = q_len561                otherwise sq_len = q_len + cache_sq562            h: hidden size563            nq: number of query heads564            nkv: number of key heads565            hn: hidden size per head566                hn = h // nq567            nqp: number of query heads (per MP partition)568                nqp = nq // (num mp partitions)569            nkvp: number of key-value heads (per MP partition)570                nkvp = nk // (num mp partitions)571 572        """573        # shape: (bs, q_len, h)574        bsz, q_len, _ = hidden_states.size()575 576        # shape: (bs, q_len, (nqp + 2 * nkvp) * hn)577        mixed_x_layer = self.query_key_value(hidden_states)578        # shape: (bs, q_len, nqp, hn), shape: (bs, q_len, nkvp, hn), shape: (bs, q_len, nkvp, hn)579        q, k, v = self._split_heads(mixed_x_layer)580 581        # shape: (bs, qnp, q_len, hn)582        query_states = q.permute(0, 2, 1, 3).contiguous()583        # shape: (bs, nkvp, q_len, hn)584        key_states = k.permute(0, 2, 1, 3).contiguous()585        # shape: (bs, nkvp, q_len, hn)586        value_states = v.permute(0, 2, 1, 3).contiguous()587 588        kv_seq_len = key_states.shape[-2]589        if past_key_values is not None:590            if self.layer_idx is None:591                raise ValueError(592                    f"The cache structure has changed since version v4.36. If you are using {self.__class__.__name__} "593                    "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "594                    "with a layer index."595                )596            if self.rotary_emb is not None:597                seqlen_offset = past_key_values.get_usable_length(kv_seq_len, layer_idx=self.layer_idx)598                # shape: (bs, nqp, q_len, hn), shape: (bs, nkvp, q_len, hn)599                query_states, key_states = self.rotary_emb(600                    query_states, key_states, seq_dimension=2, seqlen_offset=seqlen_offset601                )602                key_states, value_states = past_key_values.update(key_states=key_states, value_states=value_states, layer_idx=self.layer_idx)603        else:604            # In this case seq_len = q_len and cache_sq = 0605            if self.rotary_emb is not None:606                # shape: (bs, nqp, seq_len, hn), shape: (bs, nkvp, seq_len, hn)607                query_states, key_states = self.rotary_emb(query_states, key_states, seq_dimension=2)608 609        # shape: (bs, nkvp, 2, seq_len, hn)610        kv_states = torch.cat((key_states.unsqueeze(2), value_states.unsqueeze(2)), dim=2)611        # shape: (bs, nqp, 2, seq_len, hn)612        expanded_kv_states = self.expand_kv_to_q_size(kv_states, num_q_per_kv=self.num_q_per_kv)613        # shape: (bs, nqp, seq_len, hn), shape: (bs, nqp, seq_len, hn)614        expanded_key_states, expanded_value_states = expanded_kv_states[:, :, 0], expanded_kv_states[:, :, 1]615        if self.blocksparse:616            attn_function_output = self._apply_blocksparse_attention(617                q=query_states,618                k=expanded_key_states,619                v=expanded_value_states,620                attention_mask=attention_mask,621                return_attention_probs=output_attentions622            )623        else:624            attn_function_output = self._apply_dense_attention(625                q=query_states,626                k=expanded_key_states,627                v=expanded_value_states,628                attention_mask=attention_mask,629                return_attention_probs=output_attentions630            )631 632        attn_weights = None633        if output_attentions:634            attn_output, attn_weights = attn_function_output635        else:636            # shape: (bs, nqp, seq_len, hn)637            attn_output = attn_function_output638        # shape: (bs, seq_len, nqp, hn)639        attn_output = attn_output.transpose(1, 2).contiguous()640 641        # shape: (bs, seq_len, h)642        attn_output = attn_output.view(bsz, q_len, -1)643        attn_output = self.dense(attn_output)644        return attn_output, attn_weights, past_key_values645        646 647class Phi3SmallDecoderLayer(nn.Module):648    def __init__(self, config: Phi3SmallConfig, layer_idx: int):649        super().__init__()650        self.hidden_size = config.hidden_size651        self.self_attn = Phi3SmallSelfAttention(config, layer_idx)652        self.mlp = Phi3SmallMLP(config)653 654        self.input_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_epsilon)655        self.post_attention_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_epsilon)656    657    def forward(658        self,659        hidden_states: torch.Tensor,660        attention_mask: Optional[torch.Tensor] = None,661        position_ids: Optional[torch.LongTensor] = None,662        past_key_values: Optional[Cache] = None,663        output_attentions: Optional[bool] = None,664        use_cache: Optional[bool] = None,665        **kwargs,666    ) -> Tuple[torch.FloatTensor, Optional[torch.FloatTensor], Optional[Cache]]:667        residual = hidden_states668        hidden_states = self.input_layernorm(hidden_states)669 670        # Self Attention671        hidden_states, self_attn_weights, present_key_values = self.self_attn(672            hidden_states=hidden_states,673            attention_mask=attention_mask,674            position_ids=position_ids,675            past_key_values=past_key_values,676            output_attentions=output_attentions,677            use_cache=use_cache,678        )679        hidden_states = residual + hidden_states680 681        # Fully Connected682        residual = hidden_states683        hidden_states = self.post_attention_layernorm(hidden_states)684        hidden_states = self.mlp(hidden_states)685        hidden_states = residual + hidden_states686 687        outputs = (hidden_states,)688 689        if output_attentions:690            outputs += (self_attn_weights,)691 692        if use_cache:693            outputs += (present_key_values,)694 695        return outputs696 697 698 699class Phi3SmallPreTrainedModel(PreTrainedModel):700    config_class = Phi3SmallConfig701    base_model_prefix = "model"702    supports_gradient_checkpointing = True703    _no_split_modules = ["Phi3SmallDecoderLayer"]704    skip_keys_device_placement = "past_key_values"705    _supports_flash_attn_2 = True706    _supports_sdpa = False707    _supports_cache_class = True708 709    def _init_weights(self, module: nn.Module):710        std = self.config.initializer_range711        if isinstance(module, nn.Linear):712            # Slightly different from the TF version which uses truncated_normal for initialization713            # cf https://github.com/pytorch/pytorch/pull/5617714            module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)715        elif isinstance(module, nn.Embedding):716            module.weight.data.normal_(mean=0.0, std=self.config.initializer_range)717            if module.padding_idx is not None:718                module.weight.data[module.padding_idx].zero_()719        elif isinstance(module, nn.LayerNorm):720            module.bias.data.zero_()721            module.weight.data.fill_(1.0)722        723        # The output projection on the decoder attention layer as well as the down_proj in the MLP are scaled724        # differently (dubbed `output_layer_init_method` in the Megatron code). This is replicated here725        for name, p in module.named_parameters():726            if any(x in name for x in ("c_proj.weight", "down_proj.weight", "o_proj.weight")):727                # Special Scaled Initialization --> There are 2 Layer Norms per Transformer Block728                p.data.normal_(mean=0.0, std=(self.config.initializer_range / math.sqrt(2 * self.config.num_hidden_layers)))729 730 731class Phi3SmallModel(Phi3SmallPreTrainedModel):732 733    def __init__(self, config):734        super().__init__(config)735        self.config = config736 737        self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)738 739        # Embedding Dropout740        self.embedding_dropout = nn.Dropout(config.embedding_dropout_prob)741        742        # MuP Embedding scaling743        self.mup_embedding_multiplier = config.mup_embedding_multiplier744 745        self.layers = nn.ModuleList([Phi3SmallDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)])746 747        self.final_layernorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_epsilon)748 749        self.gradient_checkpointing = False750 751        # Initialize weights and apply final processing752        self.post_init()753    754    def get_input_embeddings(self):755        return self.embed_tokens756    757    def set_input_embeddings(self, value):758        self.embed_tokens = value759    760    @property761    def pad_sequence_to_multiple_of_64(self):762        # We only need to do this for the backward pass. So only required763        # when we are in the context of generating gradients764        return self.config.pad_sequence_to_multiple_of_64 and torch.is_grad_enabled()765 766    def forward(767        self,768        input_ids: torch.LongTensor = None,769        attention_mask: Optional[torch.Tensor] = None,770        position_ids: Optional[torch.LongTensor] = None,771        past_key_values: Optional[Union[Cache, LegacyCache]] = None,772        inputs_embeds: Optional[torch.FloatTensor] = None,773        use_cache: Optional[bool] = None,774        output_attentions: Optional[bool] = None,775        output_hidden_states: Optional[bool] = None,776        return_dict: Optional[bool] = None,777    ) -> Union[Tuple, BaseModelOutputWithPast]:778        779        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions780        output_hidden_states = (781            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states782        )783        use_cache = use_cache if use_cache is not None else self.config.use_cache784 785        return_dict = return_dict if return_dict is not None else self.config.use_return_dict786 787        if input_ids is not None and inputs_embeds is not None:788            raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")789        elif input_ids is not None:790            batch_size, seq_length = input_ids.shape791        elif inputs_embeds is not None:792            batch_size, seq_length, _ = inputs_embeds.shape793        else:794            raise ValueError("You have to specify either input_ids or inputs_embeds")795 796        if self.gradient_checkpointing and self.training:797            if use_cache:798                logger.warning_once(799                    "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..."800                )801                use_cache = False802        803        past_key_values_length = 0804 805        if use_cache:806            use_legacy_cache = not isinstance(past_key_values, Cache)807            if use_legacy_cache:808                past_key_values = DynamicCache.from_legacy_cache(past_key_values)809            past_key_values_length = past_key_values.get_usable_length(seq_length)810        811        if position_ids is None:812            device = input_ids.device if input_ids is not None else inputs_embeds.device813            position_ids = torch.arange(814                past_key_values_length, past_key_values_length + seq_length, dtype=torch.long, device=device815            )816            position_ids = position_ids.unsqueeze(0).view(-1, seq_length)817        else:818            position_ids = position_ids.view(-1, seq_length).long()819        820        if attention_mask is not None:821            if batch_size <= 0:822                raise ValueError("batch_size has to be defined and > 0")823 824        if inputs_embeds is None:825            inputs_embeds = self.embed_tokens(input_ids)826        inputs_embeds = self.embedding_dropout(inputs_embeds)827 828        if self.mup_embedding_multiplier is not None and self.mup_embedding_multiplier > 0.0:829            inputs_embeds = inputs_embeds * self.mup_embedding_multiplier830        831        residual = 0832        if self.pad_sequence_to_multiple_of_64:833            # note(bapatra): Since we don't particularly use the position_ids and the attention mask834            # we don't need to pad them835            inputs_embeds, residual = pad_tensor_to_next_mult_of(tensor=inputs_embeds, dim=1, n=64)836 837        hidden_states = inputs_embeds838 839        # decoder layers840        all_hidden_states = () if output_hidden_states else None841        all_self_attns = () if output_attentions else None842        next_decoder_cache = None843 844        for decoder_layer in self.layers:845            if output_hidden_states:846                all_hidden_states += (hidden_states,)847            848            if self.gradient_checkpointing and self.training:849                layer_outputs = self._gradient_checkpointing_func(850                    decoder_layer.__call__,851                    hidden_states,852                    attention_mask,853                    position_ids,854                    past_key_values,855                    output_attentions,856                    use_cache,857                )858            else:859                layer_outputs = decoder_layer(860                    hidden_states,861                    attention_mask=attention_mask,862                    position_ids=position_ids,863                    past_key_values=past_key_values,864                    output_attentions=output_attentions,865                    use_cache=use_cache,866                )867            hidden_states = layer_outputs[0]868 869            if use_cache:870                # Following the Mistral schema for layer return values871                next_decoder_cache = layer_outputs[2 if output_attentions else 1]872            if output_attentions:873                all_self_attns += (layer_outputs[1],)874 875        hidden_states = self.final_layernorm(hidden_states)876 877        if residual > 0:878            hidden_states = strip_padding_from_tensor(tensor=hidden_states, dim=1, residual=residual)879 880        # add hidden states from the last decoder layer881        if output_hidden_states:882            all_hidden_states += (hidden_states,)883        884        next_cache = None885        if use_cache:886            next_cache = next_decoder_cache.to_legacy_cache() if use_legacy_cache else next_decoder_cache887        888        if not return_dict:889            return tuple(v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns] if v is not None)890        return BaseModelOutputWithPast(891            last_hidden_state=hidden_states,892            past_key_values=next_cache,893            hidden_states=all_hidden_states,894            attentions=all_self_attns,895        )896 897 898class Phi3SmallForCausalLM(Phi3SmallPreTrainedModel):899    _tied_weights_keys = ["lm_head.weight"]900 901    def __init__(self, config):902        super().__init__(config)903        self.model = Phi3SmallModel(config)904        self.vocab_size = config.vocab_size905        self.lm_head = nn.Linear(config.hidden_size, self.vocab_size, bias=False)906        self.mup_width_multiplier = config.mup_width_multiplier907 908        # Create the mask for the dummy tokens in the vocabulary909        dummy_token_indices = config.dummy_token_indices910        dummy_tokens_mask = torch.zeros(self.vocab_size).bool()911        dummy_tokens_mask[dummy_token_indices] = True912        # shape: (vocab_size,)913        self.register_buffer("dummy_tokens_mask", dummy_tokens_mask, persistent=False)914 915        # Initialize weights and apply final processing916        self.post_init()917    918    def get_input_embeddings(self):919        return self.model.embed_tokens920    921    def set_input_embeddings(self, value):922        self.model.embed_tokens = value923    924    def get_output_embeddings(self):925        return self.lm_head926 927    def set_output_embeddings(self, value):928        self.lm_head = value929    930    def set_decoder(self, decoder):931        self.model = decoder932    933    def get_decoder(self):934        return self.model935 936    def forward(937        self,938        input_ids: torch.LongTensor = None,939        attention_mask: Optional[torch.Tensor] = None,940        position_ids: Optional[torch.LongTensor] = None,941        past_key_values: Optional[List[torch.FloatTensor]] = None,942        inputs_embeds: Optional[torch.FloatTensor] = None,943        labels: Optional[torch.LongTensor] = None,944        use_cache: Optional[bool] = None,945        output_attentions: Optional[bool] = None,946        output_hidden_states: Optional[bool] = None,947        return_dict: Optional[bool] = None,   948    ) -> Union[Tuple, CausalLMOutputWithPast]:949        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions950        output_hidden_states = (951            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states952        )953        return_dict = return_dict if return_dict is not None else self.config.use_return_dict954 955        # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)956        outputs = self.model(957            input_ids=input_ids,958            attention_mask=attention_mask,959            position_ids=position_ids,960            past_key_values=past_key_values,961            inputs_embeds=inputs_embeds,962            use_cache=use_cache,963            output_attentions=output_attentions,964            output_hidden_states=output_hidden_states,965            return_dict=return_dict,966        )967 968        hidden_states = outputs[0]969        logits = self.lm_head(hidden_states)970        logits = logits.float()971        if self.mup_width_multiplier:972            logits = logits / self.mup_width_multiplier973        logits = logits.masked_fill(self.dummy_tokens_mask, min_value_of_dtype(logits.dtype))974 975        loss = None976        if labels is not None:977            # Shift so that tokens < n predict n978            shift_logits = logits[..., :-1, :].contiguous()979            shift_labels = labels[..., 1:].contiguous()980            # Flatten the tokens981            loss_fct = nn.CrossEntropyLoss()982            shift_logits = shift_logits.view(-1, self.config.vocab_size)983            shift_labels = shift_labels.view(-1)984            # Enable model parallelism985            shift_labels = shift_labels.to(shift_logits.device)986            loss = loss_fct(shift_logits, shift_labels)987 988        if not return_dict:989            output = (logits,) + outputs[1:]990            return (loss,) + output if loss is not None else output991 992        return CausalLMOutputWithPast(993            loss=loss,994            logits=logits,995            past_key_values=outputs.past_key_values,996            hidden_states=outputs.hidden_states,997            attentions=outputs.attentions,998        )999    1000    def prepare_inputs_for_generation(1001        self, 1002        input_ids: torch.LongTensor,1003        past_key_values: Optional[List[torch.FloatTensor]] = None,1004        attention_mask: Optional[torch.FloatTensor] = None,1005        inputs_embeds: Optional[torch.FloatTensor] = None,1006        **kwargs1007    ) -> Dict[str, Any]:1008        # only last token for inputs_ids if past is defined in kwargs1009        if past_key_values:1010            input_ids = input_ids[:, -1].unsqueeze(-1)1011 1012        position_ids = kwargs.get("position_ids", None)1013 1014        if attention_mask is not None and position_ids is None:1015            # create position_ids on the fly for batch generation1016            position_ids = attention_mask.long().cumsum(-1) - 11017            position_ids.masked_fill_(attention_mask == 0, 1)1018            if past_key_values:1019                position_ids = position_ids[:, -1].unsqueeze(-1)1020        else:1021            position_ids = None1022 1023        # if `inputs_embeds` are passed, we only want to use them in the 1st generation step1024        if inputs_embeds is not None and past_key_values is None:1025            model_inputs = {"inputs_embeds": inputs_embeds}1026        else:1027            model_inputs = {"input_ids": input_ids}1028 1029        model_inputs.update(1030            {1031                "past_key_values": past_key_values,1032                "use_cache": kwargs.get("use_cache"),1033                "position_ids": position_ids,1034                "attention_mask": attention_mask,1035            }1036        )1037        return model_inputs1038 1039 1040# Copied from transformers.models.mistral.modeling_mistral.MistralForSequenceClassification with Mistral -> Phi3Small1041class Phi3SmallForSequenceClassification(Phi3SmallPreTrainedModel):1042    def __init__(self, config):1043        super().__init__(config)1044        self.num_labels = config.num_labels1045        self.model = Phi3SmallModel(config)1046        self.score = nn.Linear(config.hidden_size, self.num_labels, bias=False)1047 1048        # Initialize weights and apply final processing1049        self.post_init()1050    1051    def get_input_embeddings(self):1052        return self.model.embed_tokens1053    1054    def set_input_embeddings(self, value):1055        self.model.embed_tokens = value1056 1057    1058    def forward(1059        self,1060        input_ids: torch.LongTensor = None,1061        attention_mask: Optional[torch.Tensor] = None,1062        position_ids: Optional[torch.LongTensor] = None,1063        past_key_values: Optional[List[torch.FloatTensor]] = None,1064        inputs_embeds: Optional[torch.FloatTensor] = None,1065        labels: Optional[torch.LongTensor] = None,1066        use_cache: Optional[bool] = None,1067        output_attentions: Optional[bool] = None,1068        output_hidden_states: Optional[bool] = None,1069        return_dict: Optional[bool] = None,1070    ) -> Union[Tuple, SequenceClassifierOutputWithPast]:1071        return_dict = return_dict if return_dict is not None else self.config.use_return_dict1072 1073        transformer_outputs = self.model(1074            input_ids,1075            attention_mask=attention_mask,1076            position_ids=position_ids,1077            past_key_values=past_key_values,1078            inputs_embeds=inputs_embeds,1079            use_cache=use_cache,1080            output_attentions=output_attentions,1081            output_hidden_states=output_hidden_states,1082            return_dict=return_dict,1083        )1084        hidden_states = transformer_outputs[0]1085        logits = self.score(hidden_states)1086 1087        if input_ids is not None:1088            batch_size = input_ids.shape[0]1089        else:1090            batch_size = inputs_embeds.shape[0]1091 1092        if self.config.pad_token_id is None and batch_size != 1:1093            raise ValueError("Cannot handle batch sizes > 1 if no padding token is defined.")1094        if self.config.pad_token_id is None:1095            sequence_lengths = -11096        else:1097            if input_ids is not None:1098                # if no pad token found, use modulo instead of reverse indexing for ONNX compatibility1099                sequence_lengths = torch.eq(input_ids, self.config.pad_token_id).int().argmax(-1) - 11100                sequence_lengths = sequence_lengths % input_ids.shape[-1]1101                sequence_lengths = sequence_lengths.to(logits.device)1102            else:1103                sequence_lengths = -11104 1105        pooled_logits = logits[torch.arange(batch_size, device=logits.device), sequence_lengths]1106 1107        loss = None1108        if labels is not None:1109            labels = labels.to(logits.device)1110            if self.config.problem_type is None:1111                if self.num_labels == 1:1112                    self.config.problem_type = "regression"1113                elif self.num_labels > 1 and (labels.dtype == torch.long or labels.dtype == torch.int):1114                    self.config.problem_type = "single_label_classification"1115                else:1116                    self.config.problem_type = "multi_label_classification"1117 1118            if self.config.problem_type == "regression":1119                loss_fct = nn.MSELoss()1120                if self.num_labels == 1:1121                    loss = loss_fct(pooled_logits.squeeze(), labels.squeeze())1122                else:1123                    loss = loss_fct(pooled_logits, labels)1124            elif self.config.problem_type == "single_label_classification":1125                loss_fct = nn.CrossEntropyLoss()1126                loss = loss_fct(pooled_logits.view(-1, self.num_labels), labels.view(-1))1127            elif self.config.problem_type == "multi_label_classification":1128                loss_fct = nn.BCEWithLogitsLoss()1129                loss = loss_fct(pooled_logits, labels)1130        if not return_dict:1131            output = (pooled_logits,) + transformer_outputs[1:]1132            return ((loss,) + output) if loss is not None else output1133 1134        return SequenceClassifierOutputWithPast(1135            loss=loss,1136            logits=pooled_logits,1137            past_key_values=transformer_outputs.past_key_values,1138            hidden_states=transformer_outputs.hidden_states,1139            attentions=transformer_outputs.attentions,1140        )1141