NeTS-lab commited on
Commit
ebcf00b
·
verified ·
1 Parent(s): 21f446f

Upload folder using huggingface_hub

Browse files
config.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "HawkForCausalLM"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "modeling_hawk.HawkConfig",
7
+ "AutoModelForCausalLM": "modeling_hawk.HawkForCausalLM"
8
+ },
9
+ "bos_token_id": 1,
10
+ "conv_kernel": 4,
11
+ "dtype": "float32",
12
+ "eos_token_id": 2,
13
+ "max_position_embeddings": 1024,
14
+ "mlp_expansion": 3,
15
+ "model_type": "hawk_rglru",
16
+ "n_embd": 704,
17
+ "n_layer": 12,
18
+ "pad_token_id": 3,
19
+ "rglru_c": 8.0,
20
+ "rmsnorm_eps": 1e-06,
21
+ "rnn_width": 768,
22
+ "tie_word_embeddings": true,
23
+ "transformers_version": "5.3.0",
24
+ "vocab_size": 39697
25
+ }
generation_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 1,
4
+ "do_sample": false,
5
+ "eos_token_id": 2,
6
+ "output_attentions": false,
7
+ "output_hidden_states": false,
8
+ "pad_token_id": 3,
9
+ "transformers_version": "5.3.0"
10
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:68dfc1d65b30a42f7df2a44e033c3778fbcc47c781e4188e5fe60d9736a5a7e4
3
+ size 461107144
modeling_hawk.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ HF-compatible single-language Hawk / RG-LRU model, for lm-eval.
4
+
5
+ Self-contained `trust_remote_code` modeling file. The building blocks are the
6
+ SAME code used at training time (De et al., 2024, Griffin/Hawk; arXiv:2402.19427),
7
+ so the per-language export state_dict maps 1:1 onto this module's parameters
8
+ (top-level attribute names wte / layers / norm_f / lm_head match the export keys
9
+ exactly -- no renaming, no transpose). Exposes the standard
10
+ forward(input_ids, labels=None) -> CausalLMOutputWithPast that lm-eval expects.
11
+
12
+ Register via config.json:
13
+ "model_type": "hawk_rglru",
14
+ "architectures": ["HawkForCausalLM"],
15
+ "auto_map": {
16
+ "AutoConfig": "modeling_hawk.HawkConfig",
17
+ "AutoModelForCausalLM": "modeling_hawk.HawkForCausalLM"
18
+ }
19
+ """
20
+
21
+ from typing import Optional
22
+
23
+ import torch
24
+ import torch.nn as nn
25
+ import torch.nn.functional as F
26
+ from transformers import PreTrainedModel, PretrainedConfig
27
+ from transformers.generation import GenerationMixin
28
+ from transformers.modeling_outputs import (
29
+ CausalLMOutputWithPast, SequenceClassifierOutput,
30
+ )
31
+
32
+
33
+ class RMSNorm(nn.Module):
34
+ def __init__(self, dim: int, eps: float = 1e-6):
35
+ super().__init__()
36
+ self.weight = nn.Parameter(torch.ones(dim))
37
+ self.eps = eps
38
+
39
+ def forward(self, x):
40
+ norm = torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
41
+ return self.weight * (x * norm)
42
+
43
+
44
+ def diag_linear_scan(a, b):
45
+ """Inclusive parallel scan of h_t = a_t*h_{t-1} + b_t (h_0=0), diagonal affine.
46
+ Hillis-Steele in real space: ceil(log2 T) vectorised passes, exact & stable
47
+ (a in (0,1)), torch.compile-friendly (static shapes)."""
48
+ T = a.shape[1]
49
+ A, H = a, b
50
+ d = 1
51
+ while d < T:
52
+ A_prev = torch.cat([A.new_ones(A.shape[0], d, A.shape[2]), A[:, :-d]], dim=1)
53
+ H_prev = torch.cat([H.new_zeros(H.shape[0], d, H.shape[2]), H[:, :-d]], dim=1)
54
+ H = A * H_prev + H
55
+ A = A * A_prev
56
+ d *= 2
57
+ return H
58
+
59
+
60
+ class RGLRU(nn.Module):
61
+ """Real-Gated Linear Recurrent Unit (De et al., 2024)."""
62
+
63
+ def __init__(self, width: int, c: float = 8.0, use_parallel_scan: bool = True):
64
+ super().__init__()
65
+ self.width = width
66
+ self.c = c
67
+ self.use_parallel_scan = use_parallel_scan
68
+ self.input_gate = nn.Linear(width, width)
69
+ self.recur_gate = nn.Linear(width, width)
70
+ lam = torch.empty(width).uniform_(2.197, 6.907)
71
+ self.log_lambda = nn.Parameter(lam)
72
+
73
+ def forward(self, x): # x: (B, T, W)
74
+ B, T, W = x.shape
75
+ r = torch.sigmoid(self.recur_gate(x))
76
+ i = torch.sigmoid(self.input_gate(x))
77
+ log_a = -F.softplus(-self.log_lambda)
78
+ log_a_t = self.c * r * log_a
79
+ a_t = torch.exp(log_a_t)
80
+ mult = torch.sqrt(torch.clamp(-torch.expm1(2.0 * log_a_t), min=1e-8))
81
+ gated_x = mult * (i * x)
82
+ if self.use_parallel_scan:
83
+ return diag_linear_scan(a_t, gated_x)
84
+ h = torch.zeros(B, W, device=x.device, dtype=x.dtype)
85
+ outs = []
86
+ for t in range(T):
87
+ h = a_t[:, t] * h + gated_x[:, t]
88
+ outs.append(h)
89
+ return torch.stack(outs, dim=1)
90
+
91
+
92
+ class RecurrentBlock(nn.Module):
93
+ def __init__(self, d_model: int, d_rnn: int, conv_kernel: int = 4, rglru_c: float = 8.0):
94
+ super().__init__()
95
+ self.conv_kernel = conv_kernel
96
+ self.in_gate = nn.Linear(d_model, d_rnn)
97
+ self.in_recur = nn.Linear(d_model, d_rnn)
98
+ self.conv = nn.Conv1d(d_rnn, d_rnn, conv_kernel, groups=d_rnn,
99
+ padding=conv_kernel - 1)
100
+ self.rglru = RGLRU(d_rnn, rglru_c)
101
+ self.out = nn.Linear(d_rnn, d_model)
102
+
103
+ def forward(self, x):
104
+ gate = F.gelu(self.in_gate(x))
105
+ rec = self.in_recur(x).transpose(1, 2)
106
+ rec = self.conv(rec)[..., : x.size(1)]
107
+ rec = self.rglru(rec.transpose(1, 2))
108
+ return self.out(gate * rec)
109
+
110
+
111
+ class MLPBlock(nn.Module):
112
+ def __init__(self, d_model: int, expansion: int = 3):
113
+ super().__init__()
114
+ hidden = expansion * d_model
115
+ self.gate = nn.Linear(d_model, hidden)
116
+ self.up = nn.Linear(d_model, hidden)
117
+ self.down = nn.Linear(hidden, d_model)
118
+
119
+ def forward(self, x):
120
+ return self.down(F.gelu(self.gate(x)) * self.up(x))
121
+
122
+
123
+ class HawkLayer(nn.Module):
124
+ def __init__(self, d_model, d_rnn, conv_kernel, mlp_expansion, eps, rglru_c=8.0):
125
+ super().__init__()
126
+ self.norm1 = RMSNorm(d_model, eps)
127
+ self.recur = RecurrentBlock(d_model, d_rnn, conv_kernel, rglru_c)
128
+ self.norm2 = RMSNorm(d_model, eps)
129
+ self.mlp = MLPBlock(d_model, mlp_expansion)
130
+
131
+ def forward(self, x):
132
+ x = x + self.recur(self.norm1(x))
133
+ x = x + self.mlp(self.norm2(x))
134
+ return x
135
+
136
+
137
+ class HawkConfig(PretrainedConfig):
138
+ model_type = "hawk_rglru"
139
+
140
+ def __init__(self, vocab_size: int = 16384, n_layer: int = 12, n_embd: int = 768,
141
+ rnn_width: Optional[int] = None, conv_kernel: int = 4,
142
+ mlp_expansion: int = 3, rmsnorm_eps: float = 1e-6, rglru_c: float = 8.0,
143
+ max_position_embeddings: int = 1024, tie_word_embeddings: bool = True,
144
+ bos_token_id: int = 2, eos_token_id: int = 3, pad_token_id: int = 1,
145
+ **kwargs):
146
+ self.vocab_size = vocab_size
147
+ self.n_layer = n_layer
148
+ self.n_embd = n_embd
149
+ self.rnn_width = rnn_width
150
+ self.conv_kernel = conv_kernel
151
+ self.mlp_expansion = mlp_expansion
152
+ self.rmsnorm_eps = rmsnorm_eps
153
+ self.rglru_c = rglru_c
154
+ self.max_position_embeddings = max_position_embeddings
155
+ self.auto_map = {
156
+ "AutoConfig": "modeling_hawk.HawkConfig",
157
+ "AutoModelForCausalLM": "modeling_hawk.HawkForCausalLM",
158
+ }
159
+ super().__init__(tie_word_embeddings=tie_word_embeddings,
160
+ bos_token_id=bos_token_id, eos_token_id=eos_token_id,
161
+ pad_token_id=pad_token_id, **kwargs)
162
+
163
+ @property
164
+ def d_rnn(self):
165
+ return self.rnn_width if self.rnn_width is not None else self.n_embd
166
+
167
+
168
+ class HawkForCausalLM(PreTrainedModel, GenerationMixin):
169
+ config_class = HawkConfig
170
+ _tied_weights_keys = {"lm_head.weight": "wte.weight"}
171
+
172
+ def __init__(self, config: HawkConfig):
173
+ super().__init__(config)
174
+ d_rnn = config.d_rnn
175
+ self.wte = nn.Embedding(config.vocab_size, config.n_embd)
176
+ self.layers = nn.ModuleList([
177
+ HawkLayer(config.n_embd, d_rnn, config.conv_kernel,
178
+ config.mlp_expansion, config.rmsnorm_eps, config.rglru_c)
179
+ for _ in range(config.n_layer)])
180
+ self.norm_f = RMSNorm(config.n_embd, config.rmsnorm_eps)
181
+ self.lm_head = nn.Linear(config.n_embd, config.vocab_size, bias=False)
182
+ self.post_init()
183
+
184
+ def get_input_embeddings(self):
185
+ return self.wte
186
+
187
+ def set_input_embeddings(self, new):
188
+ self.wte = new
189
+
190
+ def get_output_embeddings(self):
191
+ return self.lm_head
192
+
193
+ def forward(self, input_ids: torch.LongTensor,
194
+ attention_mask: Optional[torch.Tensor] = None,
195
+ labels: Optional[torch.LongTensor] = None,
196
+ **kwargs) -> CausalLMOutputWithPast:
197
+ x = self.wte(input_ids)
198
+ for layer in self.layers:
199
+ x = layer(x)
200
+ x = self.norm_f(x)
201
+ logits = self.lm_head(x)
202
+ loss = None
203
+ if labels is not None:
204
+ shift_logits = logits[:, :-1, :].contiguous()
205
+ shift_labels = labels[:, 1:].contiguous()
206
+ loss = F.cross_entropy(shift_logits.view(-1, shift_logits.size(-1)),
207
+ shift_labels.view(-1), ignore_index=-100)
208
+ return CausalLMOutputWithPast(loss=loss, logits=logits)
209
+
210
+
211
+ class HawkForSequenceClassification(PreTrainedModel):
212
+ """
213
+ Sequence-classification head on top of the SAME Hawk backbone used for
214
+ causal LM. The backbone attribute names (wte / layers / norm_f) are
215
+ IDENTICAL to HawkForCausalLM, so a CausalLM export state_dict maps 1:1 onto
216
+ the backbone with no renaming. Only `score` is newly initialised, which is
217
+ the expected behaviour when starting a fine-tuning run.
218
+
219
+ The pooled representation is read from the hidden state at the last
220
+ non-padding position (right padding, as produced by the BabyLM finetune
221
+ tokenizer), matching the GPT-2 / Mamba sequence-classification convention.
222
+ """
223
+
224
+ config_class = HawkConfig
225
+
226
+ def __init__(self, config: HawkConfig):
227
+ super().__init__(config)
228
+ self.num_labels = config.num_labels
229
+ d_rnn = config.d_rnn
230
+ self.wte = nn.Embedding(config.vocab_size, config.n_embd)
231
+ self.layers = nn.ModuleList([
232
+ HawkLayer(config.n_embd, d_rnn, config.conv_kernel,
233
+ config.mlp_expansion, config.rmsnorm_eps, config.rglru_c)
234
+ for _ in range(config.n_layer)])
235
+ self.norm_f = RMSNorm(config.n_embd, config.rmsnorm_eps)
236
+ self.score = nn.Linear(config.n_embd, self.num_labels, bias=False)
237
+ self.post_init()
238
+
239
+ def get_input_embeddings(self):
240
+ return self.wte
241
+
242
+ def set_input_embeddings(self, new):
243
+ self.wte = new
244
+
245
+ def forward(self, input_ids: torch.LongTensor,
246
+ attention_mask: Optional[torch.Tensor] = None,
247
+ labels: Optional[torch.LongTensor] = None,
248
+ **kwargs) -> SequenceClassifierOutput:
249
+ x = self.wte(input_ids)
250
+ for layer in self.layers:
251
+ x = layer(x)
252
+ x = self.norm_f(x)
253
+ logits = self.score(x) # (B, T, num_labels)
254
+
255
+ B, T = input_ids.shape[:2]
256
+ # Index of the last real token per sequence (assumes right padding).
257
+ if attention_mask is not None:
258
+ last_idx = attention_mask.long().sum(-1) - 1
259
+ elif self.config.pad_token_id is not None:
260
+ last_idx = (input_ids != self.config.pad_token_id).int().sum(-1) - 1
261
+ else:
262
+ last_idx = torch.full((B,), T - 1, device=input_ids.device)
263
+ last_idx = last_idx.clamp(min=0)
264
+ pooled_logits = logits[torch.arange(B, device=input_ids.device), last_idx]
265
+
266
+ loss = None
267
+ if labels is not None:
268
+ if self.config.problem_type is None:
269
+ if self.num_labels == 1:
270
+ self.config.problem_type = "regression"
271
+ elif self.num_labels > 1 and labels.dtype in (torch.long, torch.int):
272
+ self.config.problem_type = "single_label_classification"
273
+ else:
274
+ self.config.problem_type = "multi_label_classification"
275
+
276
+ if self.config.problem_type == "regression":
277
+ loss_fct = nn.MSELoss()
278
+ loss = (loss_fct(pooled_logits.squeeze(), labels.squeeze())
279
+ if self.num_labels == 1
280
+ else loss_fct(pooled_logits, labels))
281
+ elif self.config.problem_type == "single_label_classification":
282
+ loss_fct = nn.CrossEntropyLoss()
283
+ loss = loss_fct(pooled_logits.view(-1, self.num_labels),
284
+ labels.view(-1))
285
+ else: # multi_label_classification
286
+ loss_fct = nn.BCEWithLogitsLoss()
287
+ loss = loss_fct(pooled_logits, labels.float())
288
+
289
+ return SequenceClassifierOutput(loss=loss, logits=pooled_logits)
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<s>",
4
+ "eos_token": "</s>",
5
+ "mask_token": "<mask>",
6
+ "model_max_length": 1000000000,
7
+ "pad_token": "<pad>",
8
+ "tokenizer_class": "TokenizersBackend",
9
+ "unk_token": "<unk>"
10
+ }
training_state.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "arch": "hawk",
3
+ "budget_unit": "eng_words",
4
+ "tokens_seen": 1635080830,
5
+ "eng_equiv_words_seen": 1027866306,
6
+ "eng_equiv_words_by_lang": {
7
+ "eng": 342615942,
8
+ "nld": 342660809,
9
+ "zho": 342589554
10
+ },
11
+ "iteration": 199990,
12
+ "temperature": null
13
+ }