zhan1206 commited on
Commit
488ee46
·
1 Parent(s): c59037a

v16-hotfix: fix kv_head_dim bug, add incremental gen test

Browse files

- Fix GQA kv_head_dim: was hidden_size//num_kv_heads (wrong), now equals
head_dim (correct for standard GQA). This caused v_to_hidden_proj input
dimension mismatch with expanded V tensor.
- Add tests/test_incremental_gen.py for verifying N6 RoPE position_ids fix
- Incremental generation verified: prefill (1,10,1000) -> step1 (1,1,1000)
-> step2 (1,1,1000) all correct shapes
- All 12 tests pass

models/sbla_attention.py CHANGED
@@ -81,7 +81,7 @@ class SBLAttention(nn.Module):
81
  self.block_size = block_size
82
  self.latent_dim = latent_dim
83
  self.head_dim = hidden_size // num_heads
84
- self.kv_head_dim = hidden_size // self.num_key_value_heads
85
  self.window_size = window_size or block_size # 默认窗口=块大小
86
  self.mode = mode
87
 
 
81
  self.block_size = block_size
82
  self.latent_dim = latent_dim
83
  self.head_dim = hidden_size // num_heads
84
+ self.kv_head_dim = self.head_dim # GQA: KV heads share same head_dim as Q heads
85
  self.window_size = window_size or block_size # 默认窗口=块大小
86
  self.mode = mode
87
 
tests/test_incremental_gen.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Quick incremental generation test to verify N6 (RoPE position_ids) fix."""
2
+
3
+ import sys
4
+ import os
5
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6
+
7
+ import torch
8
+ from models.fusion_model import FusionConfig, FusionModel
9
+
10
+ config = FusionConfig(
11
+ vocab_size=1000,
12
+ hidden_size=256,
13
+ num_hidden_layers=2,
14
+ num_attention_heads=4,
15
+ num_key_value_heads=2,
16
+ intermediate_size=512,
17
+ block_size=8,
18
+ latent_dim=16,
19
+ window_size=64,
20
+ )
21
+
22
+ model = FusionModel(config)
23
+ model.eval()
24
+
25
+ input_ids = torch.randint(0, 1000, (1, 10))
26
+
27
+ # Prefill
28
+ with torch.no_grad():
29
+ outputs = model(input_ids=input_ids, use_cache=True)
30
+ logits_prefill = outputs.logits
31
+ past_kv = outputs.past_key_values
32
+
33
+ print(f"Prefill logits shape: {logits_prefill.shape}") # (1, 10, 1000)
34
+
35
+ # Incremental step 1
36
+ next_token = logits_prefill[:, -1, :].argmax(dim=-1, keepdim=True) # (1, 1)
37
+ with torch.no_grad():
38
+ outputs_inc = model(input_ids=next_token, past_key_values=past_kv, use_cache=True)
39
+ logits_inc = outputs_inc.logits
40
+ past_kv2 = outputs_inc.past_key_values
41
+
42
+ print(f"Incremental step 1 logits shape: {logits_inc.shape}") # should be (1, 1, 1000)
43
+
44
+ # Incremental step 2
45
+ next_token2 = logits_inc[:, -1, :].argmax(dim=-1, keepdim=True)
46
+ with torch.no_grad():
47
+ outputs_inc2 = model(input_ids=next_token2, past_key_values=past_kv2, use_cache=True)
48
+ logits_inc2 = outputs_inc2.logits
49
+
50
+ print(f"Incremental step 2 logits shape: {logits_inc2.shape}") # should be (1, 1, 1000)
51
+
52
+ # Verify shapes are correct (N6 would have caused seq_len to expand)
53
+ assert logits_prefill.shape == (1, 10, 1000), f"Prefill shape wrong: {logits_prefill.shape}"
54
+ assert logits_inc.shape == (1, 1, 1000), f"Step 1 shape wrong: {logits_inc.shape}"
55
+ assert logits_inc2.shape == (1, 1, 1000), f"Step 2 shape wrong: {logits_inc2.shape}"
56
+
57
+ print("\nAll assertions passed! N6 fix verified - incremental generation works correctly.")