CoolFace
Modelpublic

duttaprat/HViLM-Patho

sourceHugging Faceapache-2.0updated 27d agoView on Hugging Face
0likes82downloads
bert_layers.py913 linesDownload Raw Back to root
1# Copyright 2022 MosaicML Examples authors2# SPDX-License-Identifier: Apache-2.03 4# Copyright 2018 The Google AI Language Team Authors and The HuggingFace Inc. team.5# Copyright (c) 2018-2021, NVIDIA CORPORATION.  All rights reserved.6# Copyright (c) 2022, Tri Dao.7 8import copy9import logging10import math11import warnings12from typing import List, Optional, Tuple, Union13 14import torch15import torch.nn as nn16from einops import rearrange17from torch.nn.modules.utils import consume_prefix_in_state_dict_if_present18from transformers.activations import ACT2FN19from transformers.modeling_outputs import (MaskedLMOutput,20                                           SequenceClassifierOutput)21from transformers.models.bert.modeling_bert import BertPreTrainedModel22from transformers.modeling_utils import PreTrainedModel23 24from .bert_padding import (index_first_axis,25                                            index_put_first_axis, pad_input,26                                            unpad_input, unpad_input_only)27 28try:29    from .flash_attn_triton import flash_attn_qkvpacked_func30except ImportError as e:31    flash_attn_qkvpacked_func = None32 33logger = logging.getLogger(__name__)34 35 36class BertEmbeddings(nn.Module):37 38    def __init__(self, config):39        super().__init__()40        self.word_embeddings = nn.Embedding(config.vocab_size,41                                            config.hidden_size,42                                            padding_idx=config.pad_token_id)43        # ALiBi doesn't use position embeddings44        self.token_type_embeddings = nn.Embedding(config.type_vocab_size,45                                                  config.hidden_size)46 47        # self.LayerNorm is not snake-cased to stick with TensorFlow model48        # variable name and be able to load any TensorFlow checkpoint file49        self.LayerNorm = nn.LayerNorm(config.hidden_size,50                                      eps=config.layer_norm_eps)51        self.dropout = nn.Dropout(config.hidden_dropout_prob)52        self.register_buffer('token_type_ids',53                             torch.zeros(config.max_position_embeddings,54                                         dtype=torch.long),55                             persistent=False)56 57    def forward(58        self,59        input_ids: Optional[torch.LongTensor] = None,60        token_type_ids: Optional[torch.LongTensor] = None,61        position_ids: Optional[torch.LongTensor] = None,62        inputs_embeds: Optional[torch.FloatTensor] = None,63        past_key_values_length: int = 0,64    ) -> torch.Tensor:65        if (input_ids is not None) == (inputs_embeds is not None):66            raise ValueError('Must specify either input_ids or input_embeds!')67        if input_ids is not None:68            input_shape = input_ids.size()69        else:70            assert inputs_embeds is not None  # just for type checking71            input_shape = inputs_embeds.size()[:-1]72 73        seq_length = input_shape[1]74 75        if position_ids is None:76            # great! ALiBi77            pass78 79        # Setting the token_type_ids to the registered buffer in constructor80        # where it is all zeros, which usually occurs when it's auto-generated;81        # registered buffer helps users when tracing the model without passing82        # token_type_ids, solves issue #566483        if token_type_ids is None:84            if hasattr(self, 'token_type_ids'):85                assert isinstance(self.token_type_ids, torch.LongTensor)86                buffered_token_type_ids = self.token_type_ids[:, :seq_length]87                buffered_token_type_ids_expanded = buffered_token_type_ids.expand(88                    input_shape[0], seq_length)89                token_type_ids = buffered_token_type_ids_expanded  # type: ignore90            else:91                token_type_ids = torch.zeros(input_shape,  # type: ignore92                                             dtype=torch.long,93                                             device=self.word_embeddings.device) # type: ignore  # yapf: disable94 95        if inputs_embeds is None:96            inputs_embeds = self.word_embeddings(input_ids)97        token_type_embeddings = self.token_type_embeddings(token_type_ids)98 99        embeddings = inputs_embeds + token_type_embeddings100        # no position embeddings! ALiBi101        embeddings = self.LayerNorm(embeddings)102        embeddings = self.dropout(embeddings)103        return embeddings104 105 106class BertUnpadSelfAttention(nn.Module):107 108    def __init__(self, config):109        super().__init__()110        if config.hidden_size % config.num_attention_heads != 0 and not hasattr(111                config, 'embedding_size'):112            raise ValueError(113                f'The hidden size ({config.hidden_size}) is not a multiple of the number of attention '114                f'heads ({config.num_attention_heads})')115 116        self.num_attention_heads = config.num_attention_heads117        self.attention_head_size = int(config.hidden_size /118                                       config.num_attention_heads)119        self.all_head_size = self.num_attention_heads * self.attention_head_size120        self.dropout = nn.Dropout(config.attention_probs_dropout_prob)121        self.p_dropout = config.attention_probs_dropout_prob122        self.Wqkv = nn.Linear(self.all_head_size, 3 * config.hidden_size)123 124        # Warn if defaulting to pytorch because of import issues125        if flash_attn_qkvpacked_func is None:126            warnings.warn(127                'Unable to import Triton; defaulting MosaicBERT attention implementation to pytorch (this will reduce throughput when using this model).'128            )129 130    def forward(self, hidden_states: torch.Tensor, cu_seqlens: torch.Tensor,131                max_seqlen_in_batch: int, indices: torch.Tensor,132                attn_mask: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:133        """Perform self-attention.134 135        If dropout is zero, then we can use the Triton kernel, so we do that. However, if not, we send through a standard PyTorch136        implementation of self-attention.137 138        The arguments are unpadded, and our implementations of attention require padded arguments,139        so we first call `pad_input`. Once we compute attention, we re-unpad our outputs for the other layers.140        The pad/unpad operations add overhead, but not sending pad tokens through ffs saves compute.141        It is possible to write an unpadded implementation of attention (in Triton and PyTorch), which we will eventually do.142 143        Args:144            hidden_states: (total_nnz, dim)145            cu_seqlens: (batch + 1,)146            max_seqlen_in_batch: int147            indices: (total_nnz,)148            attn_mask: (batch, max_seqlen_in_batch)149            bias: (batch, heads, max_seqlen_in_batch, max_seqlen_in_batch)150 151        Returns:152            attention: (total_nnz, dim)153        """154        qkv = self.Wqkv(hidden_states)155        qkv = pad_input(qkv, indices, cu_seqlens.shape[0] - 1,156                        max_seqlen_in_batch)  # batch, max_seqlen_in_batch, thd157        qkv = rearrange(qkv,158                        'b s (t h d) -> b s t h d',159                        t=3,160                        h=self.num_attention_heads)161        if self.p_dropout or flash_attn_qkvpacked_func is None:162            # if we have nonzero attention dropout (e.g. during fine-tuning) or no Triton, compute attention in PyTorch163            q = qkv[:, :, 0, :, :].permute(0, 2, 1, 3)  # b h s d164            k = qkv[:, :, 1, :, :].permute(0, 2, 3, 1)  # b h d s165            v = qkv[:, :, 2, :, :].permute(0, 2, 1, 3)  # b h s d166            attention_scores = torch.matmul(q, k) / math.sqrt(167                self.attention_head_size)168            attention_scores = attention_scores + bias169            attention_probs = nn.functional.softmax(attention_scores, dim=-1)170            attention_probs = self.dropout(attention_probs)171            attention = torch.matmul(attention_probs, v).permute(0, 2, 1,172                                                                 3)  # b s h d173        else:174            # Triton implementation only supports 0 attention dropout175            convert_dtype = qkv.dtype not in [torch.float16, torch.bfloat16]176            if convert_dtype:177                # Triton implementation only supports fp16 and bf16178                orig_dtype = qkv.dtype179                qkv = qkv.to(torch.float16)180                bias_dtype = bias.dtype181                bias = bias.to(torch.float16)182                attention = flash_attn_qkvpacked_func(qkv, bias)183                attention = attention.to(orig_dtype)184                bias = bias.to(bias_dtype)185            else:186                attention = flash_attn_qkvpacked_func(qkv, bias)187 188        # attn_mask is 1 for attend and 0 for don't189        attention = unpad_input_only(attention, torch.squeeze(attn_mask) == 1)190        return rearrange(attention, 'nnz h d -> nnz (h d)')191 192 193# Copy of transformer's library BertSelfOutput that will not be caught by surgery methods looking for HF BERT modules.194class BertSelfOutput(nn.Module):195 196    def __init__(self, config):197        super().__init__()198        self.dense = nn.Linear(config.hidden_size, config.hidden_size)199        self.LayerNorm = nn.LayerNorm(config.hidden_size,200                                      eps=config.layer_norm_eps)201        self.dropout = nn.Dropout(config.hidden_dropout_prob)202 203    def forward(self, hidden_states: torch.Tensor,204                input_tensor: torch.Tensor) -> torch.Tensor:205        hidden_states = self.dense(hidden_states)206        hidden_states = self.dropout(hidden_states)207        hidden_states = self.LayerNorm(hidden_states + input_tensor)208        return hidden_states209 210 211class BertUnpadAttention(nn.Module):212    """Chains attention, Dropout, and LayerNorm for Mosaic BERT."""213 214    def __init__(self, config):215        super().__init__()216        self.self = BertUnpadSelfAttention(config)217        self.output = BertSelfOutput(config)218 219    def forward(220        self,221        input_tensor: torch.Tensor,222        cu_seqlens: torch.Tensor,223        max_s: int,224        subset_idx: Optional[torch.Tensor] = None,225        indices: Optional[torch.Tensor] = None,226        attn_mask: Optional[torch.Tensor] = None,227        bias: Optional[torch.Tensor] = None,228    ) -> torch.Tensor:229        """Forward pass for scaled self-attention without padding.230 231        Arguments:232            input_tensor: (total_nnz, dim)233            cu_seqlens: (batch + 1,)234            max_s: int235            subset_idx: () set of indices whose values we care about at the end of the layer236                        (e.g., the masked tokens, if this is the final layer).237            indices: None or (total_nnz,)238            attn_mask: None or (batch, max_seqlen_in_batch)239            bias: None or (batch, heads, max_seqlen_in_batch, max_seqlen_in_batch)240        """241        self_output = self.self(input_tensor, cu_seqlens, max_s, indices,242                                attn_mask, bias)243        if subset_idx is not None:244            return self.output(index_first_axis(self_output, subset_idx),245                               index_first_axis(input_tensor, subset_idx))246        else:247            return self.output(self_output, input_tensor)248 249 250class BertGatedLinearUnitMLP(nn.Module):251    """Applies the FFN at the end of each Mosaic BERT layer.252 253    Compared to the default BERT architecture, this block replaces :class:`~transformers.model.bert.modeling_bert.BertIntermediate`254    and :class:`~transformers.model.bert.modeling_bert.SelfOutput` with a single module that has similar functionality, but255    introduces Gated Linear Units.256 257    Note: Mosaic BERT adds parameters in order to implement Gated Linear Units. To keep parameter count consistent with that of a258    standard Hugging Face BERT, scale down `config.intermediate_size` by 2/3. For example, a Mosaic BERT constructed with259    `config.intermediate_size=2048` will have the same parameter footprint as its Hugging Face BERT counterpart constructed260    with the `config.intermediate_size=3072`.261    However, in most cases it will not be necessary to adjust `config.intermediate_size` since, despite the increased262    parameter size, Mosaic BERT typically offers a net higher throughput than a Hugging Face BERT built from the same `config`.263    """264 265    def __init__(self, config):266        super().__init__()267        self.config = config268        self.gated_layers = nn.Linear(config.hidden_size,269                                      config.intermediate_size * 2,270                                      bias=False)271        self.act = nn.GELU(approximate='none')272        self.wo = nn.Linear(config.intermediate_size, config.hidden_size)273        self.dropout = nn.Dropout(config.hidden_dropout_prob)274        self.layernorm = nn.LayerNorm(config.hidden_size,275                                      eps=config.layer_norm_eps)276 277    def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:278        """Compute new hidden states from current hidden states.279 280        Args:281            hidden_states (torch.Tensor): The (unpadded) hidden states from282                the attention layer [nnz, dim].283        """284        residual_connection = hidden_states285        # compute the activation286        hidden_states = self.gated_layers(hidden_states)287        gated = hidden_states[:, :self.config.intermediate_size]288        non_gated = hidden_states[:, self.config.intermediate_size:]289        hidden_states = self.act(gated) * non_gated290        hidden_states = self.dropout(hidden_states)291        # multiply by the second matrix292        hidden_states = self.wo(hidden_states)293        # add the residual connection and post-LN294        hidden_states = self.layernorm(hidden_states + residual_connection)295        return hidden_states296 297 298class BertLayer(nn.Module):299    """Composes the Mosaic BERT attention and FFN blocks into a single layer."""300 301    def __init__(self, config):302        super(BertLayer, self).__init__()303        self.attention = BertUnpadAttention(config)304        self.mlp = BertGatedLinearUnitMLP(config)305 306    def forward(307        self,308        hidden_states: torch.Tensor,309        cu_seqlens: torch.Tensor,310        seqlen: int,311        subset_idx: Optional[torch.Tensor] = None,312        indices: Optional[torch.Tensor] = None,313        attn_mask: Optional[torch.Tensor] = None,314        bias: Optional[torch.Tensor] = None,315    ) -> torch.Tensor:316        """Forward pass for a BERT layer, including both attention and MLP.317 318        Args:319            hidden_states: (total_nnz, dim)320            cu_seqlens: (batch + 1,)321            seqlen: int322            subset_idx: () set of indices whose values we care about at the end of the layer323                        (e.g., the masked tokens, if this is the final layer).324            indices: None or (total_nnz,)325            attn_mask: None or (batch, max_seqlen_in_batch)326            bias: None or (batch, heads, max_seqlen_in_batch, max_seqlen_in_batch)327        """328        attention_output = self.attention(hidden_states, cu_seqlens, seqlen,329                                          subset_idx, indices, attn_mask, bias)330        layer_output = self.mlp(attention_output)331        return layer_output332 333 334class BertEncoder(nn.Module):335    """A stack of BERT layers providing the backbone of Mosaic BERT.336 337    This module is modeled after the Hugging Face BERT's :class:`~transformers.model.bert.modeling_bert.BertEncoder`,338    but with substantial modifications to implement unpadding and ALiBi.339 340    Compared to the analogous Hugging Face BERT module, this module handles unpadding to reduce unnecessary computation341    at padded tokens, and pre-computes attention biases to implement ALiBi.342    """343 344    def __init__(self, config):345        super().__init__()346        layer = BertLayer(config)347        self.layer = nn.ModuleList(348            [copy.deepcopy(layer) for _ in range(config.num_hidden_layers)])349 350        self.num_attention_heads = config.num_attention_heads351 352        # The alibi mask will be dynamically expanded if it is too small for353        # the input the model receives. But it generally helps to initialize it354        # to a reasonably large size to help pre-allocate CUDA memory.355        # The default `alibi_starting_size` is 512.356        self._current_alibi_size = int(config.alibi_starting_size)357        self.alibi = torch.zeros(358            (1, self.num_attention_heads, self._current_alibi_size,359             self._current_alibi_size))360        self.rebuild_alibi_tensor(size=config.alibi_starting_size)361 362    def rebuild_alibi_tensor(self,363                             size: int,364                             device: Optional[Union[torch.device, str]] = None):365        # Alibi366        # Following https://github.com/ofirpress/attention_with_linear_biases/issues/5 (Implementation 1)367        # In the causal case, you can exploit the fact that softmax is invariant to a uniform translation368        # of the logits, which makes the math work out *after* applying causal masking. If no causal masking369        # will be applied, it is necessary to construct the diagonal mask.370        n_heads = self.num_attention_heads371 372        def _get_alibi_head_slopes(n_heads: int) -> List[float]:373 374            def get_slopes_power_of_2(n_heads: int) -> List[float]:375                start = (2**(-2**-(math.log2(n_heads) - 3)))376                ratio = start377                return [start * ratio**i for i in range(n_heads)]378 379            # In the paper, they only train models that have 2^a heads for some a. This function380            # has some good properties that only occur when the input is a power of 2. To381            # maintain that even when the number of heads is not a power of 2, we use a382            # workaround.383            if math.log2(n_heads).is_integer():384                return get_slopes_power_of_2(n_heads)385 386            closest_power_of_2 = 2**math.floor(math.log2(n_heads))387            slopes_a = get_slopes_power_of_2(closest_power_of_2)388            slopes_b = _get_alibi_head_slopes(2 * closest_power_of_2)389            slopes_b = slopes_b[0::2][:n_heads - closest_power_of_2]390            return slopes_a + slopes_b391 392        context_position = torch.arange(size, device=device)[:, None]393        memory_position = torch.arange(size, device=device)[None, :]394        relative_position = torch.abs(memory_position - context_position)395        # [n_heads, max_token_length, max_token_length]396        relative_position = relative_position.unsqueeze(0).expand(397            n_heads, -1, -1)398        slopes = torch.Tensor(_get_alibi_head_slopes(n_heads)).to(device)399        alibi = slopes.unsqueeze(1).unsqueeze(1) * -relative_position400        # [1, n_heads, max_token_length, max_token_length]401        alibi = alibi.unsqueeze(0)402        assert alibi.shape == torch.Size([1, n_heads, size, size])403 404        self._current_alibi_size = size405        self.alibi = alibi406 407    def forward(408        self,409        hidden_states: torch.Tensor,410        attention_mask: torch.Tensor,411        output_all_encoded_layers: Optional[bool] = True,412        subset_mask: Optional[torch.Tensor] = None,413    ) -> List[torch.Tensor]:414 415        extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)416        extended_attention_mask = extended_attention_mask.to(417            dtype=torch.float32)  # fp16 compatibility418        extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0419 420        attention_mask_bool = attention_mask.bool()421        batch, seqlen = hidden_states.shape[:2]422        # Unpad inputs and mask. It will remove tokens that are padded.423        # Assume ntokens is total number of tokens (padded and non-padded)424        # and ntokens_unpad is total number of non-padded tokens.425        # Then unpadding performs the following compression of the inputs:426        # hidden_states[ntokens,hidden] -> hidden_states[ntokens_unpad,hidden]427        hidden_states, indices, cu_seqlens, _ = unpad_input(428            hidden_states, attention_mask_bool)429 430        # Add alibi matrix to extended_attention_mask431        if self._current_alibi_size < seqlen:432            # Rebuild the alibi tensor when needed433            warnings.warn(434                f'Increasing alibi size from {self._current_alibi_size} to {seqlen}'435            )436            self.rebuild_alibi_tensor(size=seqlen, device=hidden_states.device)437        elif self.alibi.device != hidden_states.device:438            # Device catch-up439            self.alibi = self.alibi.to(hidden_states.device)440        alibi_bias = self.alibi[:, :, :seqlen, :seqlen]441        attn_bias = extended_attention_mask[:, :, :seqlen, :seqlen]442        alibi_attn_mask = attn_bias + alibi_bias443 444        all_encoder_layers = []445        if subset_mask is None:446            for layer_module in self.layer:447                hidden_states = layer_module(hidden_states,448                                             cu_seqlens,449                                             seqlen,450                                             None,451                                             indices,452                                             attn_mask=attention_mask,453                                             bias=alibi_attn_mask)454                if output_all_encoded_layers:455                    all_encoder_layers.append(hidden_states)456            # Pad inputs and mask. It will insert back zero-padded tokens.457            # Assume ntokens is total number of tokens (padded and non-padded)458            # and ntokens_unpad is total number of non-padded tokens.459            # Then padding performs the following de-compression:460            #     hidden_states[ntokens_unpad,hidden] -> hidden_states[ntokens,hidden]461            hidden_states = pad_input(hidden_states, indices, batch, seqlen)462        else:463            for i in range(len(self.layer) - 1):464                layer_module = self.layer[i]465                hidden_states = layer_module(hidden_states,466                                             cu_seqlens,467                                             seqlen,468                                             None,469                                             indices,470                                             attn_mask=attention_mask,471                                             bias=alibi_attn_mask)472                if output_all_encoded_layers:473                    all_encoder_layers.append(hidden_states)474            subset_idx = torch.nonzero(subset_mask[attention_mask_bool],475                                       as_tuple=False).flatten()476            hidden_states = self.layer[-1](hidden_states,477                                           cu_seqlens,478                                           seqlen,479                                           subset_idx=subset_idx,480                                           indices=indices,481                                           attn_mask=attention_mask,482                                           bias=alibi_attn_mask)483 484        if not output_all_encoded_layers:485            all_encoder_layers.append(hidden_states)486        return all_encoder_layers487 488 489class BertPooler(nn.Module):490 491    def __init__(self, config):492        super(BertPooler, self).__init__()493        self.dense = nn.Linear(config.hidden_size, config.hidden_size)494        self.activation = nn.Tanh()495 496    def forward(self,497                hidden_states: torch.Tensor,498                pool: Optional[bool] = True) -> torch.Tensor:499        # We "pool" the model by simply taking the hidden state corresponding500        # to the first token.501        first_token_tensor = hidden_states[:, 0] if pool else hidden_states502        pooled_output = self.dense(first_token_tensor)503        pooled_output = self.activation(pooled_output)504        return pooled_output505 506 507class BertPredictionHeadTransform(nn.Module):508 509    def __init__(self, config):510        super().__init__()511        self.dense = nn.Linear(config.hidden_size, config.hidden_size)512        if isinstance(config.hidden_act, str):513            self.transform_act_fn = ACT2FN[config.hidden_act]514        else:515            self.transform_act_fn = config.hidden_act516        self.LayerNorm = torch.nn.LayerNorm(config.hidden_size, eps=1e-12)517 518    def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:519        hidden_states = self.dense(hidden_states)520        hidden_states = self.transform_act_fn(hidden_states)521        hidden_states = self.LayerNorm(hidden_states)522        return hidden_states523 524 525class BertModel(BertPreTrainedModel):526    """Overall BERT model.527 528    Args:529        config: a BertConfig class instance with the configuration to build a new model530 531    Inputs:532        `input_ids`: a torch.LongTensor of shape [batch_size, sequence_length]533            with the word token indices in the vocabulary(see the tokens preprocessing logic in the scripts534            `extract_features.py`, `run_classifier.py` and `run_squad.py`)535        `token_type_ids`: an optional torch.LongTensor of shape [batch_size, sequence_length] with the token536            types indices selected in [0, 1]. Type 0 corresponds to a `sentence A` and type 1 corresponds to537            a `sentence B` token (see BERT paper for more details).538        `attention_mask`: an optional torch.LongTensor of shape [batch_size, sequence_length] with indices539            selected in [0, 1]. It's a mask to be used if the input sequence length is smaller than the max540            input sequence length in the current batch. It's the mask that we typically use for attention when541            a batch has varying length sentences.542        `output_all_encoded_layers`: boolean which controls the content of the `encoded_layers` output as described below. Default: `True`.543 544    Outputs: Tuple of (encoded_layers, pooled_output)545        `encoded_layers`: controlled by `output_all_encoded_layers` argument:546            - `output_all_encoded_layers=True`: outputs a list of the full sequences of encoded-hidden-states at the end547                of each attention block (i.e. 12 full sequences for BERT-base, 24 for BERT-large), each548                encoded-hidden-state is a torch.FloatTensor of size [batch_size, sequence_length, hidden_size],549            - `output_all_encoded_layers=False`: outputs only the full sequence of hidden-states corresponding550                to the last attention block of shape [batch_size, sequence_length, hidden_size],551        `pooled_output`: a torch.FloatTensor of size [batch_size, hidden_size] which is the output of a552            classifier pretrained on top of the hidden state associated to the first character of the553            input (`CLS`) to train on the Next-Sentence task (see BERT's paper).554 555    Example usage:556    ```python557    # Already been converted into WordPiece token ids558    input_ids = torch.LongTensor([[31, 51, 99], [15, 5, 0]])559    input_mask = torch.LongTensor([[1, 1, 1], [1, 1, 0]])560    token_type_ids = torch.LongTensor([[0, 0, 1], [0, 1, 0]])561    config = modeling.BertConfig(vocab_size_or_config_json_file=32000, hidden_size=768,562        num_hidden_layers=12, num_attention_heads=12, intermediate_size=3072)563    model = BertModel(config=config)564    all_encoder_layers, pooled_output = model(input_ids, token_type_ids, input_mask)565    ```566    """567 568    def __init__(self, config, add_pooling_layer=True):569        super(BertModel, self).__init__(config)570        self.embeddings = BertEmbeddings(config)571        self.encoder = BertEncoder(config)572        self.pooler = BertPooler(config) if add_pooling_layer else None573        self.post_init()574 575    def get_input_embeddings(self):576        return self.embeddings.word_embeddings577 578    def set_input_embeddings(self, value):579        self.embeddings.word_embeddings = value580 581    def forward(582        self,583        input_ids: torch.Tensor,584        token_type_ids: Optional[torch.Tensor] = None,585        attention_mask: Optional[torch.Tensor] = None,586        position_ids: Optional[torch.Tensor] = None,587        output_all_encoded_layers: Optional[bool] = False,588        masked_tokens_mask: Optional[torch.Tensor] = None,589        **kwargs590    ) -> Tuple[Union[List[torch.Tensor], torch.Tensor], Optional[torch.Tensor]]:591        if attention_mask is None:592            attention_mask = torch.ones_like(input_ids)593        if token_type_ids is None:594            token_type_ids = torch.zeros_like(input_ids)595 596        embedding_output = self.embeddings(input_ids, token_type_ids,597                                           position_ids)598 599        subset_mask = []600        first_col_mask = []601 602        if masked_tokens_mask is None:603            subset_mask = None604        else:605            first_col_mask = torch.zeros_like(masked_tokens_mask)606            first_col_mask[:, 0] = True607            subset_mask = masked_tokens_mask | first_col_mask608 609        encoder_outputs = self.encoder(610            embedding_output,611            attention_mask,612            output_all_encoded_layers=output_all_encoded_layers,613            subset_mask=subset_mask)614 615        if masked_tokens_mask is None:616            sequence_output = encoder_outputs[-1]617            pooled_output = self.pooler(618                sequence_output) if self.pooler is not None else None619        else:620            # TD [2022-03-01]: the indexing here is very tricky.621            attention_mask_bool = attention_mask.bool()622            subset_idx = subset_mask[attention_mask_bool]  # type: ignore623            sequence_output = encoder_outputs[-1][624                masked_tokens_mask[attention_mask_bool][subset_idx]]625            if self.pooler is not None:626                pool_input = encoder_outputs[-1][627                    first_col_mask[attention_mask_bool][subset_idx]]628                pooled_output = self.pooler(pool_input, pool=False)629            else:630                pooled_output = None631 632        if not output_all_encoded_layers:633            encoder_outputs = sequence_output634 635        if self.pooler is not None:636            return encoder_outputs, pooled_output637 638        return encoder_outputs, None639 640 641###################642# Bert Heads643###################644class BertLMPredictionHead(nn.Module):645 646    def __init__(self, config, bert_model_embedding_weights):647        super().__init__()648        self.transform = BertPredictionHeadTransform(config)649        # The output weights are the same as the input embeddings, but there is650        # an output-only bias for each token.651        self.decoder = nn.Linear(bert_model_embedding_weights.size(1),652                                 bert_model_embedding_weights.size(0))653        self.decoder.weight = bert_model_embedding_weights654 655    def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:656        hidden_states = self.transform(hidden_states)657        hidden_states = self.decoder(hidden_states)658        return hidden_states659 660 661class BertOnlyMLMHead(nn.Module):662 663    def __init__(self, config, bert_model_embedding_weights):664        super().__init__()665        self.predictions = BertLMPredictionHead(config,666                                                bert_model_embedding_weights)667 668    def forward(self, sequence_output: torch.Tensor) -> torch.Tensor:669        prediction_scores = self.predictions(sequence_output)670        return prediction_scores671 672 673class BertOnlyNSPHead(nn.Module):674 675    def __init__(self, config):676        super().__init__()677        self.seq_relationship = nn.Linear(config.hidden_size, 2)678 679    def forward(self, pooled_output: torch.Tensor) -> torch.Tensor:680        seq_relationship_score = self.seq_relationship(pooled_output)681        return seq_relationship_score682 683 684 685class BertForMaskedLM(BertPreTrainedModel):686 687    def __init__(self, config):688        super().__init__(config)689 690        if config.is_decoder:691            warnings.warn(692                'If you want to use `BertForMaskedLM` make sure `config.is_decoder=False` for '693                'bi-directional self-attention.')694 695        self.bert = BertModel(config, add_pooling_layer=False)696        self.cls = BertOnlyMLMHead(config,697                                   self.bert.embeddings.word_embeddings.weight)698 699        # Initialize weights and apply final processing700        self.post_init()701 702    def get_output_embeddings(self):703        return self.cls.predictions.decoder704 705    def set_output_embeddings(self, new_embeddings):706        self.cls.predictions.decoder = new_embeddings707 708    def forward(709        self,710        input_ids: Optional[torch.Tensor] = None,711        attention_mask: Optional[torch.Tensor] = None,712        token_type_ids: Optional[torch.Tensor] = None,713        position_ids: Optional[torch.Tensor] = None,714        head_mask: Optional[torch.Tensor] = None,715        inputs_embeds: Optional[torch.Tensor] = None,716        encoder_hidden_states: Optional[torch.Tensor] = None,717        encoder_attention_mask: Optional[torch.Tensor] = None,718        labels: Optional[torch.Tensor] = None,719        output_attentions: Optional[bool] = None,720        output_hidden_states: Optional[bool] = None,721        return_dict: Optional[bool] = None,722    ) -> Union[Tuple[torch.Tensor], MaskedLMOutput]:723        # labels should be a `torch.LongTensor` of shape724        # `(batch_size, sequence_length)`. These are used for computing the725        #  masked language modeling loss.726        #727        # Indices should be in `[-100, 0, ..., config.vocab_size]` (see728        # `input_ids` docstring) Tokens with indices set to `-100` are ignored729        # (masked), the loss is only computed for the tokens with labels in `[0,730        # ..., config.vocab_size]`731        #732        # Prediction scores are only computed for masked tokens and the (bs,733        # seqlen) dimensions are flattened734        if (input_ids is not None) == (inputs_embeds is not None):735            raise ValueError('Must specify either input_ids or input_embeds!')736 737        if labels is None:738            masked_tokens_mask = None739        else:740            masked_tokens_mask = labels > 0741 742        return_dict = return_dict if return_dict is not None else self.config.use_return_dict743 744        outputs = self.bert(745            input_ids,746            attention_mask=attention_mask,747            token_type_ids=token_type_ids,748            position_ids=position_ids,749            head_mask=head_mask,750            inputs_embeds=inputs_embeds,751            encoder_hidden_states=encoder_hidden_states,752            encoder_attention_mask=encoder_attention_mask,753            output_attentions=output_attentions,754            output_hidden_states=output_hidden_states,755            return_dict=return_dict,756            masked_tokens_mask=masked_tokens_mask,757        )758        759        sequence_output = outputs[0]760        prediction_scores = self.cls(sequence_output)761 762        loss = None763        if labels is not None:764            # Compute loss765            loss_fct = nn.CrossEntropyLoss()766            masked_token_idx = torch.nonzero(labels.flatten() > 0,767                                             as_tuple=False).flatten()768            loss = loss_fct(prediction_scores,769                            labels.flatten()[masked_token_idx])770 771            assert input_ids is not None, 'Coding error; please open an issue'772            batch, seqlen = input_ids.shape[:2]773            prediction_scores = rearrange(index_put_first_axis(774                prediction_scores, masked_token_idx, batch * seqlen),775                                          '(b s) d -> b s d',776                                          b=batch)777 778        if not return_dict:779            output = (prediction_scores,) + outputs[2:]780            return ((loss,) + output) if loss is not None else output781 782        return MaskedLMOutput(783            loss=loss,784            logits=prediction_scores,785            hidden_states=outputs[0],786            attentions=None,787        )788 789    def prepare_inputs_for_generation(self, input_ids: torch.Tensor,790                                      attention_mask: torch.Tensor,791                                      **model_kwargs):792        input_shape = input_ids.shape793        effective_batch_size = input_shape[0]794 795        #  add a dummy token796        if self.config.pad_token_id is None:797            raise ValueError('The PAD token should be defined for generation')798 799        attention_mask = torch.cat([800            attention_mask,801            attention_mask.new_zeros((attention_mask.shape[0], 1))802        ],803                                   dim=-1)804        dummy_token = torch.full((effective_batch_size, 1),805                                 self.config.pad_token_id,806                                 dtype=torch.long,807                                 device=input_ids.device)808        input_ids = torch.cat([input_ids, dummy_token], dim=1)809 810        return {'input_ids': input_ids, 'attention_mask': attention_mask}811 812 813 814class BertForSequenceClassification(BertPreTrainedModel):815    """Bert Model transformer with a sequence classification/regression head.816 817    This head is just a linear layer on top of the pooled output. Used for,818    e.g., GLUE tasks.819    """820 821    def __init__(self, config):822        super().__init__(config)823        self.num_labels = config.num_labels824        self.config = config825 826        self.bert = BertModel(config)827        classifier_dropout = (config.classifier_dropout828                              if config.classifier_dropout is not None else829                              config.hidden_dropout_prob)830        self.dropout = nn.Dropout(classifier_dropout)831        self.classifier = nn.Linear(config.hidden_size, config.num_labels)832 833        # Initialize weights and apply final processing834        self.post_init()835 836 837    def forward(838        self,839        input_ids: Optional[torch.Tensor] = None,840        attention_mask: Optional[torch.Tensor] = None,841        token_type_ids: Optional[torch.Tensor] = None,842        position_ids: Optional[torch.Tensor] = None,843        head_mask: Optional[torch.Tensor] = None,844        inputs_embeds: Optional[torch.Tensor] = None,845        labels: Optional[torch.Tensor] = None,846        output_attentions: Optional[bool] = None,847        output_hidden_states: Optional[bool] = None,848        return_dict: Optional[bool] = None,849    ) -> Union[Tuple[torch.Tensor], SequenceClassifierOutput]:850        # labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):851        # Labels for computing the sequence classification/regression loss.852        # Indices should be in `[0, ..., config.num_labels - 1]`.853        # If `config.num_labels == 1` a regression loss is computed854        # (mean-square loss). If `config.num_labels > 1` a classification loss855        # is computed (cross-entropy).856 857        return_dict = return_dict if return_dict is not None else self.config.use_return_dict858 859        outputs = self.bert(860            input_ids,861            attention_mask=attention_mask,862            token_type_ids=token_type_ids,863            position_ids=position_ids,864            head_mask=head_mask,865            inputs_embeds=inputs_embeds,866            output_attentions=output_attentions,867            output_hidden_states=output_hidden_states,868            return_dict=return_dict,869        )870 871        pooled_output = outputs[1]872 873        pooled_output = self.dropout(pooled_output)874        logits = self.classifier(pooled_output)875 876        loss = None877        if labels is not None:878            # Compute loss879            if self.config.problem_type is None:880                if self.num_labels == 1:881                    self.config.problem_type = 'regression'882                elif self.num_labels > 1 and (labels.dtype == torch.long or883                                              labels.dtype == torch.int):884                    self.config.problem_type = 'single_label_classification'885                else:886                    self.config.problem_type = 'multi_label_classification'887 888            if self.config.problem_type == 'regression':889                loss_fct = nn.MSELoss()890                if self.num_labels == 1:891                    loss = loss_fct(logits.squeeze(), labels.squeeze())892                else:893                    loss = loss_fct(logits, labels)894            elif self.config.problem_type == 'single_label_classification':895                loss_fct = nn.CrossEntropyLoss()896                loss = loss_fct(logits.view(-1, self.num_labels),897                                labels.view(-1))898            elif self.config.problem_type == 'multi_label_classification':899                loss_fct = nn.BCEWithLogitsLoss()900                loss = loss_fct(logits, labels)901 902        if not return_dict:903            output = (logits,) + outputs[2:]904            return ((loss,) + output) if loss is not None else output905 906        return SequenceClassifierOutput(907            loss=loss,908            logits=logits,909            hidden_states=outputs[0],910            attentions=None,911        )912 913