manjunath2n7 commited on
Commit
a4cc75e
·
verified ·
1 Parent(s): f865979

Update modeling_spin.py

Browse files
Files changed (1) hide show
  1. modeling_spin.py +54 -67
modeling_spin.py CHANGED
@@ -6,45 +6,6 @@ from transformers import PreTrainedModel, GenerationMixin
6
  from transformers.modeling_outputs import CausalLMOutputWithPast
7
  from .configuration_spin import SpinConfig
8
 
9
- try:
10
- from transformers.cache_utils import DynamicCache
11
- HAVE_DYNAMIC_CACHE = True
12
- except ImportError:
13
- HAVE_DYNAMIC_CACHE = False
14
-
15
-
16
- def extract_kv_cache(past_key_values):
17
- """Safely extracts KV cache regardless of whether HF passes DynamicCache, list, or tuple."""
18
- if past_key_values is None:
19
- return None, 0
20
-
21
- # 1. Hugging Face DynamicCache / Cache object
22
- if hasattr(past_key_values, "to_legacy_cache"):
23
- legacy = past_key_values.to_legacy_cache()
24
- seq_len = past_key_values.get_seq_length() if hasattr(past_key_values, "get_seq_length") else 0
25
- if seq_len == 0 or len(legacy) == 0:
26
- return None, 0
27
- return list(legacy), seq_len
28
-
29
- if hasattr(past_key_values, "key_cache") and hasattr(past_key_values, "value_cache"):
30
- if len(past_key_values.key_cache) == 0:
31
- return None, 0
32
- kv_list = [
33
- (past_key_values.key_cache[i], past_key_values.value_cache[i])
34
- for i in range(len(past_key_values.key_cache))
35
- ]
36
- seq_len = kv_list[0][0].shape[2] if len(kv_list) > 0 else 0
37
- return kv_list, seq_len
38
-
39
- # 2. Legacy tuple / list format
40
- if isinstance(past_key_values, (list, tuple)) and len(past_key_values) > 0:
41
- if past_key_values[0] is None:
42
- return None, 0
43
- seq_len = past_key_values[0][0].shape[2]
44
- return list(past_key_values), seq_len
45
-
46
- return None, 0
47
-
48
 
49
  class RMSNorm(nn.Module):
50
  def __init__(self, dim: int, eps: float = 1e-5):
@@ -93,8 +54,9 @@ class SwiGLU(nn.Module):
93
 
94
 
95
  class CausalSelfAttention(nn.Module):
96
- def __init__(self, config: SpinConfig):
97
  super().__init__()
 
98
  self.n_heads = config.n_heads
99
  self.head_dim = config.d_model // config.n_heads
100
 
@@ -106,7 +68,7 @@ class CausalSelfAttention(nn.Module):
106
  mask = torch.full((config.max_seq_len, config.max_seq_len), float("-inf"))
107
  self.register_buffer("causal_mask", torch.triu(mask, diagonal=1), persistent=False)
108
 
109
- def forward(self, x, freqs_cos, freqs_sin, kv_cache=None):
110
  B, T, C = x.shape
111
  q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim)
112
  k = self.k_proj(x).view(B, T, self.n_heads, self.head_dim)
@@ -115,11 +77,20 @@ class CausalSelfAttention(nn.Module):
115
  q, k = apply_rotary_emb(q, k, freqs_cos, freqs_sin)
116
  q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
117
 
118
- if kv_cache is not None:
119
- prev_k, prev_v = kv_cache
120
- k = torch.cat([prev_k, k], dim=2)
121
- v = torch.cat([prev_v, v], dim=2)
122
- new_kv_cache = (k, v)
 
 
 
 
 
 
 
 
 
123
 
124
  scores = (q @ k.transpose(-2, -1)) / math.sqrt(self.head_dim)
125
  if T > 1:
@@ -131,15 +102,15 @@ class CausalSelfAttention(nn.Module):
131
 
132
 
133
  class TransformerBlock(nn.Module):
134
- def __init__(self, config: SpinConfig):
135
  super().__init__()
136
  self.attn_norm = RMSNorm(config.d_model, eps=config.norm_eps)
137
- self.attn = CausalSelfAttention(config)
138
  self.ffn_norm = RMSNorm(config.d_model, eps=config.norm_eps)
139
  self.ffn = SwiGLU(config.d_model, config.d_ff)
140
 
141
- def forward(self, x, freqs_cos, freqs_sin, kv_cache=None):
142
- attn_out, next_kv = self.attn(self.attn_norm(x), freqs_cos, freqs_sin, kv_cache=kv_cache)
143
  x = x + attn_out
144
  x = x + self.ffn(self.ffn_norm(x))
