ThingsAI commited on
Commit
434cb12
·
verified ·
1 Parent(s): 674494c

fix: cast q,k a dtype di v dopo RoPE — identico a train.py

Browse files
Files changed (1) hide show
  1. modeling_quark.py +30 -40
modeling_quark.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Quark language model copia esatta dell'architettura di training.
3
  """
4
  import math
5
  import torch
@@ -10,6 +10,8 @@ from transformers.modeling_outputs import CausalLMOutputWithPast
10
  from .configuration_quark import QuarkConfig
11
 
12
 
 
 
13
  class RMSNorm(nn.Module):
14
  def __init__(self, dim, eps=1e-5):
15
  super().__init__()
@@ -24,16 +26,14 @@ class RMSNorm(nn.Module):
24
  class RotaryEmbedding(nn.Module):
25
  def __init__(self, head_dim, max_seq_len, theta=10_000.0):
26
  super().__init__()
27
- assert head_dim % 2 == 0
28
  inv_freq = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
29
  self.register_buffer("inv_freq", inv_freq, persistent=True)
30
  self._build_cache(max_seq_len)
31
 
32
  def _build_cache(self, seq_len):
33
- device = self.inv_freq.device
34
- t = torch.arange(seq_len, device=device, dtype=self.inv_freq.dtype)
35
- freqs = torch.outer(t, self.inv_freq)
36
- emb = torch.cat([freqs, freqs], dim=-1)
37
  self.register_buffer("cos_cache", emb.cos()[None, None], persistent=False)
38
  self.register_buffer("sin_cache", emb.sin()[None, None], persistent=False)
39
  self._max = seq_len
@@ -49,6 +49,7 @@ class RotaryEmbedding(nn.Module):
49
  self._build_cache(T)
50
  cos = self.cos_cache[:, :, :T, :]
51
  sin = self.sin_cache[:, :, :T, :]
 
52
  q = q * cos + self._rotate_half(q) * sin
53
  k = k * cos + self._rotate_half(k) * sin
54
  return q, k
@@ -57,7 +58,6 @@ class RotaryEmbedding(nn.Module):
57
  class GroupedQueryAttention(nn.Module):
58
  def __init__(self, cfg):
59
  super().__init__()
60
- assert cfg.n_heads % cfg.n_kv_heads == 0
61
  self.n_heads = cfg.n_heads
62
  self.n_kv_heads = cfg.n_kv_heads
63
  self.n_groups = cfg.n_heads // cfg.n_kv_heads
@@ -69,22 +69,21 @@ class GroupedQueryAttention(nn.Module):
69
  self.rope = RotaryEmbedding(cfg.head_dim, cfg.max_seq_len, cfg.rope_theta)
70
  self.drop = cfg.dropout
71
 
72
- def forward(self, x, attention_mask=None, **kwargs):
73
  B, T, _ = x.shape
74
- dtype = x.dtype # salva dtype originale (bfloat16)
75
  q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
76
  k = self.k_proj(x).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
77
  v = self.v_proj(x).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
78
- q, k = self.rope(q, k) # RoPE porta q,k a float32
79
  if self.n_groups > 1:
80
  k = k.repeat_interleave(self.n_groups, dim=1)
81
  v = v.repeat_interleave(self.n_groups, dim=1)
82
- # Porta tutti allo stesso dtype per SDPA
83
- q, k, v = q.to(dtype), k.to(dtype), v.to(dtype)
 
84
  out = F.scaled_dot_product_attention(
85
- q, k, v, attn_mask=None,
86
  dropout_p=self.drop if self.training else 0.0,
87
- is_causal=True,
88
  )
89
  out = out.transpose(1, 2).contiguous().view(B, T, self.n_heads * self.head_dim)
90
  return self.o_proj(out)
@@ -115,20 +114,18 @@ class TransformerBlock(nn.Module):
115
  return x
116
 
117
 
 
 
118
  class QuarkPreTrainedModel(PreTrainedModel):
119
  config_class = QuarkConfig
120
  base_model_prefix = "model"
121
  _keys_to_ignore_on_load_missing = ["lm_head.weight"]
122
- supports_gradient_checkpointing = False
123
 
124
  def _init_weights(self, module):
125
- std = 0.02
126
- if isinstance(module, nn.Linear):
127
- nn.init.normal_(module.weight, 0.0, std)
128
- if module.bias is not None:
129
  nn.init.zeros_(module.bias)
130
- elif isinstance(module, nn.Embedding):
131
- nn.init.normal_(module.weight, 0.0, std)
132
 
133
 
134
  class QuarkForCausalLM(QuarkPreTrainedModel):
@@ -139,25 +136,26 @@ class QuarkForCausalLM(QuarkPreTrainedModel):
139
  self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model)
140
  self.layers = nn.ModuleList([TransformerBlock(config) for _ in range(config.n_layers)])
141
  self.norm = RMSNorm(config.d_model, config.rms_eps)
142
- # lm_head usa embed_tokens.weight (weight tying) — non è un parametro separato
 
143
  self.post_init()
144
 
145
  def get_input_embeddings(self): return self.embed_tokens
146
  def set_input_embeddings(self, v): self.embed_tokens = v
147
- def get_output_embeddings(self): return None
148
- def tie_weights(self, **kwargs): pass
 
149
 
150
  def forward(self, input_ids=None, attention_mask=None, labels=None, **kwargs):
151
  x = self.embed_tokens(input_ids)
152
  for layer in self.layers:
153
  x = layer(x)
154
  x = self.norm(x)
155
- # Weight tying: proiezione finale con la stessa matrice degli embedding
156
- logits = x @ self.embed_tokens.weight.T
157
  loss = None
158
  if labels is not None:
159
  loss = F.cross_entropy(
160
- logits[:, :-1].contiguous().view(-1, self.config.vocab_size),
161
  labels[:, 1:].contiguous().view(-1),
162
  ignore_index=-100,
163
  )
@@ -170,25 +168,17 @@ class QuarkForCausalLM(QuarkPreTrainedModel):
170
  for _ in range(max_new_tokens):
171
  out = self(ctx[:, -self.config.max_seq_len:])
172
  logits = out.logits[0, -1, :].float()
173
- if logits.isnan().any() or logits.isinf().any():
174
- logits = torch.zeros_like(logits)
175
- logits[2] = 1.0 # forza </s>
176
- if temperature <= 0:
177
  token = logits.argmax().view(1, 1)
178
  else:
179
  logits -= logits.max()
180
  logits /= temperature
181
  probs = F.softmax(logits, dim=-1)
182
  sorted_p, sorted_i = torch.sort(probs, descending=True)
183
- cum_p = torch.cumsum(sorted_p, dim=-1)
184
- mask = (cum_p - sorted_p) > top_p
185
- sorted_p[mask] = 0.0
186
- total = sorted_p.sum()
187
- if total <= 0:
188
- token = sorted_i[0].view(1, 1)
189
- else:
190
- sorted_p /= total
191
- token = sorted_i[torch.multinomial(sorted_p, 1)].view(1, 1)
192
  ctx = torch.cat([ctx, token], dim=1)
193
  if eos_token_id is not None and token.item() == eos_token_id:
194
  break
 
1
  """
