ereniko commited on
Commit
3fcf7dd
·
verified ·
1 Parent(s): cb41b16

Add modeling_expivme_diffusion.py

Browse files
Files changed (1) hide show
  1. modeling_expivme_diffusion.py +179 -0
modeling_expivme_diffusion.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """HuggingFace Transformers model for ExpIvme-DiffusionConversate-v1-Instruct (SFT)."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+ from torch.nn.attention import SDPBackend, sdpa_kernel
9
+ from transformers import PreTrainedModel
10
+ from transformers.modeling_outputs import ModelOutput
11
+
12
+ try:
13
+ from .configuration_expivme_diffusion import ExpIvmeDiffusionConfig
14
+ except ImportError:
15
+ from configuration_expivme_diffusion import ExpIvmeDiffusionConfig
16
+
17
+ if torch.cuda.is_available() and torch.cuda.get_device_capability(0)[0] >= 8:
18
+ PREFERRED_SDPA_BACKENDS = [SDPBackend.CUDNN_ATTENTION, SDPBackend.FLASH_ATTENTION, SDPBackend.EFFICIENT_ATTENTION, SDPBackend.MATH]
19
+ else:
20
+ PREFERRED_SDPA_BACKENDS = [SDPBackend.EFFICIENT_ATTENTION, SDPBackend.MATH]
21
+
22
+
23
+ def _precompute_rope_freqs(head_dim, max_seq_len, theta, device=None):
24
+ freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2, device=device).float() / head_dim))
25
+ positions = torch.arange(max_seq_len, device=device).float()
26
+ angles = torch.outer(positions, freqs)
27
+ return torch.cos(angles), torch.sin(angles)
28
+
29
+
30
+ def _apply_rope(x, rope_cos_sin):
31
+ cos, sin = rope_cos_sin
32
+ B, H, T, D = x.shape
33
+ x1 = x[..., 0::2]
34
+ x2 = x[..., 1::2]
35
+ cos = cos.view(1, 1, T, D // 2).to(x.dtype)
36
+ sin = sin.view(1, 1, T, D // 2).to(x.dtype)
37
+ out1 = x1 * cos - x2 * sin
38
+ out2 = x1 * sin + x2 * cos
39
+ return torch.stack([out1, out2], dim=-1).reshape(B, H, T, D).type_as(x)
40
+
41
+
42
+ class ExpIvmeRMSNorm(nn.Module):
43
+ def __init__(self, dim, eps=1e-5):
44
+ super().__init__()
45
+ self.eps = eps
46
+ self.weight = nn.Parameter(torch.ones(dim))
47
+
48
+ def forward(self, x):
49
+ dtype = x.dtype
50
+ x = x.float()
51
+ rms = torch.rsqrt(x.pow(2).mean(dim=-1, keepdim=True) + self.eps)
52
+ return (x * rms).to(dtype) * self.weight
53
+
54
+
55
+ class ExpIvmeSelfAttention(nn.Module):
56
+ def __init__(self, hidden_dim, n_heads, dropout=0.0):
57
+ super().__init__()
58
+ self.n_heads = n_heads
59
+ self.head_dim = hidden_dim // n_heads
60
+ self.dropout = dropout
61
+ self.q_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
62
+ self.k_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
63
+ self.v_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
64
+ self.out_proj = nn.Linear(hidden_dim, hidden_dim, bias=False)
65
+
66
+ def forward(self, x, rope_freqs, attn_mask=None):
67
+ B, T, C = x.shape
68
+ q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
69
+ k = self.k_proj(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
70
+ v = self.v_proj(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
71
+ q = _apply_rope(q, rope_freqs)
72
+ k = _apply_rope(k, rope_freqs)
73
+ with sdpa_kernel(PREFERRED_SDPA_BACKENDS):
74
+ out = F.scaled_dot_product_attention(
75
+ q, k, v, attn_mask=attn_mask, is_causal=False,
76
+ dropout_p=self.dropout if self.training else 0.0,
77
+ )
78
+ out = out.transpose(1, 2).contiguous().view(B, T, C)
79
+ return self.out_proj(out)
80
+
81
+
82
+ class ExpIvmeSwiGLU(nn.Module):
83
+ def __init__(self, hidden_dim, ffn_mult):
84
+ super().__init__()
85
+ inner_dim = int(hidden_dim * ffn_mult * 2 / 3)
86
+ inner_dim = ((inner_dim + 7) // 8) * 8
87
+ self.gate_proj = nn.Linear(hidden_dim, inner_dim, bias=False)
88
+ self.up_proj = nn.Linear(hidden_dim, inner_dim, bias=False)
89
+ self.down_proj = nn.Linear(inner_dim, hidden_dim, bias=False)
90
+
91
+ def forward(self, x):
92
+ return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x))
93
+
94
+
95
+ class ExpIvmeBlock(nn.Module):
96
+ def __init__(self, hidden_dim, n_heads, ffn_mult, norm_eps, dropout=0.0):
97
+ super().__init__()
98
+ self.attn_norm = ExpIvmeRMSNorm(hidden_dim, eps=norm_eps)
99
+ self.attn = ExpIvmeSelfAttention(hidden_dim, n_heads, dropout)
100
+ self.ffn_norm = ExpIvmeRMSNorm(hidden_dim, eps=norm_eps)
101
+ self.ffn = ExpIvmeSwiGLU(hidden_dim, ffn_mult)
102
+
103
+ def forward(self, x, rope_freqs, attn_mask=None):
104
+ x = x + self.attn(self.attn_norm(x), rope_freqs, attn_mask=attn_mask)
105
+ x = x + self.ffn(self.ffn_norm(x))
106
+ return x
107
+
108
+
109
+ @dataclass
110
+ class DiffusionLMOutput(ModelOutput):
111
+ loss: torch.FloatTensor = None
112
+ logits: torch.FloatTensor = None
113
+
114
+
115
+ class ExpIvmeForDiffusionLMHub(PreTrainedModel):
116
+ config_class = ExpIvmeDiffusionConfig
117
+ base_model_prefix = "model"
118
+ _tied_weights_keys = {"lm_head.weight": "model.tok_embed.weight"}
119
+
120
+ def __init__(self, config):
121
+ super().__init__(config)
122
+ self.model = nn.Module()
123
+ self.model.tok_embed = nn.Embedding(config.vocab_size, config.hidden_dim)
124
+ self.model.blocks = nn.ModuleList([
125
+ ExpIvmeBlock(config.hidden_dim, config.n_heads, config.ffn_mult, config.norm_eps, config.dropout)
126
+ for _ in range(config.n_layers)
127
+ ])
128
+ self.model.final_norm = ExpIvmeRMSNorm(config.hidden_dim, eps=config.norm_eps)
129
+ self.lm_head = nn.Linear(config.hidden_dim, config.vocab_size, bias=False)
130
+ self.head_dim = config.hidden_dim // config.n_heads
131
+ self.rope_theta = config.rope_theta
132
+ self.post_init()
133
+ if config.tie_word_embeddings:
134
+ self.tie_weights()
135
+
136
+ def get_input_embeddings(self):
137
+ return self.model.tok_embed
138
+
139
+ def set_input_embeddings(self, value):
140
+ self.model.tok_embed = value
141
+
142
+ def get_output_embeddings(self):
143
+ return self.lm_head
144
+
145
+ def forward(self, input_ids, attention_mask=None, labels=None, mask_positions=None, t=None, return_dict=True, **kw):
146
+ B, T = input_ids.shape
147
+ rope = _precompute_rope_freqs(self.head_dim, T, self.rope_theta, device=input_ids.device)
148
+
149
+ sdpa_mask = None
150
+ if attention_mask is not None:
151
+ sdpa_mask = torch.zeros(B, 1, 1, T, dtype=torch.float32, device=input_ids.device)
152
+ sdpa_mask.masked_fill_(attention_mask[:, None, None, :] == 0, float("-inf"))
153
+ sdpa_mask = sdpa_mask.to(dtype=self.model.tok_embed.weight.dtype)
154
+
155
+ x = self.model.tok_embed(input_ids)
156
+ for block in self.model.blocks:
157
+ x = block(x, rope, attn_mask=sdpa_mask)
158
+ x = self.model.final_norm(x)
159
+ logits = self.lm_head(x)
160
+
161
+ loss = None
162
+ if labels is not None and mask_positions is not None:
163
+ ce = F.cross_entropy(
164
+ logits.view(-1, self.config.vocab_size), labels.view(-1), ignore_index=-100, reduction="none",
165
+ ).view(B, T)
166
+ ce = ce * mask_positions.float()
167
+ per_example_loss = ce.sum(dim=1)
168
+ if t is not None:
169
+ weight = 1.0 / t.clamp(min=1e-3)
170
+ per_example_loss = per_example_loss * weight
171
+ n_masked = mask_positions.float().sum(dim=1).clamp(min=1.0)
172
+ loss = (per_example_loss / n_masked).mean()
173
+
174
+ if not return_dict:
175
+ return (loss, logits) if loss is not None else (logits,)
176
+ return DiffusionLMOutput(loss=loss, logits=logits)
177
+
178
+
179
+ __all__ = ["ExpIvmeDiffusionConfig", "ExpIvmeForDiffusionLMHub"]