MoEmad07's picture
Load Model from HF hub
56bdf8f
Raw
History Blame Contribute Delete
3.46 kB
import torch
import torch.nn as nn
from transformers import AutoModel
import os
from config import *
class XLMRBiGRU(nn.Module):
def __init__(self, xlmr_model_name, gru_hidden_size, gru_num_layers, dropout, freeze_xlmr_layers):
super().__init__()
self.xlmr = AutoModel.from_pretrained(xlmr_model_name)
# freeze embedding layer
for param in self.xlmr.embeddings.parameters():
param.requires_grad = False
# freeze first 6 encoder layers
for num_layer in range(freeze_xlmr_layers):
for param in self.xlmr.encoder.layer[num_layer].parameters():
param.requires_grad = False
self.gru = nn.GRU(
input_size=self.xlmr.config.hidden_size,
hidden_size=gru_hidden_size,
num_layers=gru_num_layers,
batch_first=True,
bidirectional=True,
dropout=dropout if gru_num_layers > 1 else 0
)
self.attention = nn.Linear(gru_hidden_size * 2, 1) # For attention scoring
self.classifier = nn.Linear(gru_hidden_size * 2, 1) # Binary classification
self.dropout = nn.Dropout(dropout)
def forward(self, input_ids, attention_mask, conv_length):
batch_size, max_conv_len, max_msg_len = input_ids.size()
# Reshape for XLM-RoBERTa
input_ids = input_ids.view(-1, max_msg_len) # (batch_size * max_conv_len, max_msg_len)
attention_mask = attention_mask.view(-1, max_msg_len) # (batch_size * max_conv_len, max_msg_len)
# XLM-RoBERTa encoding
outputs = self.xlmr(input_ids=input_ids, attention_mask=attention_mask)
cls_embeddings = outputs.last_hidden_state[:, 0, :] # (batch_size * max_conv_len, hidden_size)
# Reshape back to conversation format
cls_embeddings = cls_embeddings.view(batch_size, max_conv_len, -1) # (batch_size, max_conv_len, hidden_size)
# GRU encoding
gru_output, _ = self.gru(cls_embeddings) # (batch_size, max_conv_len, gru_hidden_size*2)
# Attention mechanism
attn_scores = self.attention(gru_output).squeeze(-1) # (batch_size, max_conv_len)
# Mask out padding messages
mask = torch.arange(max_conv_len).unsqueeze(0).to(conv_length.device) < conv_length.unsqueeze(1)
attn_scores[~mask] = float('-inf') # Set scores of padding messages to -inf
attn_weights = torch.softmax(attn_scores, dim=1).unsqueeze(-1) # (batch_size, max_conv_len, 1)
context_vector = torch.sum(attn_weights * gru_output, dim=1) # (batch_size, gru_hidden_size*2)
context_vector = self.dropout(context_vector)
logits = self.classifier(context_vector).squeeze(-1) # (batch_size,)
return logits
if __name__ == "__main__":
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
model = XLMRBiGRU(
xlmr_model_name=XLMR_MODEL_NAME,
gru_hidden_size=GRU_HIDDEN_SIZE,
gru_num_layers=GRU_NUM_LAYERS,
dropout=DROPOUT,
freeze_xlmr_layers=FREEZE_XLMR_LAYERS
)
# dummy input
input_ids = torch.randint(0, 100, (2, 50, 64))
attention_mask = torch.ones(2, 50, 64, dtype=torch.long)
conv_lengths = torch.tensor([50, 30])
output = model(input_ids, attention_mask, conv_lengths)
print(output.shape) # should be (2,)