BlackSamorez commited on
Commit
e9730b5
·
verified ·
1 Parent(s): f4e8d02

Upload modeling_cloverlm.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. modeling_cloverlm.py +249 -0
modeling_cloverlm.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from math import sqrt
3
+
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+ from transformers import PreTrainedModel, GenerationMixin
8
+ from transformers.modeling_outputs import CausalLMOutputWithPast
9
+
10
+ from .configuration_cloverlm import CloverLMConfig
11
+ from .fake_quartet import FakeQuartetLinear
12
+
13
+
14
+
15
+ def _sphere_norm(X, dim=-1):
16
+ return F.normalize(X, dim=dim)
17
+
18
+
19
+ class _ReLU2(nn.Module):
20
+ def forward(self, x):
21
+ return F.relu(x) ** 2
22
+
23
+
24
+ def _make_linear(in_f, out_f, bias, quartet_2_impl):
25
+ if quartet_2_impl == "pseudoquant":
26
+ return FakeQuartetLinear(in_f, out_f, bias)
27
+ elif quartet_2_impl == "quartet2":
28
+ try:
29
+ from quartet2.linear import Quartet_II_linear
30
+ except ImportError as e:
31
+ e.add_note("Quartet_II_linear import failed. Install the latest quartet2 from https://github.com/IST-DASLab/Quartet-II")
32
+ raise e
33
+
34
+ return Quartet_II_linear(in_f, out_f, bias)
35
+ else:
36
+ raise ValueError(f"Unsupported quartet_2_impl: {quartet_2_impl}")
37
+
38
+
39
+ def _build_rope(context, d_head, device):
40
+ ms = torch.arange(context, device=device, dtype=torch.float32)
41
+ js = torch.arange(d_head // 2, device=device, dtype=torch.float32)
42
+ theta = 1.0 / (1024.0 ** (2.0 * js / d_head))
43
+ phi = ms[:, None] @ theta[None, :]
44
+ cos = torch.cos(phi).repeat_interleave(2, dim=1)
45
+ sin = torch.sin(phi).repeat_interleave(2, dim=1)
46
+ return torch.stack((cos, sin))
47
+
48
+
49
+ def _apply_rope(X, rope):
50
+ X_ = torch.empty_like(X)
51
+ X_[..., 0::2] = -X[..., 1::2]
52
+ X_[..., 1::2] = X[..., 0::2]
53
+ return (X * rope[0] + X_ * rope[1]).to(X.dtype)
54
+
55
+
56
+
57
+ class _MLP(nn.Module):
58
+
59
+ def __init__(self, d, d_hidden, quartet_2_impl):
60
+ super().__init__()
61
+ self.l1 = nn.Sequential(_make_linear(d, d_hidden, False, quartet_2_impl), _ReLU2())
62
+ self.l2 = _make_linear(d_hidden, d, False, quartet_2_impl)
63
+
64
+ def forward(self, x):
65
+ return self.l2(self.l1(x))
66
+
67
+
68
+
69
+ class MHSA(nn.Module):
70
+ def __init__(self, heads, d_head, ratio, quartet_2_impl):
71
+ super().__init__()
72
+ self.heads = heads
73
+ self.d_head = d_head
74
+ self.d = heads * d_head
75
+ self.groups = heads // ratio
76
+ d_kv = self.groups * d_head
77
+
78
+ self.lq = _make_linear(self.d, self.d, False, quartet_2_impl)
79
+ self.lk = _make_linear(self.d, d_kv, False, quartet_2_impl)
80
+ self.lv = _make_linear(self.d, d_kv, False, quartet_2_impl)
81
+ self.lo = _make_linear(self.d, self.d, False, quartet_2_impl)
82
+
83
+ self.scale = nn.Parameter(torch.full((1, heads, 1, 1), sqrt(d_head)))
84
+
85
+ def forward(self, X, rope, attn_backend):
86
+ B = X.shape[0] if X.dim() == 3 else 1
87
+ ctx = X.shape[-2]
88
+
89
+ Q = self.lq(X).unflatten(-1, (self.heads, self.d_head)).movedim(-3, -2)
90
+ K = self.lk(X).unflatten(-1, (self.groups, self.d_head)).movedim(-3, -2)
91
+ V = self.lv(X).unflatten(-1, (self.groups, self.d_head)).movedim(-3, -2)
92
+
93
+ Q = _apply_rope(Q, rope)
94
+ K = _apply_rope(K, rope)
95
+ Q = _sphere_norm(Q)
96
+ K = _sphere_norm(K)
97
+
98
+ Q_shape = Q.shape
99
+ Q = self.scale * Q
100
+ Q = Q.reshape(Q_shape)
101
+
102
+ if attn_backend == "pytorch":
103
+ K = K.repeat_interleave(self.heads // self.groups, dim=-3)
104
+ V = V.repeat_interleave(self.heads // self.groups, dim=-3)
105
+ Y = F.scaled_dot_product_attention(Q, K, V, is_causal=True, scale=1.0)
106
+ Y = Y.movedim(-3, -2).flatten(-2, -1)
107
+ elif attn_backend in ("flash2", "flash3", "flash4"):
108
+ Q = Q.movedim(-3, -2).reshape(-1, ctx, self.heads, self.d_head)
109
+ K = K.movedim(-3, -2).reshape(-1, ctx, self.groups, self.d_head)
110
+ V = V.movedim(-3, -2).reshape(-1, ctx, self.groups, self.d_head)
111
+
112
+ dtype = Q.dtype if Q.dtype in (torch.bfloat16, torch.float16) else torch.bfloat16
113
+ if attn_backend == "flash2":
114
+ try:
115
+ import flash_attn
116
+ except ImportError as e:
117
+ e.add_note(f"Can't run `attn_backend=flash2` because can't import flash_attn")
118
+ raise e
119
+ Y = flash_attn.flash_attn_func(Q.to(dtype), K.to(dtype), V.to(dtype), causal=True, softmax_scale=1.0)
120
+ elif attn_backend == "flash3":
121
+ import importlib
122
+ try:
123
+ _fa3 = importlib.import_module("flash_attn_interface")
124
+ except ImportError as e:
125
+ e.add_note(f"Can't run `attn_backend=flash3` because can't import flash_attn_interface")
126
+ raise e
127
+ Y = _fa3.flash_attn_func(Q.to(dtype), K.to(dtype), V.to(dtype), causal=True, softmax_scale=1.0)
128
+ elif attn_backend == "flash4":
129
+ import importlib
130
+ try:
131
+ _fa4 = importlib.import_module("flash_attn.cute")
132
+ except ImportError as e:
133
+ e.add_note(f"Can't run `attn_backend=flash4` because can't import flash_attn.cute")
134
+ raise e
135
+ Y = _fa4.flash_attn_func(Q.to(dtype), K.to(dtype), V.to(dtype), causal=True, softmax_scale=1.0)[0]
136
+ Y = Y.to(Q.dtype).flatten(-2, -1)
137
+
138
+ return self.lo(Y)
139
+
140
+
141
+
142
+ class _Block(nn.Module):
143
+
144
+ def __init__(self, heads, d_head, ratio, quartet_2_impl):
145
+ super().__init__()
146
+ d = heads * d_head
147
+
148
+ self.mhsa = MHSA(heads, d_head, ratio, quartet_2_impl)
149
+ self.out_att_norm = nn.RMSNorm(d, elementwise_affine=True)
150
+
151
+ self.mlp = _MLP(d, 4 * d, quartet_2_impl)
152
+ self.out_mlp_norm = nn.RMSNorm(d, elementwise_affine=True)
153
+
154
+ def forward(self, X, rope, attn_backend):
155
+ Y = self.out_att_norm(self.mhsa(X, rope, attn_backend))
156
+ Y = X + Y
157
+ Z = self.out_mlp_norm(self.mlp(Y))
158
+ return Y + Z
159
+
160
+
161
+
162
+ class _Transformer(nn.Module):
163
+
164
+ def __init__(self, vocab_size, num_blocks, heads, d_head, ratio,
165
+ max_context, std, quartet_2_impl, weight_tying, attn_backend):
166
+ super().__init__()
167
+ self.d_head = d_head
168
+ self.attn_backend = attn_backend
169
+ d = heads * d_head
170
+
171
+ self.emb = nn.Embedding(vocab_size, d)
172
+ self.blocks = nn.Sequential(*[
173
+ _Block(heads, d_head, ratio, quartet_2_impl) for _ in range(num_blocks)
174
+ ])
175
+ self.out_norm = nn.RMSNorm(d, elementwise_affine=True)
176
+ self.linear = nn.Linear(d, vocab_size, bias=False)
177
+
178
+ if weight_tying:
179
+ self.emb.weight = self.linear.weight
180
+
181
+ for name, p in self.named_parameters():
182
+ parent_name, _, suffix = name.rpartition(".")
183
+ parent = self.get_submodule(parent_name)
184
+ if isinstance(parent, (nn.Linear, nn.Embedding)) and suffix == "weight":
185
+ nn.init.normal_(p, 0, std)
186
+ elif isinstance(parent, nn.RMSNorm) and suffix == "weight":
187
+ nn.init.ones_(p)
188
+ elif p.ndim == 4:
189
+ nn.init.constant_(p, sqrt(d_head))
190
+
191
+ if quartet_2_impl:
192
+ for m in self.modules():
193
+ if isinstance(m, (nn.LayerNorm, nn.RMSNorm, nn.Embedding)):
194
+ m.to(torch.bfloat16)
195
+
196
+ def forward(self, ids):
197
+ ctx = ids.shape[-1]
198
+ rope = _build_rope(ctx, self.d_head, device=ids.device)
199
+
200
+ X = self.emb(ids)
201
+ for block in self.blocks:
202
+ X = block(X, rope, self.attn_backend)
203
+ X = self.out_norm(X)
204
+ return self.linear(X)
205
+
206
+
207
+
208
+ class CloverLMForCausalLM(PreTrainedModel, GenerationMixin):
209
+ config_class = CloverLMConfig
210
+ supports_gradient_checkpointing = False
211
+ _no_split_modules = ["_Block"]
212
+ _tied_weights_keys = ["transformer.linear.weight"]
213
+ _tp_plan = {}
214
+
215
+ def __init__(self, config: CloverLMConfig):
216
+ super().__init__(config)
217
+ self.all_tied_weights_keys = {k: "transformer.emb.weight"
218
+ for k in (self._tied_weights_keys or [])}
219
+ self.transformer = _Transformer(
220
+ vocab_size=config.vocab_size,
221
+ num_blocks=config.num_blocks,
222
+ heads=config.heads,
223
+ d_head=config.d_head,
224
+ ratio=config.ratio,
225
+ max_context=config.max_context,
226
+ std=0.02,
227
+ quartet_2_impl=config.quartet_2_impl,
228
+ weight_tying=config.weight_tying,
229
+ attn_backend=config.attn_backend,
230
+ )
231
+
232
+ def forward(self, input_ids, attention_mask=None, labels=None, **kwargs):
233
+ logits = self.transformer(input_ids)
234
+
235
+ loss = None
236
+ if labels is not None:
237
+ shift_logits = logits[..., :-1, :].contiguous()
238
+ shift_labels = labels[..., 1:].contiguous()
239
+ loss = F.cross_entropy(
240
+ shift_logits.view(-1, shift_logits.size(-1)),
241
+ shift_labels.view(-1),
242
+ )
243
+ return CausalLMOutputWithPast(loss=loss, logits=logits)
244
+
245
+ def prepare_inputs_for_generation(self, input_ids, **kwargs):
246
+ return {"input_ids": input_ids}
247
+
248
+ def _supports_default_dynamic_cache(self):
249
+ return False