145
  return x, next_kv
@@ -148,12 +119,13 @@ class TransformerBlock(nn.Module):
148
  class SpinForCausalLM(PreTrainedModel, GenerationMixin):
149
  config_class = SpinConfig
150
  _tied_weights_keys = {"lm_head.weight": "tok_embeddings.weight"}
 
151
 
152
  def __init__(self, config: SpinConfig):
153
  super().__init__(config)
154
  self.config = config
155
  self.tok_embeddings = nn.Embedding(config.vocab_size, config.d_model)
156
- self.layers = nn.ModuleList([TransformerBlock(config) for _ in range(config.n_layers)])
157
  self.norm = RMSNorm(config.d_model, eps=config.norm_eps)
158
  self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
159
 
@@ -192,16 +164,29 @@ class SpinForCausalLM(PreTrainedModel, GenerationMixin):
192
  B, T = input_ids.shape
193
  x = self.tok_embeddings(input_ids)
194
 
195
- kv_caches_in, start_pos = extract_kv_cache(past_key_values)
 
 
 
 
 
 
196
 
197
  freqs_cos = self.freqs_cos[start_pos : start_pos + T]
198
  freqs_sin = self.freqs_sin[start_pos : start_pos + T]
199
 
200
- new_kv_caches = []
201
  for i, layer in enumerate(self.layers):
202
- cache_i = kv_caches_in[i] if kv_caches_in is not None else None
203
- x, new_cache = layer(x, freqs_cos, freqs_sin, kv_cache=cache_i)
204
- new_kv_caches.append(new_cache)
 
 
 
 
 
 
 
205
 
206
  x = self.norm(x)
207
  logits = self.lm_head(x)
@@ -210,32 +195,34 @@ class SpinForCausalLM(PreTrainedModel, GenerationMixin):
210
  if labels is not None:
211
  loss = F.cross_entropy(logits.view(-1, self.config.vocab_size), labels.view(-1), ignore_index=-100)
212
 
213
- # Package past_key_values back into HF expected format
214
  if use_cache:
215
- if HAVE_DYNAMIC_CACHE and isinstance(past_key_values, DynamicCache):
216
- past_key_values_out = DynamicCache.from_legacy_cache(new_kv_caches)
217
- else:
218
- past_key_values_out = tuple(new_kv_caches)
219
  else:
220
- past_key_values_out = None
221
 
222
  if not return_dict:
223
- return (logits, loss, past_key_values_out)
224
 
225
  return CausalLMOutputWithPast(
226
  loss=loss,
227
  logits=logits,
228
- past_key_values=past_key_values_out,
229
  )
230
 
231
  def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **kwargs):
232
- _, seq_len = extract_kv_cache(past_key_values)
233
- if seq_len > 0:
 
 
 
 
 
 
234
  input_ids = input_ids[:, -1:]
 
235
  return {
236
  "input_ids": input_ids,
237
  "past_key_values": past_key_values,
238
  "attention_mask": attention_mask,
239
  "use_cache": True,
240
  }
241
-
 
6
  from transformers.modeling_outputs import CausalLMOutputWithPast
7
  from .configuration_spin import SpinConfig
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  class RMSNorm(nn.Module):
11
  def __init__(self, dim: int, eps: float = 1e-5):
 
54
 
55
 
56
  class CausalSelfAttention(nn.Module):
57
+ def __init__(self, config: SpinConfig, layer_idx: int = 0):
58
  super().__init__()
59
+ self.layer_idx = layer_idx
60
  self.n_heads = config.n_heads
61
  self.head_dim = config.d_model // config.n_heads
62
 
 
68
  mask = torch.full((config.max_seq_len, config.max_seq_len), float("-inf"))
69
  self.register_buffer("causal_mask", torch.triu(mask, diagonal=1), persistent=False)
70
 
71
+ def forward(self, x, freqs_cos, freqs_sin, past_key_value=None):
72
  B, T, C = x.shape
73
  q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim)
74
  k = self.k_proj(x).view(B, T, self.n_heads, self.head_dim)
 
77
  q, k = apply_rotary_emb(q, k, freqs_cos, freqs_sin)
78
  q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
79
 
80
+ # Standard Cache update (handles both DynamicCache and classic tuple)
81
+ if past_key_value is not None:
82
+ if hasattr(past_key_value, "update"):
83
+ k, v = past_key_value.update(k, v, self.layer_idx)
84
+ new_kv_cache = past_key_value
85
+ elif isinstance(past_key_value, tuple):
86
+ prev_k, prev_v = past_key_value
87
+ k = torch.cat([prev_k, k], dim=2)
88
+ v = torch.cat([prev_v, v], dim=2)
89
+ new_kv_cache = (k, v)
90
+ else:
91
+ new_kv_cache = (k, v)
92
+ else:
93
+ new_kv_cache = (k, v)
94
 
