CompressedGemma commited on
Commit
9303d37
Β·
verified Β·
1 Parent(s): 262cc7b

Experimental

Browse files
Files changed (1) hide show
  1. generate_imatrix.py +110 -5
generate_imatrix.py CHANGED
@@ -1,6 +1,6 @@
1
  #!/usr/bin/env python3
2
  """
3
- HExState Importance Matrix Generator β€” HPC-Enhanced iMatrix from GGUF
4
 
5
  Runs transformer forward passes over calibration text to collect per-channel
6
  E[xΒ²] activation statistics, then uses HPC triality BP to propagate importance
@@ -147,6 +147,7 @@ class GGUFModel:
147
  'vocab_size': self.kv.get(f'{arch}.vocab_size', 0),
148
  'rms_eps': self.kv.get(f'{arch}.attention.layer_norm_rms_epsilon', 1e-6),
149
  'rope_base': self.kv.get(f'{arch}.rope.freq_base', 10000.0),
 
150
  }
151
 
152
  def get_tensor_f32(self, name):
@@ -342,9 +343,21 @@ def softmax(x, axis=-1):
342
  e = np.exp(x - x_max)
343
  return e / np.sum(e, axis=axis, keepdims=True)
344
 
 
 
 
 
345
  def gelu(x):
 
346
  return 0.5 * x * (1.0 + np.tanh(np.sqrt(2.0 / np.pi) * (x + 0.044715 * x**3)))
347
 
 
 
 
 
 
 
 
348
 
349
  class TransformerRunner:
350
  """Minimal Gemma transformer for importance collection."""
@@ -354,6 +367,7 @@ class TransformerRunner:
354
  self.cfg = config
355
  self.verbose = verbose
356
  self.head_dim = config['n_embd'] // config['n_head']
 
357
 
358
  # Importance accumulators: tensor_name β†’ (sum_x2, count)
359
  self.importance = {}
@@ -438,8 +452,16 @@ class TransformerRunner:
438
  scale = 1.0 / np.sqrt(head_dim)
439
  attn = np.matmul(q_t, k_t.transpose(0, 2, 1)) * scale # [n_head, seq, seq]
440
 
441
- # Causal mask
442
  mask = np.triu(np.full((seq_len, seq_len), -1e9, dtype=np.float32), k=1)
 
 
 
 
 
 
 
 
443
  attn = attn + mask[np.newaxis, :, :]
444
  attn = softmax(attn, axis=-1)
445
 
@@ -466,7 +488,7 @@ class TransformerRunner:
466
  self._record(f'{pfx}.ffn_gate.weight', normed_ff)
467
  self._record(f'{pfx}.ffn_up.weight', normed_ff)
468
 
469
- gate_out = gelu(normed_ff @ gate_w.T)
470
  up_out = normed_ff @ up_w.T
471
  ff_mid = gate_out * up_out
472
 
@@ -499,7 +521,7 @@ class TransformerRunner:
499
  self._record(f'{pfx}.ffn_gate.{exp_id}.weight', exp_input)
500
  self._record(f'{pfx}.ffn_up.{exp_id}.weight', exp_input)
501
 
502
- g = gelu(exp_input @ ew_gate.T)
503
  u = exp_input @ ew_up.T
504
  mid = g * u
505
  self._record(f'{pfx}.ffn_down.{exp_id}.weight', mid)
@@ -515,6 +537,81 @@ class TransformerRunner:
515
 
516
  return hidden
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  def forward(self, token_ids):
519
  """Full forward pass, collecting importance statistics."""
520
  cfg = self.cfg
@@ -532,7 +629,15 @@ class TransformerRunner:
532
 
533
  # Process each layer
534
  for layer_idx in range(cfg['n_layers']):
535
- hidden = self.forward_layer(hidden, layer_idx, cos_f, sin_f)
 
 
 
 
 
 
 
 
536
  if self.verbose and (layer_idx + 1) % 4 == 0:
537
  print(f" Layer {layer_idx + 1}/{cfg['n_layers']}", end='\r')
538
 
 
1
  #!/usr/bin/env python3
2
  """
3
+ HexState Importance Matrix Generator β€” HPC-Enhanced iMatrix from GGUF
4
 
5
  Runs transformer forward passes over calibration text to collect per-channel