2
+ Quark-72M wrapper HuggingFace che usa l'architettura originale di training.
3
  """
4
  import math
5
  import torch
 
10
  from .configuration_quark import QuarkConfig
11
 
12
 
13
+ # ── Architettura identica a train.py ─────────────────────────────────────────
14
+
15
  class RMSNorm(nn.Module):
16
  def __init__(self, dim, eps=1e-5):
17
  super().__init__()
 
26
  class RotaryEmbedding(nn.Module):
27
  def __init__(self, head_dim, max_seq_len, theta=10_000.0):
28
  super().__init__()
 
29
  inv_freq = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
30
  self.register_buffer("inv_freq", inv_freq, persistent=True)
31
  self._build_cache(max_seq_len)
32
 
33
  def _build_cache(self, seq_len):
34
+ t = torch.arange(seq_len, device=self.inv_freq.device).float()
35
+ freqs = torch.outer(t, self.inv_freq)
36
+ emb = torch.cat([freqs, freqs], dim=-1)
 
37
  self.register_buffer("cos_cache", emb.cos()[None, None], persistent=False)
38
  self.register_buffer("sin_cache", emb.sin()[None, None], persistent=False)
39
  self._max = seq_len
 
49
  self._build_cache(T)
50
  cos = self.cos_cache[:, :, :T, :]
51
  sin = self.sin_cache[:, :, :T, :]
52
+ # Identico a train.py — nessun cast, broadcast naturale
53
  q = q * cos + self._rotate_half(q) * sin
54
  k = k * cos + self._rotate_half(k) * sin
55
  return q, k
 
58
  class GroupedQueryAttention(nn.Module):
59
  def __init__(self, cfg):
60
  super().__init__()
 
61
  self.n_heads = cfg.n_heads
62
  self.n_kv_heads = cfg.n_kv_heads
63
  self.n_groups = cfg.n_heads // cfg.n_kv_heads
 
69
  self.rope = RotaryEmbedding(cfg.head_dim, cfg.max_seq_len, cfg.rope_theta)
70
  self.drop = cfg.dropout
71
 
72
+ def forward(self, x, **kwargs):
73
  B, T, _ = x.shape
 
74
  q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim).transpose(1, 2)
75
  k = self.k_proj(x).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
76
  v = self.v_proj(x).view(B, T, self.n_kv_heads, self.head_dim).transpose(1, 2)
77
+ q, k = self.rope(q, k)
78
  if self.n_groups > 1:
79
  k = k.repeat_interleave(self.n_groups, dim=1)
80
  v = v.repeat_interleave(self.n_groups, dim=1)
81
+ # Cast uniforme prima di SDPA (q/k possono essere float32 dopo RoPE)
82
+ dtype = v.dtype
83
+ q, k = q.to(dtype), k.to(dtype)
84
  out = F.scaled_dot_product_attention(
85
+ q, k, v, is_causal=True,
86
  dropout_p=self.drop if self.training else 0.0,
 
87
  )
88
  out = out.transpose(1, 2).contiguous().view(B, T, self.n_heads * self.head_dim)
89
  return self.o_proj(out)
 
114
  return x
115
 
116
 
117
+ # ── HuggingFace wrapper ───────────────────────────────────────────────────────
118
+
119
  class QuarkPreTrainedModel(PreTrainedModel):
120
  config_class = QuarkConfig
121
  base_model_prefix = "model"
122
  _keys_to_ignore_on_load_missing = ["lm_head.weight"]
 
123
 
124
  def _init_weights(self, module):
125
+ if isinstance(module, (nn.Linear, nn.Embedding)):
126
+ nn.init.normal_(module.weight, 0.0, 0.02)
127
+ if hasattr(module, "bias") and module.bias is not None:
 
128
  nn.init.zeros_(module.bias)
 
 
129
 
130
 
131
  class QuarkForCausalLM(QuarkPreTrainedModel):
 
136
  self.embed_tokens = nn.Embedding(config.vocab_size, config.d_model)
137
  self.layers = nn.ModuleList([TransformerBlock(config) for _ in range(config.n_layers)])
138
  self.norm = RMSNorm(config.d_model, config.rms_eps)
139
+ self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
140
+ self.lm_head.weight = self.embed_tokens.weight
141
  self.post_init()
142
 
143
  def get_input_embeddings(self): return self.embed_tokens
144
  def set_input_embeddings(self, v): self.embed_tokens = v
145
+ def get_output_embeddings(self): return self.lm_head
146
+ def set_output_embeddings(self, v): self.lm_head = v
147
+ def tie_weights(self, **kwargs): self.lm_head.weight = self.embed_tokens.weight
148
 
149
  def forward(self, input_ids=None, attention_mask=None, labels=None, **kwargs):
150
  x = self.embed_tokens(input_ids)
151
  for layer in self.layers:
152
  x = layer(x)
153
  x = self.norm(x)
154
+ logits = self.lm_head(x)
 
155
  loss = None
156
  if labels is not None:
157
  loss = F.cross_entropy(
158
+ logits[:, :-1].contiguous().view(-1, config.vocab_size),
159
  labels[:, 1:].contiguous().view(-1),
160
  ignore_index=-100,
161
  )
 
168
  for _ in range(max_new_tokens):
169
  out = self(ctx[:, -self.config.max_seq_len:])
170
  logits = out.logits[0, -1, :].float()
171
+ if temperature <= 0 or logits.isnan().any():
 
 
 
172
  token = logits.argmax().view(1, 1)
173
  else:
174
  logits -= logits.max()
175
  logits /= temperature
176
  probs = F.softmax(logits, dim=-1)
177
  sorted_p, sorted_i = torch.sort(probs, descending=True)
178
+ cum_p = torch.cumsum(sorted_p, dim=-1)
179
+ sorted_p[(cum_p - sorted_p) > top_p] = 0.0
180
+ total = sorted_p.sum()
181
+ token = sorted_i[torch.multinomial(sorted_p / (total if total > 0 else 1), 1)].view(1, 1)
 
 
 
 
 
182
  ctx = torch.cat([ctx, token], dim=1)
183
  if eos_token_id is not None and token.item() == eos_token_id:
184
  break