95
  scores = (q @ k.transpose(-2, -1)) / math.sqrt(self.head_dim)
96
  if T > 1:
 
102
 
103
 
104
  class TransformerBlock(nn.Module):
105
+ def __init__(self, config: SpinConfig, layer_idx: int = 0):
106
  super().__init__()
107
  self.attn_norm = RMSNorm(config.d_model, eps=config.norm_eps)
108
+ self.attn = CausalSelfAttention(config, layer_idx=layer_idx)
109
  self.ffn_norm = RMSNorm(config.d_model, eps=config.norm_eps)
110
  self.ffn = SwiGLU(config.d_model, config.d_ff)
111
 
112
+ def forward(self, x, freqs_cos, freqs_sin, past_key_value=None):
113
+ attn_out, next_kv = self.attn(self.attn_norm(x), freqs_cos, freqs_sin, past_key_value=past_key_value)
114
  x = x + attn_out
115
  x = x + self.ffn(self.ffn_norm(x))
116
  return x, next_kv
 
119
  class SpinForCausalLM(PreTrainedModel, GenerationMixin):
120
  config_class = SpinConfig
121
  _tied_weights_keys = {"lm_head.weight": "tok_embeddings.weight"}
122
+ _supports_cache_class = True
123
 
124
  def __init__(self, config: SpinConfig):
125
  super().__init__(config)
126
  self.config = config
127
  self.tok_embeddings = nn.Embedding(config.vocab_size, config.d_model)
128
+ self.layers = nn.ModuleList([TransformerBlock(config, layer_idx=i) for i in range(config.n_layers)])
129
  self.norm = RMSNorm(config.d_model, eps=config.norm_eps)
130
  self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
131
 
 
164
  B, T = input_ids.shape
165
  x = self.tok_embeddings(input_ids)
166
 
167
+ # Calculate start position for RoPE
168
+ start_pos = 0
169
+ if past_key_values is not None:
170
+ if hasattr(past_key_values, "get_seq_length"):
171
+ start_pos = past_key_values.get_seq_length()
172
+ elif isinstance(past_key_values, (tuple, list)) and len(past_key_values) > 0 and past_key_values[0] is not None:
173
+ start_pos = past_key_values[0][0].shape[2]
174
 
175
  freqs_cos = self.freqs_cos[start_pos : start_pos + T]
176
  freqs_sin = self.freqs_sin[start_pos : start_pos + T]
177
 
178
+ legacy_kv_caches = []
179
  for i, layer in enumerate(self.layers):
180
+ if hasattr(past_key_values, "update"):
181
+ layer_cache = past_key_values
182
+ elif isinstance(past_key_values, (tuple, list)) and len(past_key_values) > i:
183
+ layer_cache = past_key_values[i]
184
+ else:
185
+ layer_cache = None
186
+
187
+ x, new_cache = layer(x, freqs_cos, freqs_sin, past_key_value=layer_cache)
188
+ if not hasattr(past_key_values, "update"):
189
+ legacy_kv_caches.append(new_cache)
190
 
191
  x = self.norm(x)
192
  logits = self.lm_head(x)
 
195
  if labels is not None:
196
  loss = F.cross_entropy(logits.view(-1, self.config.vocab_size), labels.view(-1), ignore_index=-100)
197
 
 
198
  if use_cache:
199
+ output_cache = past_key_values if hasattr(past_key_values, "update") else tuple(legacy_kv_caches)
 
 
 
200
  else:
201
+ output_cache = None
202
 
203
  if not return_dict:
204
+ return (logits, loss, output_cache)
205
 
206
  return CausalLMOutputWithPast(
207
  loss=loss,
208
  logits=logits,
209
+ past_key_values=output_cache,
210
  )
211
 
212
  def prepare_inputs_for_generation(self, input_ids, past_key_values=None, attention_mask=None, **kwargs):
213
+ past_length = 0
214
+ if past_key_values is not None:
215
+ if hasattr(past_key_values, "get_seq_length"):
216
+ past_length = past_key_values.get_seq_length()
217
+ elif isinstance(past_key_values, (tuple, list)) and len(past_key_values) > 0 and past_key_values[0] is not None:
218
+ past_length = past_key_values[0][0].shape[2]
219
+
220
+ if past_length > 0:
221
  input_ids = input_ids[:, -1:]
222
+
223
  return {
224
  "input_ids": input_ids,
225
  "past_key_values": past_key_values,
226
  "attention_mask": attention_mask,
227
  "use_cache": True,
228
  }