6
  E[xΒ²] activation statistics, then uses HPC triality BP to propagate importance
 
147
  'vocab_size': self.kv.get(f'{arch}.vocab_size', 0),
148
  'rms_eps': self.kv.get(f'{arch}.attention.layer_norm_rms_epsilon', 1e-6),
149
  'rope_base': self.kv.get(f'{arch}.rope.freq_base', 10000.0),
150
+ 'swa_window': self.kv.get(f'{arch}.attention.sliding_window', 0),
151
  }
152
 
153
  def get_tensor_f32(self, name):
 
343
  e = np.exp(x - x_max)
344
  return e / np.sum(e, axis=axis, keepdims=True)
345
 
346
+ def silu(x):
347
+ """SiLU / Swish activation β€” used by LLaMA, Mistral, Qwen, DeepSeek."""
348
+ return x * (1.0 / (1.0 + np.exp(-np.clip(x, -88, 88))))
349
+
350
  def gelu(x):
351
+ """GELU activation β€” used by Gemma, GPT-2."""
352
  return 0.5 * x * (1.0 + np.tanh(np.sqrt(2.0 / np.pi) * (x + 0.044715 * x**3)))
353
 
354
+ # Architecture β†’ activation function mapping
355
+ ACTIVATION_MAP = {
356
+ 'llama': silu, 'mistral': silu, 'qwen2': silu, 'qwen2moe': silu,
357
+ 'phi3': silu, 'falcon': silu, 'deepseek': silu, 'deepseek2': silu,
358
+ 'gemma': gelu, 'gemma2': gelu, 'gpt2': gelu,
359
+ }
360
+
361
 
362
  class TransformerRunner:
363
  """Minimal Gemma transformer for importance collection."""
 
367
  self.cfg = config
368
  self.verbose = verbose
369
  self.head_dim = config['n_embd'] // config['n_head']
370
+ self.act_fn = ACTIVATION_MAP.get(config['arch'], silu)
371
 
372
  # Importance accumulators: tensor_name β†’ (sum_x2, count)
373
  self.importance = {}
 
452
  scale = 1.0 / np.sqrt(head_dim)
453
  attn = np.matmul(q_t, k_t.transpose(0, 2, 1)) * scale # [n_head, seq, seq]
454
 
455
+ # Causal mask (with optional sliding window)
456
  mask = np.triu(np.full((seq_len, seq_len), -1e9, dtype=np.float32), k=1)
457
+ swa = cfg.get('swa_window', 0)
458
+ if swa and swa > 0:
459
+ # Sliding window: mask out positions beyond the window
460
+ for i in range(seq_len):
461
+ for j in range(max(0, i - swa), i):
462
+ pass # already 0 (visible)
463
+ for j in range(0, max(0, i - swa)):
464
+ mask[i, j] = -1e9
465
  attn = attn + mask[np.newaxis, :, :]
466
  attn = softmax(attn, axis=-1)
467
 
 
488
  self._record(f'{pfx}.ffn_gate.weight', normed_ff)
489
  self._record(f'{pfx}.ffn_up.weight', normed_ff)
490
 
491
+ gate_out = self.act_fn(normed_ff @ gate_w.T)
492
  up_out = normed_ff @ up_w.T
493
  ff_mid = gate_out * up_out
494
 
 
521
  self._record(f'{pfx}.ffn_gate.{exp_id}.weight', exp_input)
522
  self._record(f'{pfx}.ffn_up.{exp_id}.weight', exp_input)
523
 
524
+ g = self.act_fn(exp_input @ ew_gate.T)
525
  u = exp_input @ ew_up.T
526
  mid = g * u
527
  self._record(f'{pfx}.ffn_down.{exp_id}.weight', mid)
 
537
 
538
  return hidden
539
 
