Sentence Similarity
PyTorch
English
taylor-m1
constructai commited on
Commit
501da72
·
verified ·
1 Parent(s): 217b3c0

Upload modeling.py

Browse files
Files changed (1) hide show
  1. modeling.py +115 -0
modeling.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ import math
6
+ import json
7
+ from transformers import BertTokenizer
8
+ from huggingface_hub import hf_hub_download
9
+
10
+ class ModelConfig:
11
+ def __init__(self, **kwargs):
12
+ self.vocab_size = kwargs.get('vocab_size', 30522)
13
+ self.max_seq_len = kwargs.get('max_seq_len', 128)
14
+ self.type_vocab_size = kwargs.get('type_vocab_size', 2)
15
+ self.hidden_size = kwargs.get('hidden_size', 384)
16
+ self.num_layers = kwargs.get('num_layers', 6)
17
+ self.num_heads = kwargs.get('num_heads', 8)
18
+ self.ffn_size = kwargs.get('ffn_size', 1536)
19
+ self.dropout = kwargs.get('dropout', 0.1)
20
+ self.attention_dropout = kwargs.get('attention_dropout', 0.1)
21
+ self.embedding_dim = kwargs.get('embedding_dim', 256)
22
+ self.layer_norm_eps = kwargs.get('layer_norm_eps', 1e-12)
23
+
24
+ class FeedForward(nn.Module):
25
+ def __init__(self, config):
26
+ super().__init__()
27
+ self.fc1 = nn.Linear(config.hidden_size, config.ffn_size)
28
+ self.fc2 = nn.Linear(config.ffn_size, config.hidden_size)
29
+ self.act = nn.GELU()
30
+ def forward(self, x):
31
+ return self.fc2(self.act(self.fc1(x)))
32
+
33
+ class MultiHeadAttention(nn.Module):
34
+ def __init__(self, config):
35
+ super().__init__()
36
+ self.num_heads = config.num_heads
37
+ self.head_dim = config.hidden_size // config.num_heads
38
+ self.qkv_proj = nn.Linear(config.hidden_size, 3 * config.hidden_size)
39
+ self.out_proj = nn.Linear(config.hidden_size, config.hidden_size)
40
+ self.dropout = nn.Dropout(config.attention_dropout)
41
+ def forward(self, x, mask=None):
42
+ B, L, D = x.shape
43
+ qkv = self.qkv_proj(x).reshape(B, L, 3, self.num_heads, self.head_dim)
44
+ q, k, v = qkv.unbind(2)
45
+ q = q.transpose(1, 2)
46
+ k = k.transpose(1, 2)
47
+ v = v.transpose(1, 2)
48
+ attn = (q @ k.transpose(-2, -1)) / math.sqrt(self.head_dim)
49
+ if mask is not None:
50
+ attn = attn.masked_fill(mask[:, None, None, :] == 0, float('-inf'))
51
+ attn = torch.softmax(attn, dim=-1)
52
+ attn = self.dropout(attn)
53
+ out = (attn @ v).transpose(1, 2).reshape(B, L, D)
54
+ return self.out_proj(out)
55
+
56
+ class TransformerBlock(nn.Module):
57
+ def __init__(self, config):
58
+ super().__init__()
59
+ self.attention = MultiHeadAttention(config)
60
+ self.norm1 = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
61
+ self.ffn = FeedForward(config)
62
+ self.norm2 = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
63
+ def forward(self, x, mask=None):
64
+ attn_out = self.attention(x, mask)
65
+ x = self.norm1(x + attn_out)
66
+ ffn_out = self.ffn(x)
67
+ x = self.norm2(x + ffn_out)
68
+ return x
69
+
70
+ class EmbeddingModel(nn.Module):
71
+ def __init__(self, config):
72
+ super().__init__()
73
+ self.token_embeddings = nn.Embedding(config.vocab_size, config.hidden_size)
74
+ self.position_embeddings = nn.Embedding(config.max_seq_len, config.hidden_size)
75
+ self.type_embeddings = nn.Embedding(config.type_vocab_size, config.hidden_size)
76
+ self.layer_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
77
+ self.dropout = nn.Dropout(config.dropout)
78
+ self.encoder = nn.ModuleList([TransformerBlock(config) for _ in range(config.num_layers)])
79
+ self.final_norm = nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
80
+
81
+ def forward(self, input_ids, attention_mask=None, token_type_ids=None):
82
+ seq_len = input_ids.size(1)
83
+ position_ids = torch.arange(seq_len, device=input_ids.device).unsqueeze(0)
84
+ if token_type_ids is None:
85
+ token_type_ids = torch.zeros_like(input_ids)
86
+ x = self.token_embeddings(input_ids) + self.position_embeddings(position_ids) + self.type_embeddings(token_type_ids)
87
+ x = self.layer_norm(x)
88
+ x = self.dropout(x)
89
+ for layer in self.encoder:
90
+ x = layer(x, attention_mask)
91
+ x = self.final_norm(x)
92
+ return x[:, 0, :]
93
+
94
+ def load_taylor_model(repo_id="constructai/taylor-v1-128-emb", device="cuda"):
95
+ config_path = hf_hub_download(repo_id, "config.json")
96
+ model_path = hf_hub_download(repo_id, "pytorch_model.bin")
97
+ with open(config_path) as f:
98
+ config_dict = json.load(f)
99
+ config = ModelConfig(**config_dict)
100
+ model = EmbeddingModel(config)
101
+ model.load_state_dict(torch.load(model_path, map_location="cpu"))
102
+ model.to(device)
103
+ model.eval()
104
+ tokenizer = BertTokenizer.from_pretrained(repo_id)
105
+ return model, tokenizer, config
106
+
107
+ def embed_texts(model, tokenizer, texts, max_len=128, normalize=True, device="cuda"):
108
+ encoded = tokenizer(texts, padding=True, truncation=True, max_length=max_len, return_tensors="pt")
109
+ input_ids = encoded["input_ids"].to(device)
110
+ attention_mask = encoded["attention_mask"].to(device)
111
+ with torch.no_grad():
112
+ embs = model(input_ids, attention_mask)
113
+ if normalize:
114
+ embs = F.normalize(embs, p=2, dim=1)
115
+ return embs.cpu().numpy()