Aluode/PerceptionLabPortable
0
1# coding=utf-82# Copyright 2023-present NAVER Corp, The Microsoft Research Asia LayoutLM Team Authors and the HuggingFace Inc. team.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15"""PyTorch Bros model."""16 17import math18from dataclasses import dataclass19from typing import Optional, Union20 21import torch22from torch import nn23from torch.nn import CrossEntropyLoss24 25from ...activations import ACT2FN26from ...modeling_layers import GradientCheckpointingLayer27from ...modeling_outputs import (28 BaseModelOutputWithCrossAttentions,29 BaseModelOutputWithPoolingAndCrossAttentions,30 TokenClassifierOutput,31)32from ...modeling_utils import PreTrainedModel33from ...pytorch_utils import apply_chunking_to_forward, find_pruneable_heads_and_indices, prune_linear_layer34from ...utils import ModelOutput, auto_docstring, can_return_tuple, logging35from .configuration_bros import BrosConfig36 37 38logger = logging.get_logger(__name__)39 40 41@dataclass42@auto_docstring(43 custom_intro="""44 Base class for outputs of token classification models.45 """46)47class BrosSpadeOutput(ModelOutput):48 r"""49 loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):50 Classification loss.51 initial_token_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.num_labels)`):52 Classification scores for entity initial tokens (before SoftMax).53 subsequent_token_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, sequence_length+1)`):54 Classification scores for entity sequence tokens (before SoftMax).55 """56 57 loss: Optional[torch.FloatTensor] = None58 initial_token_logits: Optional[torch.FloatTensor] = None59 subsequent_token_logits: Optional[torch.FloatTensor] = None60 hidden_states: Optional[tuple[torch.FloatTensor]] = None61 attentions: Optional[tuple[torch.FloatTensor]] = None62 63 64class BrosPositionalEmbedding1D(nn.Module):65 # Reference: https://github.com/kimiyoung/transformer-xl/blob/master/pytorch/mem_transformer.py#L1566 67 def __init__(self, config):68 super().__init__()69 70 self.dim_bbox_sinusoid_emb_1d = config.dim_bbox_sinusoid_emb_1d71 72 inv_freq = 1 / (73 10000 ** (torch.arange(0.0, self.dim_bbox_sinusoid_emb_1d, 2.0) / self.dim_bbox_sinusoid_emb_1d)74 )75 self.register_buffer("inv_freq", inv_freq)76 77 def forward(self, pos_seq: torch.Tensor) -> torch.Tensor:78 seq_size = pos_seq.size()79 b1, b2, b3 = seq_size80 sinusoid_inp = pos_seq.view(b1, b2, b3, 1) * self.inv_freq.view(1, 1, 1, self.dim_bbox_sinusoid_emb_1d // 2)81 pos_emb = torch.cat([sinusoid_inp.sin(), sinusoid_inp.cos()], dim=-1)82 return pos_emb83 84 85class BrosPositionalEmbedding2D(nn.Module):86 def __init__(self, config):87 super().__init__()88 89 self.dim_bbox = config.dim_bbox90 self.x_pos_emb = BrosPositionalEmbedding1D(config)91 self.y_pos_emb = BrosPositionalEmbedding1D(config)92 93 def forward(self, bbox: torch.Tensor) -> torch.Tensor:94 stack = []95 for i in range(self.dim_bbox):96 if i % 2 == 0:97 stack.append(self.x_pos_emb(bbox[..., i]))98 else:99 stack.append(self.y_pos_emb(bbox[..., i]))100 bbox_pos_emb = torch.cat(stack, dim=-1)101 return bbox_pos_emb102 103 104class BrosBboxEmbeddings(nn.Module):105 def __init__(self, config):106 super().__init__()107 self.bbox_sinusoid_emb = BrosPositionalEmbedding2D(config)108 self.bbox_projection = nn.Linear(config.dim_bbox_sinusoid_emb_2d, config.dim_bbox_projection, bias=False)109 110 def forward(self, bbox: torch.Tensor):111 bbox_t = bbox.transpose(0, 1)112 bbox_pos = bbox_t[None, :, :, :] - bbox_t[:, None, :, :]113 bbox_pos_emb = self.bbox_sinusoid_emb(bbox_pos)114 bbox_pos_emb = self.bbox_projection(bbox_pos_emb)115 116 return bbox_pos_emb117 118 119class BrosTextEmbeddings(nn.Module):120 """Construct the embeddings from word, position and token_type embeddings."""121 122 def __init__(self, config):123 super().__init__()124 125 self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, padding_idx=config.pad_token_id)126 self.position_embeddings = nn.Embedding(config.max_position_embeddings, config.hidden_size)127 self.token_type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)128 129 # self.LayerNorm is not snake-cased to stick with TensorFlow model variable name and be able to load130 # any TensorFlow checkpoint file131 self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)132 self.dropout = nn.Dropout(config.hidden_dropout_prob)133 # position_ids (1, len position emb) is contiguous in memory and exported when serialized134 self.position_embedding_type = getattr(config, "position_embedding_type", "absolute")135 self.register_buffer("position_ids", torch.arange(config.max_position_embeddings).expand((1, -1)))136 self.register_buffer(137 "token_type_ids",138 torch.zeros(139 self.position_ids.size(),140 dtype=torch.long,141 device=self.position_ids.device,142 ),143 persistent=False,144 )145 146 def forward(147 self,148 input_ids: Optional[torch.Tensor] = None,149 token_type_ids: Optional[torch.Tensor] = None,150 position_ids: Optional[torch.Tensor] = None,151 inputs_embeds: Optional[torch.Tensor] = None,152 ) -> torch.Tensor:153 if input_ids is not None:154 input_shape = input_ids.size()155 else:156 input_shape = inputs_embeds.size()[:-1]157 158 seq_length = input_shape[1]159 160 if position_ids is None:161 position_ids = self.position_ids[:, :seq_length]162 163 if token_type_ids is None:164 if hasattr(self, "token_type_ids"):165 buffered_token_type_ids = self.token_type_ids[:, :seq_length]166 buffered_token_type_ids_expanded = buffered_token_type_ids.expand(input_shape[0], seq_length)167 token_type_ids = buffered_token_type_ids_expanded168 else:169 token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=self.position_ids.device)170 171 if inputs_embeds is None:172 inputs_embeds = self.word_embeddings(input_ids)173 token_type_embeddings = self.token_type_embeddings(token_type_ids)174 175 embeddings = inputs_embeds + token_type_embeddings176 if self.position_embedding_type == "absolute":177 position_embeddings = self.position_embeddings(position_ids)178 embeddings += position_embeddings179 embeddings = self.LayerNorm(embeddings)180 embeddings = self.dropout(embeddings)181 return embeddings182 183 184class BrosSelfAttention(nn.Module):185 def __init__(self, config):186 super().__init__()187 if config.hidden_size % config.num_attention_heads != 0 and not hasattr(config, "embedding_size"):188 raise ValueError(189 f"The hidden size ({config.hidden_size}) is not a multiple of the number of attention "190 f"heads ({config.num_attention_heads})"191 )192 193 self.num_attention_heads = config.num_attention_heads194 self.attention_head_size = int(config.hidden_size / config.num_attention_heads)195 self.all_head_size = self.num_attention_heads * self.attention_head_size196 197 self.query = nn.Linear(config.hidden_size, self.all_head_size)198 self.key = nn.Linear(config.hidden_size, self.all_head_size)199 self.value = nn.Linear(config.hidden_size, self.all_head_size)200 201 self.dropout = nn.Dropout(config.attention_probs_dropout_prob)202 self.position_embedding_type = getattr(config, "position_embedding_type", "absolute")203 if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query":204 self.max_position_embeddings = config.max_position_embeddings205 self.distance_embedding = nn.Embedding(2 * config.max_position_embeddings - 1, self.attention_head_size)206 207 self.is_decoder = config.is_decoder208 209 def forward(210 self,211 hidden_states: torch.Tensor,212 bbox_pos_emb: torch.Tensor,213 attention_mask: Optional[torch.Tensor] = None,214 head_mask: Optional[torch.Tensor] = None,215 encoder_hidden_states: Optional[torch.Tensor] = None,216 encoder_attention_mask: Optional[torch.Tensor] = None,217 output_attentions: Optional[torch.Tensor] = False,218 ) -> tuple[torch.Tensor]:219 hidden_shape = (hidden_states.shape[0], -1, self.num_attention_heads, self.attention_head_size)220 query_layer = self.query(hidden_states).view(hidden_shape).transpose(1, 2)221 222 # If this is instantiated as a cross-attention module, the keys223 # and values come from an encoder; the attention mask needs to be224 # such that the encoder's padding tokens are not attended to.225 is_cross_attention = encoder_hidden_states is not None226 227 if is_cross_attention:228 key_layer = self.key(encoder_hidden_states).view(hidden_shape).transpose(1, 2)229 value_layer = self.value(encoder_hidden_states).view(hidden_shape).transpose(1, 2)230 attention_mask = encoder_attention_mask231 else:232 key_layer = self.key(hidden_states).view(hidden_shape).transpose(1, 2)233 value_layer = self.value(hidden_states).view(hidden_shape).transpose(1, 2)234 235 # Take the dot product between "query" and "key" to get the raw attention scores.236 attention_scores = torch.matmul(query_layer, key_layer.transpose(-1, -2))237 238 if self.position_embedding_type == "relative_key" or self.position_embedding_type == "relative_key_query":239 seq_length = hidden_states.size()[1]240 position_ids_l = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(-1, 1)241 position_ids_r = torch.arange(seq_length, dtype=torch.long, device=hidden_states.device).view(1, -1)242 distance = position_ids_l - position_ids_r243 positional_embedding = self.distance_embedding(distance + self.max_position_embeddings - 1)244 positional_embedding = positional_embedding.to(dtype=query_layer.dtype) # fp16 compatibility245 246 if self.position_embedding_type == "relative_key":247 relative_position_scores = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding)248 attention_scores = attention_scores + relative_position_scores249 elif self.position_embedding_type == "relative_key_query":250 relative_position_scores_query = torch.einsum("bhld,lrd->bhlr", query_layer, positional_embedding)251 relative_position_scores_key = torch.einsum("bhrd,lrd->bhlr", key_layer, positional_embedding)252 253 attention_scores = attention_scores + relative_position_scores_query + relative_position_scores_key254 255 # bbox positional encoding256 batch_size, n_head, seq_length, d_head = query_layer.shape257 bbox_pos_emb = bbox_pos_emb.view(seq_length, seq_length, batch_size, d_head)258 bbox_pos_emb = bbox_pos_emb.permute([2, 0, 1, 3])259 bbox_pos_scores = torch.einsum("bnid,bijd->bnij", (query_layer, bbox_pos_emb))260 261 attention_scores = attention_scores + bbox_pos_scores262 263 attention_scores = attention_scores / math.sqrt(self.attention_head_size)264 if attention_mask is not None:265 # Apply the attention mask is (precomputed for all layers in BrosModel forward() function)266 attention_scores = attention_scores + attention_mask267 268 # Normalize the attention scores to probabilities.269 attention_probs = nn.Softmax(dim=-1)(attention_scores)270 271 # This is actually dropping out entire tokens to attend to, which might272 # seem a bit unusual, but is taken from the original Transformer paper.273 attention_probs = self.dropout(attention_probs)274 275 # Mask heads if we want to276 if head_mask is not None:277 attention_probs = attention_probs * head_mask278 279 context_layer = torch.matmul(attention_probs, value_layer)280 281 context_layer = context_layer.permute(0, 2, 1, 3).contiguous()282 new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size,)283 context_layer = context_layer.view(*new_context_layer_shape)284 285 outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)286 287 if self.is_decoder:288 outputs = outputs + (None,)289 return outputs290 291 292# Copied from transformers.models.bert.modeling_bert.BertSelfOutput with Bert->Bros293class BrosSelfOutput(nn.Module):294 def __init__(self, config):295 super().__init__()296 self.dense = nn.Linear(config.hidden_size, config.hidden_size)297 self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)298 self.dropout = nn.Dropout(config.hidden_dropout_prob)299 300 def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:301 hidden_states = self.dense(hidden_states)302 hidden_states = self.dropout(hidden_states)303 hidden_states = self.LayerNorm(hidden_states + input_tensor)304 return hidden_states305 306 307class BrosAttention(nn.Module):308 def __init__(self, config):309 super().__init__()310 self.self = BrosSelfAttention(config)311 self.output = BrosSelfOutput(config)312 self.pruned_heads = set()313 314 def prune_heads(self, heads):315 if len(heads) == 0:316 return317 heads, index = find_pruneable_heads_and_indices(318 heads,319 self.self.num_attention_heads,320 self.self.attention_head_size,321 self.pruned_heads,322 )323 324 # Prune linear layers325 self.self.query = prune_linear_layer(self.self.query, index)326 self.self.key = prune_linear_layer(self.self.key, index)327 self.self.value = prune_linear_layer(self.self.value, index)328 self.output.dense = prune_linear_layer(self.output.dense, index, dim=1)329 330 # Update hyper params and store pruned heads331 self.self.num_attention_heads = self.self.num_attention_heads - len(heads)332 self.self.all_head_size = self.self.attention_head_size * self.self.num_attention_heads333 self.pruned_heads = self.pruned_heads.union(heads)334 335 def forward(336 self,337 hidden_states: torch.Tensor,338 bbox_pos_emb: torch.Tensor,339 attention_mask: Optional[torch.Tensor] = None,340 head_mask: Optional[torch.Tensor] = None,341 encoder_hidden_states: Optional[torch.Tensor] = None,342 encoder_attention_mask: Optional[torch.Tensor] = None,343 output_attentions: Optional[bool] = False,344 ) -> tuple[torch.Tensor]:345 self_outputs = self.self(346 hidden_states=hidden_states,347 bbox_pos_emb=bbox_pos_emb,348 attention_mask=attention_mask,349 head_mask=head_mask,350 encoder_hidden_states=encoder_hidden_states,351 encoder_attention_mask=encoder_attention_mask,352 output_attentions=output_attentions,353 )354 attention_output = self.output(self_outputs[0], hidden_states)355 outputs = (attention_output,) + self_outputs[1:] # add attentions if we output them356 return outputs357 358 359# Copied from transformers.models.bert.modeling_bert.BertIntermediate with Bert->Bros360class BrosIntermediate(nn.Module):361 def __init__(self, config):362 super().__init__()363 self.dense = nn.Linear(config.hidden_size, config.intermediate_size)364 if isinstance(config.hidden_act, str):365 self.intermediate_act_fn = ACT2FN[config.hidden_act]366 else:367 self.intermediate_act_fn = config.hidden_act368 369 def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:370 hidden_states = self.dense(hidden_states)371 hidden_states = self.intermediate_act_fn(hidden_states)372 return hidden_states373 374 375class BrosOutput(nn.Module):376 def __init__(self, config):377 super().__init__()378 self.dense = nn.Linear(config.intermediate_size, config.hidden_size)379 self.LayerNorm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)380 self.dropout = nn.Dropout(config.hidden_dropout_prob)381 382 def forward(self, hidden_states: torch.Tensor, input_tensor: torch.Tensor) -> torch.Tensor:383 hidden_states = self.dense(hidden_states)384 hidden_states = self.dropout(hidden_states)385 hidden_states = self.LayerNorm(hidden_states + input_tensor)386 return hidden_states387 388 389class BrosLayer(GradientCheckpointingLayer):390 def __init__(self, config):391 super().__init__()392 self.chunk_size_feed_forward = config.chunk_size_feed_forward393 self.seq_len_dim = 1394 self.attention = BrosAttention(config)395 self.is_decoder = config.is_decoder396 self.add_cross_attention = config.add_cross_attention397 if self.add_cross_attention:398 if not self.is_decoder:399 raise Exception(f"{self} should be used as a decoder model if cross attention is added")400 self.crossattention = BrosAttention(config)401 self.intermediate = BrosIntermediate(config)402 self.output = BrosOutput(config)403 404 def forward(405 self,406 hidden_states: torch.Tensor,407 bbox_pos_emb: torch.Tensor,408 attention_mask: Optional[torch.FloatTensor] = None,409 head_mask: Optional[torch.FloatTensor] = None,410 encoder_hidden_states: Optional[torch.FloatTensor] = None,411 encoder_attention_mask: Optional[torch.FloatTensor] = None,412 output_attentions: Optional[bool] = False,413 ) -> tuple[torch.Tensor]:414 self_attention_outputs = self.attention(415 hidden_states,416 bbox_pos_emb=bbox_pos_emb,417 attention_mask=attention_mask,418 head_mask=head_mask,419 output_attentions=output_attentions,420 )421 attention_output = self_attention_outputs[0]422 423 # if decoder, the last output is tuple of self-attn cache424 if self.is_decoder:425 outputs = self_attention_outputs[1:-1]426 else:427 outputs = self_attention_outputs[1:] # add self attentions if we output attention weights428 429 if self.is_decoder and encoder_hidden_states is not None:430 if hasattr(self, "crossattention"):431 raise Exception(432 f"If `encoder_hidden_states` are passed, {self} has to be instantiated with cross-attention layers by setting `config.add_cross_attention=True`"433 )434 435 cross_attention_outputs = self.crossattention(436 attention_output,437 attention_mask=attention_mask,438 head_mask=head_mask,439 encoder_hidden_states=encoder_hidden_states,440 encoder_attention_mask=encoder_attention_mask,441 output_attentions=output_attentions,442 )443 attention_output = cross_attention_outputs[0]444 outputs = outputs + cross_attention_outputs[1:-1] # add cross attentions if we output attention weights445 446 layer_output = apply_chunking_to_forward(447 self.feed_forward_chunk,448 self.chunk_size_feed_forward,449 self.seq_len_dim,450 attention_output,451 )452 outputs = (layer_output,) + outputs453 454 # if decoder, return the attn key/values as the last output455 if self.is_decoder:456 outputs = outputs + (None,)457 458 return outputs459 460 def feed_forward_chunk(self, attention_output):461 intermediate_output = self.intermediate(attention_output)462 layer_output = self.output(intermediate_output, attention_output)463 return layer_output464 465 466class BrosEncoder(nn.Module):467 def __init__(self, config):468 super().__init__()469 self.config = config470 self.layer = nn.ModuleList([BrosLayer(config) for _ in range(config.num_hidden_layers)])471 472 @can_return_tuple473 def forward(474 self,475 hidden_states: torch.Tensor,476 bbox_pos_emb: torch.Tensor,477 attention_mask: Optional[torch.FloatTensor] = None,478 head_mask: Optional[torch.FloatTensor] = None,479 encoder_hidden_states: Optional[torch.FloatTensor] = None,480 encoder_attention_mask: Optional[torch.FloatTensor] = None,481 output_attentions: Optional[bool] = False,482 output_hidden_states: Optional[bool] = False,483 return_dict: Optional[bool] = True,484 ) -> Union[tuple[torch.Tensor], BaseModelOutputWithCrossAttentions]:485 all_hidden_states = () if output_hidden_states else None486 all_self_attentions = () if output_attentions else None487 all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None488 489 for i, layer_module in enumerate(self.layer):490 if output_hidden_states:491 all_hidden_states = all_hidden_states + (hidden_states,)492 493 layer_head_mask = head_mask[i] if head_mask is not None else None494 495 layer_outputs = layer_module(496 hidden_states=hidden_states,497 bbox_pos_emb=bbox_pos_emb,498 attention_mask=attention_mask,499 head_mask=layer_head_mask,500 encoder_hidden_states=encoder_hidden_states,501 encoder_attention_mask=encoder_attention_mask,502 output_attentions=output_attentions,503 )504 505 hidden_states = layer_outputs[0]506 if output_attentions:507 all_self_attentions = all_self_attentions + (layer_outputs[1],)508 if self.config.add_cross_attention:509 all_cross_attentions = all_cross_attentions + (layer_outputs[2],)510 511 if output_hidden_states:512 all_hidden_states = all_hidden_states + (hidden_states,)513 514 return BaseModelOutputWithCrossAttentions(515 last_hidden_state=hidden_states,516 hidden_states=all_hidden_states,517 attentions=all_self_attentions,518 cross_attentions=all_cross_attentions,519 )520 521 522# Copied from transformers.models.bert.modeling_bert.BertPooler with Bert->Bros523class BrosPooler(nn.Module):524 def __init__(self, config):525 super().__init__()526 self.dense = nn.Linear(config.hidden_size, config.hidden_size)527 self.activation = nn.Tanh()528 529 def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:530 # We "pool" the model by simply taking the hidden state corresponding531 # to the first token.532 first_token_tensor = hidden_states[:, 0]533 pooled_output = self.dense(first_token_tensor)534 pooled_output = self.activation(pooled_output)535 return pooled_output536 537 538class BrosRelationExtractor(nn.Module):539 def __init__(self, config):540 super().__init__()541 self.n_relations = config.n_relations542 self.backbone_hidden_size = config.hidden_size543 self.head_hidden_size = config.hidden_size544 self.classifier_dropout_prob = config.classifier_dropout_prob545 546 self.drop = nn.Dropout(self.classifier_dropout_prob)547 self.query = nn.Linear(self.backbone_hidden_size, self.n_relations * self.head_hidden_size)548 549 self.key = nn.Linear(self.backbone_hidden_size, self.n_relations * self.head_hidden_size)550 551 self.dummy_node = nn.Parameter(torch.zeros(1, self.backbone_hidden_size))552 553 def forward(self, query_layer: torch.Tensor, key_layer: torch.Tensor):554 query_layer = self.query(self.drop(query_layer))555 556 dummy_vec = self.dummy_node.unsqueeze(0).repeat(1, key_layer.size(1), 1)557 key_layer = torch.cat([key_layer, dummy_vec], axis=0)558 key_layer = self.key(self.drop(key_layer))559 560 query_layer = query_layer.view(561 query_layer.size(0), query_layer.size(1), self.n_relations, self.head_hidden_size562 )563 key_layer = key_layer.view(key_layer.size(0), key_layer.size(1), self.n_relations, self.head_hidden_size)564 565 relation_score = torch.matmul(566 query_layer.permute(2, 1, 0, 3), key_layer.permute(2, 1, 3, 0)567 ) # equivalent to torch.einsum("ibnd,jbnd->nbij", (query_layer, key_layer))568 569 return relation_score570 571 572@auto_docstring573class BrosPreTrainedModel(PreTrainedModel):574 config: BrosConfig575 base_model_prefix = "bros"576 577 def _init_weights(self, module: nn.Module):578 """Initialize the weights"""579 std = self.config.initializer_range580 if isinstance(module, nn.Linear):581 # Slightly different from the TF version which uses truncated_normal for initialization582 # cf https://github.com/pytorch/pytorch/pull/5617583 module.weight.data.normal_(mean=0.0, std=std)584 if module.bias is not None:585 module.bias.data.zero_()586 elif isinstance(module, nn.Embedding):587 module.weight.data.normal_(mean=0.0, std=std)588 if module.padding_idx is not None:589 module.weight.data[module.padding_idx].zero_()590 elif isinstance(module, nn.LayerNorm):591 module.bias.data.zero_()592 module.weight.data.fill_(1.0)593 elif isinstance(module, BrosRelationExtractor):594 nn.init.normal_(module.dummy_node, std=std)595 596 597@auto_docstring598class BrosModel(BrosPreTrainedModel):599 def __init__(self, config, add_pooling_layer=True):600 r"""601 add_pooling_layer (bool, *optional*, defaults to `True`):602 Whether to add a pooling layer603 """604 super().__init__(config)605 self.config = config606 607 self.embeddings = BrosTextEmbeddings(config)608 self.bbox_embeddings = BrosBboxEmbeddings(config)609 self.encoder = BrosEncoder(config)610 611 self.pooler = BrosPooler(config) if add_pooling_layer else None612 613 self.init_weights()614 615 def get_input_embeddings(self):616 return self.embeddings.word_embeddings617 618 def set_input_embeddings(self, value):619 self.embeddings.word_embeddings = value620 621 def _prune_heads(self, heads_to_prune):622 """623 Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base624 class PreTrainedModel625 """626 for layer, heads in heads_to_prune.items():627 self.encoder.layer[layer].attention.prune_heads(heads)628 629 @can_return_tuple630 @auto_docstring631 def forward(632 self,633 input_ids: Optional[torch.Tensor] = None,634 bbox: Optional[torch.Tensor] = None,635 attention_mask: Optional[torch.Tensor] = None,636 token_type_ids: Optional[torch.Tensor] = None,637 position_ids: Optional[torch.Tensor] = None,638 head_mask: Optional[torch.Tensor] = None,639 inputs_embeds: Optional[torch.Tensor] = None,640 encoder_hidden_states: Optional[torch.Tensor] = None,641 encoder_attention_mask: Optional[torch.Tensor] = None,642 output_attentions: Optional[bool] = None,643 output_hidden_states: Optional[bool] = None,644 return_dict: Optional[bool] = None,645 ) -> Union[tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]:646 r"""647 bbox ('torch.FloatTensor' of shape '(batch_size, num_boxes, 4)'):648 Bounding box coordinates for each token in the input sequence. Each bounding box is a list of four values649 (x1, y1, x2, y2), where (x1, y1) is the top left corner, and (x2, y2) is the bottom right corner of the650 bounding box.651 652 Examples:653 654 ```python655 >>> import torch656 >>> from transformers import BrosProcessor, BrosModel657 658 >>> processor = BrosProcessor.from_pretrained("jinho8345/bros-base-uncased")659 660 >>> model = BrosModel.from_pretrained("jinho8345/bros-base-uncased")661 662 >>> encoding = processor("Hello, my dog is cute", add_special_tokens=False, return_tensors="pt")663 >>> bbox = torch.tensor([[[0, 0, 1, 1]]]).repeat(1, encoding["input_ids"].shape[-1], 1)664 >>> encoding["bbox"] = bbox665 666 >>> outputs = model(**encoding)667 >>> last_hidden_states = outputs.last_hidden_state668 ```"""669 output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions670 output_hidden_states = (671 output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states672 )673 return_dict = return_dict if return_dict is not None else self.config.use_return_dict674 675 if input_ids is not None and inputs_embeds is not None:676 raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")677 elif input_ids is not None:678 input_shape = input_ids.size()679 elif inputs_embeds is not None:680 input_shape = inputs_embeds.size()[:-1]681 else:682 raise ValueError("You have to specify either input_ids or inputs_embeds")683 684 if bbox is None:685 raise ValueError("You have to specify bbox")686 687 batch_size, seq_length = input_shape688 device = input_ids.device if input_ids is not None else inputs_embeds.device689 690 if attention_mask is None:691 attention_mask = torch.ones(input_shape, device=device)692 693 if token_type_ids is None:694 if hasattr(self.embeddings, "token_type_ids"):695 buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length]696 buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length)697 token_type_ids = buffered_token_type_ids_expanded698 else:699 token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device)700 701 # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length]702 # ourselves in which case we just need to make it broadcastable to all heads.703 extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape, device)704 705 # If a 2D or 3D attention mask is provided for the cross-attention706 # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length]707 if self.config.is_decoder and encoder_hidden_states is not None:708 encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size()709 encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length)710 if encoder_attention_mask is None:711 encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device)712 encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask)713 else:714 encoder_extended_attention_mask = None715 716 # Prepare head mask if needed717 # 1.0 in head_mask indicate we keep the head718 # attention_probs has shape bsz x n_heads x N x N719 # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads]720 # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length]721 head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers)722 723 embedding_output = self.embeddings(724 input_ids=input_ids,725 position_ids=position_ids,726 token_type_ids=token_type_ids,727 inputs_embeds=inputs_embeds,728 )729 730 # if bbox has 2 points (4 float tensors) per token, convert it to 4 points (8 float tensors) per token731 if bbox.shape[-1] == 4:732 bbox = bbox[:, :, [0, 1, 2, 1, 2, 3, 0, 3]]733 scaled_bbox = bbox * self.config.bbox_scale734 bbox_position_embeddings = self.bbox_embeddings(scaled_bbox)735 736 encoder_outputs = self.encoder(737 embedding_output,738 bbox_pos_emb=bbox_position_embeddings,739 attention_mask=extended_attention_mask,740 head_mask=head_mask,741 encoder_hidden_states=encoder_hidden_states,742 encoder_attention_mask=encoder_extended_attention_mask,743 output_attentions=output_attentions,744 output_hidden_states=output_hidden_states,745 return_dict=True,746 )747 sequence_output = encoder_outputs[0]748 pooled_output = self.pooler(sequence_output) if self.pooler is not None else None749 750 return BaseModelOutputWithPoolingAndCrossAttentions(751 last_hidden_state=sequence_output,752 pooler_output=pooled_output,753 hidden_states=encoder_outputs.hidden_states,754 attentions=encoder_outputs.attentions,755 cross_attentions=encoder_outputs.cross_attentions,756 )757 758 759@auto_docstring760class BrosForTokenClassification(BrosPreTrainedModel):761 _keys_to_ignore_on_load_unexpected = [r"pooler"]762 763 def __init__(self, config):764 super().__init__(config)765 self.num_labels = config.num_labels766 767 self.bros = BrosModel(config)768 classifier_dropout = (769 config.classifier_dropout if hasattr(config, "classifier_dropout") else config.hidden_dropout_prob770 )771 self.dropout = nn.Dropout(classifier_dropout)772 self.classifier = nn.Linear(config.hidden_size, config.num_labels)773 774 self.init_weights()775 776 @can_return_tuple777 @auto_docstring778 def forward(779 self,780 input_ids: Optional[torch.Tensor] = None,781 bbox: Optional[torch.Tensor] = None,782 attention_mask: Optional[torch.Tensor] = None,783 bbox_first_token_mask: Optional[torch.Tensor] = None,784 token_type_ids: Optional[torch.Tensor] = None,785 position_ids: Optional[torch.Tensor] = None,786 head_mask: Optional[torch.Tensor] = None,787 inputs_embeds: Optional[torch.Tensor] = None,788 labels: Optional[torch.Tensor] = None,789 output_attentions: Optional[bool] = None,790 output_hidden_states: Optional[bool] = None,791 return_dict: Optional[bool] = None,792 ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]:793 r"""794 bbox ('torch.FloatTensor' of shape '(batch_size, num_boxes, 4)'):795 Bounding box coordinates for each token in the input sequence. Each bounding box is a list of four values796 (x1, y1, x2, y2), where (x1, y1) is the top left corner, and (x2, y2) is the bottom right corner of the797 bounding box.798 bbox_first_token_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*):799 Mask to indicate the first token of each bounding box. Mask values selected in `[0, 1]`:800 801 - 1 for tokens that are **not masked**,802 - 0 for tokens that are **masked**.803 804 Examples:805 806 ```python807 >>> import torch808 >>> from transformers import BrosProcessor, BrosForTokenClassification809 810 >>> processor = BrosProcessor.from_pretrained("jinho8345/bros-base-uncased")811 812 >>> model = BrosForTokenClassification.from_pretrained("jinho8345/bros-base-uncased")813 814 >>> encoding = processor("Hello, my dog is cute", add_special_tokens=False, return_tensors="pt")815 >>> bbox = torch.tensor([[[0, 0, 1, 1]]]).repeat(1, encoding["input_ids"].shape[-1], 1)816 >>> encoding["bbox"] = bbox817 818 >>> outputs = model(**encoding)819 ```"""820 821 return_dict = return_dict if return_dict is not None else self.config.use_return_dict822 823 outputs = self.bros(824 input_ids,825 bbox=bbox,826 attention_mask=attention_mask,827 token_type_ids=token_type_ids,828 position_ids=position_ids,829 head_mask=head_mask,830 inputs_embeds=inputs_embeds,831 output_attentions=output_attentions,832 output_hidden_states=output_hidden_states,833 return_dict=True,834 )835 836 sequence_output = outputs[0]837 838 sequence_output = self.dropout(sequence_output)839 logits = self.classifier(sequence_output)840 841 loss = None842 if labels is not None:843 loss_fct = CrossEntropyLoss()844 if bbox_first_token_mask is not None:845 bbox_first_token_mask = bbox_first_token_mask.view(-1)846 loss = loss_fct(847 logits.view(-1, self.num_labels)[bbox_first_token_mask], labels.view(-1)[bbox_first_token_mask]848 )849 else:850 loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))851 852 return TokenClassifierOutput(853 loss=loss,854 logits=logits,855 hidden_states=outputs.hidden_states,856 attentions=outputs.attentions,857 )858 859 860@auto_docstring(861 custom_intro="""862 Bros Model with a token classification head on top (initial_token_layers and subsequent_token_layer on top of the863 hidden-states output) e.g. for Named-Entity-Recognition (NER) tasks. The initial_token_classifier is used to864 predict the first token of each entity, and the subsequent_token_classifier is used to predict the subsequent865 tokens within an entity. Compared to BrosForTokenClassification, this model is more robust to serialization errors866 since it predicts next token from one token.867 """868)869class BrosSpadeEEForTokenClassification(BrosPreTrainedModel):870 _keys_to_ignore_on_load_unexpected = [r"pooler"]871 872 def __init__(self, config):873 super().__init__(config)874 self.config = config875 self.num_labels = config.num_labels876 self.n_relations = config.n_relations877 self.backbone_hidden_size = config.hidden_size878 879 self.bros = BrosModel(config)880 classifier_dropout = (881 config.classifier_dropout if hasattr(config, "classifier_dropout") else config.hidden_dropout_prob882 )883 884 # Initial token classification for Entity Extraction (NER)885 self.initial_token_classifier = nn.Sequential(886 nn.Dropout(classifier_dropout),887 nn.Linear(config.hidden_size, config.hidden_size),888 nn.Dropout(classifier_dropout),889 nn.Linear(config.hidden_size, config.num_labels),890 )891 892 # Subsequent token classification for Entity Extraction (NER)893 self.subsequent_token_classifier = BrosRelationExtractor(config)894 895 self.init_weights()896 897 @can_return_tuple898 @auto_docstring899 def forward(900 self,901 input_ids: Optional[torch.Tensor] = None,902 bbox: Optional[torch.Tensor] = None,903 attention_mask: Optional[torch.Tensor] = None,904 bbox_first_token_mask: Optional[torch.Tensor] = None,905 token_type_ids: Optional[torch.Tensor] = None,906 position_ids: Optional[torch.Tensor] = None,907 head_mask: Optional[torch.Tensor] = None,908 inputs_embeds: Optional[torch.Tensor] = None,909 initial_token_labels: Optional[torch.Tensor] = None,910 subsequent_token_labels: Optional[torch.Tensor] = None,911 output_attentions: Optional[bool] = None,912 output_hidden_states: Optional[bool] = None,913 return_dict: Optional[bool] = None,914 ) -> Union[tuple[torch.Tensor], BrosSpadeOutput]:915 r"""916 bbox ('torch.FloatTensor' of shape '(batch_size, num_boxes, 4)'):917 Bounding box coordinates for each token in the input sequence. Each bounding box is a list of four values918 (x1, y1, x2, y2), where (x1, y1) is the top left corner, and (x2, y2) is the bottom right corner of the919 bounding box.920 bbox_first_token_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*):921 Mask to indicate the first token of each bounding box. Mask values selected in `[0, 1]`:922 923 - 1 for tokens that are **not masked**,924 - 0 for tokens that are **masked**.925 initial_token_labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):926 Labels for the initial token classification.927 subsequent_token_labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):928 Labels for the subsequent token classification.929 930 Examples:931 932 ```python933 >>> import torch934 >>> from transformers import BrosProcessor, BrosSpadeEEForTokenClassification935 936 >>> processor = BrosProcessor.from_pretrained("jinho8345/bros-base-uncased")937 938 >>> model = BrosSpadeEEForTokenClassification.from_pretrained("jinho8345/bros-base-uncased")939 940 >>> encoding = processor("Hello, my dog is cute", add_special_tokens=False, return_tensors="pt")941 >>> bbox = torch.tensor([[[0, 0, 1, 1]]]).repeat(1, encoding["input_ids"].shape[-1], 1)942 >>> encoding["bbox"] = bbox943 944 >>> outputs = model(**encoding)945 ```"""946 947 return_dict = return_dict if return_dict is not None else self.config.use_return_dict948 949 outputs = self.bros(950 input_ids=input_ids,951 bbox=bbox,952 attention_mask=attention_mask,953 token_type_ids=token_type_ids,954 position_ids=position_ids,955 head_mask=head_mask,956 inputs_embeds=inputs_embeds,957 output_attentions=output_attentions,958 output_hidden_states=output_hidden_states,959 return_dict=True,960 )961 962 last_hidden_states = outputs[0]963 last_hidden_states = last_hidden_states.transpose(0, 1).contiguous()964 initial_token_logits = self.initial_token_classifier(last_hidden_states).transpose(0, 1).contiguous()965 subsequent_token_logits = self.subsequent_token_classifier(last_hidden_states, last_hidden_states).squeeze(0)966 967 # make subsequent token (sequence token classification) mask968 inv_attention_mask = 1 - attention_mask969 batch_size, max_seq_length = inv_attention_mask.shape970 device = inv_attention_mask.device971 invalid_token_mask = torch.cat([inv_attention_mask, torch.zeros([batch_size, 1]).to(device)], axis=1).bool()972 subsequent_token_logits = subsequent_token_logits.masked_fill(973 invalid_token_mask[:, None, :], torch.finfo(subsequent_token_logits.dtype).min974 )975 self_token_mask = torch.eye(max_seq_length, max_seq_length + 1).to(device=device, dtype=torch.bool)976 subsequent_token_logits = subsequent_token_logits.masked_fill(977 self_token_mask[None, :, :], torch.finfo(subsequent_token_logits.dtype).min978 )979 subsequent_token_mask = attention_mask.view(-1).bool()980 981 loss = None982 if initial_token_labels is not None and subsequent_token_labels is not None:983 loss_fct = CrossEntropyLoss()984 985 # get initial token loss986 initial_token_labels = initial_token_labels.view(-1)987 if bbox_first_token_mask is not None:988 bbox_first_token_mask = bbox_first_token_mask.view(-1)989 initial_token_loss = loss_fct(990 initial_token_logits.view(-1, self.num_labels)[bbox_first_token_mask],991 initial_token_labels[bbox_first_token_mask],992 )993 else:994 initial_token_loss = loss_fct(initial_token_logits.view(-1, self.num_labels), initial_token_labels)995 996 subsequent_token_labels = subsequent_token_labels.view(-1)997 subsequent_token_loss = loss_fct(998 subsequent_token_logits.view(-1, max_seq_length + 1)[subsequent_token_mask],999 subsequent_token_labels[subsequent_token_mask],1000 )1001 1002 loss = initial_token_loss + subsequent_token_loss1003 1004 return BrosSpadeOutput(1005 loss=loss,1006 initial_token_logits=initial_token_logits,1007 subsequent_token_logits=subsequent_token_logits,1008 hidden_states=outputs.hidden_states,1009 attentions=outputs.attentions,1010 )1011 1012 1013@auto_docstring(1014 custom_intro="""1015 Bros Model with a token classification head on top (a entity_linker layer on top of the hidden-states output) e.g.1016 for Entity-Linking. The entity_linker is used to predict intra-entity links (one entity to another entity).1017 """1018)1019class BrosSpadeELForTokenClassification(BrosPreTrainedModel):1020 _keys_to_ignore_on_load_unexpected = [r"pooler"]1021 1022 def __init__(self, config):1023 super().__init__(config)1024 self.config = config1025 self.num_labels = config.num_labels1026 self.n_relations = config.n_relations1027 self.backbone_hidden_size = config.hidden_size1028 1029 self.bros = BrosModel(config)1030 (config.classifier_dropout if hasattr(config, "classifier_dropout") else config.hidden_dropout_prob)1031 1032 self.entity_linker = BrosRelationExtractor(config)1033 1034 self.init_weights()1035 1036 @can_return_tuple1037 @auto_docstring1038 def forward(1039 self,1040 input_ids: Optional[torch.Tensor] = None,1041 bbox: Optional[torch.Tensor] = None,1042 attention_mask: Optional[torch.Tensor] = None,1043 bbox_first_token_mask: Optional[torch.Tensor] = None,1044 token_type_ids: Optional[torch.Tensor] = None,1045 position_ids: Optional[torch.Tensor] = None,1046 head_mask: Optional[torch.Tensor] = None,1047 inputs_embeds: Optional[torch.Tensor] = None,1048 labels: Optional[torch.Tensor] = None,1049 output_attentions: Optional[bool] = None,1050 output_hidden_states: Optional[bool] = None,1051 return_dict: Optional[bool] = None,1052 ) -> Union[tuple[torch.Tensor], TokenClassifierOutput]:1053 r"""1054 bbox ('torch.FloatTensor' of shape '(batch_size, num_boxes, 4)'):1055 Bounding box coordinates for each token in the input sequence. Each bounding box is a list of four values1056 (x1, y1, x2, y2), where (x1, y1) is the top left corner, and (x2, y2) is the bottom right corner of the1057 bounding box.1058 bbox_first_token_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*):1059 Mask to indicate the first token of each bounding box. Mask values selected in `[0, 1]`:1060 1061 - 1 for tokens that are **not masked**,1062 - 0 for tokens that are **masked**.1063 1064 Examples:1065 1066 ```python1067 >>> import torch1068 >>> from transformers import BrosProcessor, BrosSpadeELForTokenClassification1069 1070 >>> processor = BrosProcessor.from_pretrained("jinho8345/bros-base-uncased")1071 1072 >>> model = BrosSpadeELForTokenClassification.from_pretrained("jinho8345/bros-base-uncased")1073 1074 >>> encoding = processor("Hello, my dog is cute", add_special_tokens=False, return_tensors="pt")1075 >>> bbox = torch.tensor([[[0, 0, 1, 1]]]).repeat(1, encoding["input_ids"].shape[-1], 1)1076 >>> encoding["bbox"] = bbox1077 1078 >>> outputs = model(**encoding)1079 ```"""1080 return_dict = return_dict if return_dict is not None else self.config.use_return_dict1081 1082 outputs = self.bros(1083 input_ids=input_ids,1084 bbox=bbox,1085 attention_mask=attention_mask,1086 token_type_ids=token_type_ids,1087 position_ids=position_ids,1088 head_mask=head_mask,1089 inputs_embeds=inputs_embeds,1090 output_attentions=output_attentions,1091 output_hidden_states=output_hidden_states,1092 return_dict=True,1093 )1094 1095 last_hidden_states = outputs[0]1096 last_hidden_states = last_hidden_states.transpose(0, 1).contiguous()1097 1098 logits = self.entity_linker(last_hidden_states, last_hidden_states).squeeze(0)1099 1100 loss = None1101 if labels is not None:1102 loss_fct = CrossEntropyLoss()1103 1104 batch_size, max_seq_length = attention_mask.shape1105 device = attention_mask.device1106 1107 self_token_mask = torch.eye(max_seq_length, max_seq_length + 1).to(device=device, dtype=torch.bool)1108 1109 mask = bbox_first_token_mask.view(-1)1110 bbox_first_token_mask = torch.cat(1111 [1112 ~bbox_first_token_mask,1113 torch.zeros([batch_size, 1], dtype=torch.bool, device=device),1114 ],1115 axis=1,1116 )1117 logits = logits.masked_fill(bbox_first_token_mask[:, None, :], torch.finfo(logits.dtype).min)1118 logits = logits.masked_fill(self_token_mask[None, :, :], torch.finfo(logits.dtype).min)1119 1120 loss = loss_fct(logits.view(-1, max_seq_length + 1)[mask], labels.view(-1)[mask])1121 1122 return TokenClassifierOutput(1123 loss=loss,1124 logits=logits,1125 hidden_states=outputs.hidden_states,1126 attentions=outputs.attentions,1127 )1128 1129 1130__all__ = [1131 "BrosPreTrainedModel",1132 "BrosModel",1133 "BrosForTokenClassification",1134 "BrosSpadeEEForTokenClassification",1135 "BrosSpadeELForTokenClassification",1136]1137 