540
+ def forward_linear_attn_layer(self, hidden, layer_idx):
541
+ """Forward pass through a DeltaNet (gated linear attention) layer.
542
+
543
+ Used by Qwen 3.5/3.6 for ~75% of layers. Records importance stats
544
+ for all SSM projection weights.
545
+ """
546
+ pfx = self._layer_prefix(layer_idx)
547
+ cfg = self.cfg
548
+ seq_len = hidden.shape[0]
549
+
550
+ # ── Attention norm ──
551
+ attn_norm_w = self._get_weight(f'{pfx}.attn_norm.weight')
552
+ if attn_norm_w is None:
553
+ return hidden
554
+ normed = rms_norm(hidden, attn_norm_w, cfg['rms_eps'])
555
+
556
+ # ── DeltaNet projections ──
557
+ qkv_w = self._get_weight(f'{pfx}.ssm_in_qkv.weight')
558
+ z_w = self._get_weight(f'{pfx}.ssm_in_z.weight')
559
+ a_w = self._get_weight(f'{pfx}.ssm_in_a.weight')
560
+ b_w = self._get_weight(f'{pfx}.ssm_in_b.weight')
561
+ out_w = self._get_weight(f'{pfx}.ssm_out.weight')
562
+
563
+ if qkv_w is None or out_w is None:
564
+ return hidden
565
+
566
+ # Record importance on input activations
567
+ self._record(f'{pfx}.ssm_in_qkv.weight', normed)
568
+ if z_w is not None:
569
+ self._record(f'{pfx}.ssm_in_z.weight', normed)
570
+ if a_w is not None:
571
+ self._record(f'{pfx}.ssm_in_a.weight', normed)
572
+ if b_w is not None:
573
+ self._record(f'{pfx}.ssm_in_b.weight', normed)
574
+
575
+ # Approximate forward: project through QKV and output
576
+ # (Full DeltaNet recurrence is complex; for importance collection
577
+ # we just need the activation magnitudes at each projection)
578
+ qkv = normed @ qkv_w.T
579
+
580
+ # For importance: record output projection input
581
+ # Use qkv as a proxy for the recurrent state output
582
+ n_out = out_w.shape[1] if out_w.ndim >= 2 else hidden.shape[-1]
583
+ if qkv.shape[-1] >= n_out:
584
+ out_input = qkv[:, :n_out]
585
+ else:
586
+ out_input = qkv
587
+ self._record(f'{pfx}.ssm_out.weight', out_input)
588
+
589
+ attn_out = out_input @ out_w.T
590
+ hidden = hidden + attn_out
591
+
592
+ # ── FFN (same as standard transformer) ──
593
+ ffn_norm_w = self._get_weight(f'{pfx}.ffn_norm.weight')
594
+ if ffn_norm_w is None:
595
+ return hidden
596
+
597
+ normed_ff = rms_norm(hidden, ffn_norm_w, cfg['rms_eps'])
598
+
599
+ gate_w = self._get_weight(f'{pfx}.ffn_gate.weight')
600
+ up_w = self._get_weight(f'{pfx}.ffn_up.weight')
601
+ down_w = self._get_weight(f'{pfx}.ffn_down.weight')
602
+
603
+ if gate_w is not None and up_w is not None and down_w is not None:
604
+ self._record(f'{pfx}.ffn_gate.weight', normed_ff)
605
+ self._record(f'{pfx}.ffn_up.weight', normed_ff)
606
+ gate_out = self.act_fn(normed_ff @ gate_w.T)
607
+ up_out = normed_ff @ up_w.T
608
+ ff_mid = gate_out * up_out
609
+ self._record(f'{pfx}.ffn_down.weight', ff_mid)
610
+ ff_out = ff_mid @ down_w.T
611
+ hidden = hidden + ff_out
612
+
613
+ return hidden
614
+
615
  def forward(self, token_ids):
616
  """Full forward pass, collecting importance statistics."""
617
  cfg = self.cfg
 
629
 
630
  # Process each layer
631
  for layer_idx in range(cfg['n_layers']):
632
+ # Check if this layer has DeltaNet tensors (Qwen 3.6 hybrid)
633
+ pfx = f"blk.{layer_idx}"
634
+ has_linear_attn = f'{pfx}.ssm_in_qkv.weight' in self.model.tensor_infos
635
+ has_full_attn = f'{pfx}.attn_q.weight' in self.model.tensor_infos
636
+
637
+ if has_linear_attn and not has_full_attn:
638
+ hidden = self.forward_linear_attn_layer(hidden, layer_idx)
639
+ else:
640
+ hidden = self.forward_layer(hidden, layer_idx, cos_f, sin_f)
641
  if self.verbose and (layer_idx + 1) % 4 == 0:
642
  print(f" Layer {layer_idx + 1}/{cfg['n_layers']}", end='\r')
643