dogeplusplus commited on
Commit
20fa206
·
verified ·
1 Parent(s): 482b0d0

Upload KV Tenants DuoAttention Laguna adapter

Browse files
.gitattributes CHANGED
@@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ figures/efficiency_decoding.jpg filter=lfs diff=lfs merge=lfs -text
37
+ figures/efficiency_prefilling.jpg filter=lfs diff=lfs merge=lfs -text
38
+ figures/kv_capacity.jpg filter=lfs diff=lfs merge=lfs -text
39
+ figures/method1.jpg filter=lfs diff=lfs merge=lfs -text
40
+ figures/method2.jpg filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ base_model: poolside/Laguna-XS.2
4
+ tags:
5
+ - laguna
6
+ - duo-attention
7
+ - custom-code
8
+ ---
9
+
10
+ # DuoAttention Laguna Adapter
11
+
12
+ This repository contains the learned DuoAttention attention-head weights and
13
+ custom loading code for `poolside/Laguna-XS.2`. It intentionally does not include
14
+ the full Laguna base-model weights or tokenizer files.
15
+
16
+ Install the optional tokenizer dependencies if they are not already present:
17
+
18
+ ```bash
19
+ pip install sentencepiece tiktoken
20
+ ```
21
+
22
+ Load the tokenizer from the base Laguna model and the patched model from this
23
+ adapter repository:
24
+
25
+ ```python
26
+ import torch
27
+ from transformers import AutoModelForCausalLM, AutoTokenizer
28
+
29
+ repo_id = "<this-repo-id>"
30
+ base_model = "poolside/Laguna-XS.2"
31
+
32
+ tokenizer = AutoTokenizer.from_pretrained(
33
+ base_model,
34
+ trust_remote_code=True,
35
+ token=True,
36
+ )
37
+ model = AutoModelForCausalLM.from_pretrained(
38
+ repo_id,
39
+ trust_remote_code=True,
40
+ token=True,
41
+ torch_dtype="auto",
42
+ device_map="auto",
43
+ )
44
+
45
+ prompt = "The capital of France is"
46
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
47
+ with torch.no_grad():
48
+ generated = model.generate(**inputs, max_new_tokens=32)
49
+ print(tokenizer.decode(generated[0], skip_special_tokens=True))
50
+ ```
51
+
52
+ Use `token=True` after running `hf auth login`, or pass a token string directly
53
+ when loading private or gated repositories.
config.json ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "poolside/Laguna-XS.2",
3
+ "architectures": [
4
+ "DuoLagunaForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "auto_map": {
9
+ "AutoModelForCausalLM": "modeling_duo_laguna.DuoLagunaForCausalLM"
10
+ },
11
+ "bos_token_id": 2,
12
+ "chunk_size_feed_forward": 0,
13
+ "dtype": "bfloat16",
14
+ "duo_attention": {
15
+ "architecture": "laguna",
16
+ "base_config_name_or_path": null,
17
+ "base_model_name_or_path": "poolside/Laguna-XS.2",
18
+ "enabled": true,
19
+ "format_version": 1,
20
+ "full_attention_heads_file": "duo_attention/full_attention_heads.pt",
21
+ "full_attention_heads_tsv_file": "duo_attention/full_attention_heads.tsv",
22
+ "patch_mode": "eval",
23
+ "recent_size": 256,
24
+ "sink_size": 64,
25
+ "training_recent_size": 256,
26
+ "training_sink_size": 64
27
+ },
28
+ "eos_token_id": [
29
+ 2,
30
+ 24
31
+ ],
32
+ "gating": true,
33
+ "head_dim": 128,
34
+ "hidden_act": "silu",
35
+ "hidden_size": 2048,
36
+ "id2label": {
37
+ "0": "LABEL_0",
38
+ "1": "LABEL_1"
39
+ },
40
+ "initializer_range": 0.02,
41
+ "intermediate_size": 8192,
42
+ "is_encoder_decoder": false,
43
+ "label2id": {
44
+ "LABEL_0": 0,
45
+ "LABEL_1": 1
46
+ },
47
+ "layer_types": [
48
+ "full_attention",
49
+ "sliding_attention",
50
+ "sliding_attention",
51
+ "sliding_attention",
52
+ "full_attention",
53
+ "sliding_attention",
54
+ "sliding_attention",
55
+ "sliding_attention",
56
+ "full_attention",
57
+ "sliding_attention",
58
+ "sliding_attention",
59
+ "sliding_attention",
60
+ "full_attention",
61
+ "sliding_attention",
62
+ "sliding_attention",
63
+ "sliding_attention",
64
+ "full_attention",
65
+ "sliding_attention",
66
+ "sliding_attention",
67
+ "sliding_attention",
68
+ "full_attention",
69
+ "sliding_attention",
70
+ "sliding_attention",
71
+ "sliding_attention",
72
+ "full_attention",
73
+ "sliding_attention",
74
+ "sliding_attention",
75
+ "sliding_attention",
76
+ "full_attention",
77
+ "sliding_attention",
78
+ "sliding_attention",
79
+ "sliding_attention",
80
+ "full_attention",
81
+ "sliding_attention",
82
+ "sliding_attention",
83
+ "sliding_attention",
84
+ "full_attention",
85
+ "sliding_attention",
86
+ "sliding_attention",
87
+ "sliding_attention"
88
+ ],
89
+ "max_position_embeddings": 262144,
90
+ "mlp_layer_types": [
91
+ "dense",
92
+ "sparse",
93
+ "sparse",
94
+ "sparse",
95
+ "sparse",
96
+ "sparse",
97
+ "sparse",
98
+ "sparse",
99
+ "sparse",
100
+ "sparse",
101
+ "sparse",
102
+ "sparse",
103
+ "sparse",
104
+ "sparse",
105
+ "sparse",
106
+ "sparse",
107
+ "sparse",
108
+ "sparse",
109
+ "sparse",
110
+ "sparse",
111
+ "sparse",
112
+ "sparse",
113
+ "sparse",
114
+ "sparse",
115
+ "sparse",
116
+ "sparse",
117
+ "sparse",
118
+ "sparse",
119
+ "sparse",
120
+ "sparse",
121
+ "sparse",
122
+ "sparse",
123
+ "sparse",
124
+ "sparse",
125
+ "sparse",
126
+ "sparse",
127
+ "sparse",
128
+ "sparse",
129
+ "sparse",
130
+ "sparse"
131
+ ],
132
+ "model_type": "laguna",
133
+ "moe_apply_router_weight_on_input": false,
134
+ "moe_intermediate_size": 512,
135
+ "moe_routed_scaling_factor": 2.5,
136
+ "moe_router_logit_softcapping": 0.0,
137
+ "num_attention_heads": 48,
138
+ "num_attention_heads_per_layer": [
139
+ 48,
140
+ 64,
141
+ 64,
142
+ 64,
143
+ 48,
144
+ 64,
145
+ 64,
146
+ 64,
147
+ 48,
148
+ 64,
149
+ 64,
150
+ 64,
151
+ 48,
152
+ 64,
153
+ 64,
154
+ 64,
155
+ 48,
156
+ 64,
157
+ 64,
158
+ 64,
159
+ 48,
160
+ 64,
161
+ 64,
162
+ 64,
163
+ 48,
164
+ 64,
165
+ 64,
166
+ 64,
167
+ 48,
168
+ 64,
169
+ 64,
170
+ 64,
171
+ 48,
172
+ 64,
173
+ 64,
174
+ 64,
175
+ 48,
176
+ 64,
177
+ 64,
178
+ 64
179
+ ],
180
+ "num_experts": 256,
181
+ "num_experts_per_tok": 8,
182
+ "num_hidden_layers": 40,
183
+ "num_key_value_heads": 8,
184
+ "output_attentions": false,
185
+ "output_hidden_states": false,
186
+ "output_router_logits": false,
187
+ "pad_token_id": 9,
188
+ "partial_rotary_factor": 0.5,
189
+ "problem_type": null,
190
+ "return_dict": true,
191
+ "rms_norm_eps": 1e-06,
192
+ "rope_parameters": {
193
+ "full_attention": {
194
+ "attention_factor": 1.0,
195
+ "beta_fast": 64.0,
196
+ "beta_slow": 1.0,
197
+ "factor": 64.0,
198
+ "original_max_position_embeddings": 4096,
199
+ "partial_rotary_factor": 0.5,
200
+ "rope_theta": 500000.0,
201
+ "rope_type": "yarn"
202
+ },
203
+ "original_max_position_embeddings": 4096,
204
+ "rope_type": "default",
205
+ "sliding_attention": {
206
+ "partial_rotary_factor": 1.0,
207
+ "rope_theta": 10000.0,
208
+ "rope_type": "default"
209
+ }
210
+ },
211
+ "router_aux_loss_coef": 0.0,
212
+ "shared_expert_intermediate_size": 512,
213
+ "sliding_window": 512,
214
+ "tie_word_embeddings": false,
215
+ "transformers_version": "5.9.0",
216
+ "use_cache": true,
217
+ "vocab_size": 100352
218
+ }
duo_attention/config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architecture": "laguna",
3
+ "base_config_name_or_path": null,
4
+ "base_model_name_or_path": "poolside/Laguna-XS.2",
5
+ "enabled": true,
6
+ "format_version": 1,
7
+ "full_attention_heads_file": "duo_attention/full_attention_heads.pt",
8
+ "full_attention_heads_tsv_file": "duo_attention/full_attention_heads.tsv",
9
+ "patch_mode": "eval",
10
+ "recent_size": 256,
11
+ "sink_size": 64,
12
+ "training_recent_size": 256,
13
+ "training_sink_size": 64
14
+ }
duo_attention/full_attention_heads.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7bf485ba3f39e94d04660d87faddabebdf6a70820f7f472c4f5d2171ec32b94b
3
+ size 2525
duo_attention/full_attention_heads.tsv ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 8.984375000000000000e-01 5.468750000000000000e-01 9.882812500000000000e-01 1.000000000000000000e+00 8.906250000000000000e-01 1.000000000000000000e+00 9.921875000000000000e-01 9.882812500000000000e-01
2
+ 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 9.687500000000000000e-01 9.960937500000000000e-01 1.000000000000000000e+00
3
+ 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 9.179687500000000000e-01 7.070312500000000000e-01 8.554687500000000000e-01 9.765625000000000000e-01
4
+ 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 9.570312500000000000e-01 1.000000000000000000e+00 9.726562500000000000e-01 1.000000000000000000e+00 9.648437500000000000e-01
5
+ 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 8.242187500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00
6
+ 1.000000000000000000e+00 1.000000000000000000e+00 8.437500000000000000e-01 9.960937500000000000e-01 1.000000000000000000e+00 9.101562500000000000e-01 1.000000000000000000e+00 8.945312500000000000e-01
7
+ 8.085937500000000000e-01 9.765625000000000000e-01 3.652343750000000000e-01 1.000000000000000000e+00 9.765625000000000000e-01 1.000000000000000000e+00 3.359375000000000000e-01 1.000000000000000000e+00
8
+ 1.000000000000000000e+00 1.000000000000000000e+00 1.007812500000000000e+00 9.609375000000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 9.609375000000000000e-01
9
+ 1.000000000000000000e+00 9.375000000000000000e-01 1.000000000000000000e+00 8.593750000000000000e-01 9.570312500000000000e-01 9.843750000000000000e-01 9.882812500000000000e-01 7.187500000000000000e-01
10
+ 8.632812500000000000e-01 7.187500000000000000e-01 1.000000000000000000e+00 7.226562500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00
11
+ 7.109375000000000000e-01 1.000000000000000000e+00 8.750000000000000000e-01 1.000000000000000000e+00 9.179687500000000000e-01 8.906250000000000000e-01 9.414062500000000000e-01 1.000000000000000000e+00
12
+ 1.000000000000000000e+00 7.187500000000000000e-01 6.132812500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 9.023437500000000000e-01 1.000000000000000000e+00 9.882812500000000000e-01
13
+ 1.000000000000000000e+00 8.945312500000000000e-01 9.960937500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 6.875000000000000000e-01
14
+ 4.140625000000000000e-01 7.812500000000000000e-01 1.007812500000000000e+00 9.492187500000000000e-01 9.062500000000000000e-01 5.703125000000000000e-01 5.351562500000000000e-01 8.945312500000000000e-01
15
+ 1.000000000000000000e+00 9.609375000000000000e-01 1.000000000000000000e+00 3.906250000000000000e-01 6.718750000000000000e-01 7.617187500000000000e-02 5.585937500000000000e-01 1.000000000000000000e+00
16
+ 1.000000000000000000e+00 8.085937500000000000e-01 1.031494140625000000e-02 1.000000000000000000e+00 9.921875000000000000e-01 3.984375000000000000e-01 1.640625000000000000e-01 1.867675781250000000e-02
17
+ 9.921875000000000000e-01 1.000000000000000000e+00 2.558593750000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 9.882812500000000000e-01 8.242187500000000000e-01 9.375000000000000000e-01
18
+ 1.000000000000000000e+00 3.398437500000000000e-01 4.570312500000000000e-01 2.578125000000000000e-01 9.609375000000000000e-01 9.375000000000000000e-01 6.757812500000000000e-01 8.906250000000000000e-01
19
+ 1.000000000000000000e+00 7.421875000000000000e-01 4.824218750000000000e-01 2.792968750000000000e-01 4.467773437500000000e-02 3.574218750000000000e-01 8.945312500000000000e-01 8.320312500000000000e-01
20
+ -1.564025878906250000e-04 4.218750000000000000e-01 6.054687500000000000e-01 1.000000000000000000e+00 9.375000000000000000e-01 9.882812500000000000e-01 4.746093750000000000e-01 2.880859375000000000e-02
21
+ 9.882812500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 8.437500000000000000e-01 2.197265625000000000e-01
22
+ 2.558593750000000000e-01 8.320312500000000000e-01 7.812500000000000000e-01 4.414062500000000000e-01 1.000000000000000000e+00 6.640625000000000000e-01 1.000000000000000000e+00 4.570312500000000000e-01
23
+ 7.421875000000000000e-01 5.625000000000000000e-01 9.375000000000000000e-01 3.417968750000000000e-01 9.335937500000000000e-01 6.445312500000000000e-01 1.708984375000000000e-01 4.863281250000000000e-01
24
+ 5.468750000000000000e-01 4.062500000000000000e-01 3.496093750000000000e-01 5.419921875000000000e-02 4.843750000000000000e-01 1.060485839843750000e-03 -1.953125000000000000e-03 3.593750000000000000e-01
25
+ 1.000000000000000000e+00 9.140625000000000000e-01 1.007812500000000000e+00 1.007812500000000000e+00 1.007812500000000000e+00 3.710937500000000000e-01 1.007812500000000000e+00 9.257812500000000000e-01
26
+ 2.431640625000000000e-01 9.179687500000000000e-01 9.296875000000000000e-01 1.000000000000000000e+00 6.796875000000000000e-01 4.726562500000000000e-01 3.847656250000000000e-01 1.000000000000000000e+00
27
+ 9.609375000000000000e-01 9.921875000000000000e-01 5.664062500000000000e-01 1.000000000000000000e+00 7.031250000000000000e-01 3.125000000000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00
28
+ 1.079101562500000000e-01 5.507812500000000000e-01 2.138671875000000000e-01 -1.899719238281250000e-03 9.216308593750000000e-03 8.867187500000000000e-01 2.187500000000000000e-01 2.324218750000000000e-01
29
+ 1.007812500000000000e+00 8.515625000000000000e-01 1.007812500000000000e+00 1.000000000000000000e+00 9.023437500000000000e-01 1.000000000000000000e+00 8.007812500000000000e-01 1.000000000000000000e+00
30
+ 5.507812500000000000e-01 4.414062500000000000e-01 9.687500000000000000e-01 8.593750000000000000e-01 8.437500000000000000e-01 9.335937500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00
31
+ 1.000000000000000000e+00 1.777343750000000000e-01 8.476562500000000000e-01 9.257812500000000000e-01 1.000000000000000000e+00 6.640625000000000000e-01 7.617187500000000000e-01 1.000000000000000000e+00
32
+ 9.179687500000000000e-02 3.769531250000000000e-01 7.304687500000000000e-01 7.070312500000000000e-01 9.843750000000000000e-01 8.398437500000000000e-01 1.007812500000000000e+00 9.453125000000000000e-01
33
+ 1.007812500000000000e+00 9.335937500000000000e-01 9.023437500000000000e-01 1.000000000000000000e+00 1.000000000000000000e+00 -3.967285156250000000e-03 1.000000000000000000e+00 1.007812500000000000e+00
34
+ 1.000000000000000000e+00 1.000000000000000000e+00 9.843750000000000000e-01 9.726562500000000000e-01 9.335937500000000000e-01 5.000000000000000000e-01 5.781250000000000000e-01 9.804687500000000000e-01
35
+ 1.007812500000000000e+00 9.804687500000000000e-01 9.453125000000000000e-01 9.726562500000000000e-01 4.667968750000000000e-01 9.960937500000000000e-01 8.085937500000000000e-01 1.000000000000000000e+00
36
+ 7.617187500000000000e-01 3.847656250000000000e-01 8.710937500000000000e-01 8.593750000000000000e-01 5.117187500000000000e-01 7.500000000000000000e-01 1.007812500000000000e+00 5.625000000000000000e-01
37
+ 9.023437500000000000e-01 9.179687500000000000e-01 8.632812500000000000e-01 1.007812500000000000e+00 9.765625000000000000e-01 6.914062500000000000e-01 5.351562500000000000e-01 9.765625000000000000e-01
38
+ 8.125000000000000000e-01 3.847656250000000000e-01 9.453125000000000000e-01 8.906250000000000000e-01 7.890625000000000000e-01 8.203125000000000000e-01 9.140625000000000000e-01 8.593750000000000000e-01
39
+ 7.148437500000000000e-01 9.179687500000000000e-01 9.414062500000000000e-01 1.000000000000000000e+00 6.367187500000000000e-01 8.164062500000000000e-01 1.007812500000000000e+00 1.000000000000000000e+00
40
+ 1.000000000000000000e+00 5.312500000000000000e-01 8.476562500000000000e-01 6.250000000000000000e-01 4.785156250000000000e-01 1.007812500000000000e+00 9.375000000000000000e-01 1.007812500000000000e+00
duo_laguna_remote.py ADDED
@@ -0,0 +1,448 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import types
2
+ from typing import Optional, Tuple
3
+
4
+ import torch
5
+ import torch.nn.functional as F
6
+ from transformers.modeling_outputs import MoeCausalLMOutputWithPast, MoeModelOutputWithPast
7
+ from transformers.models.laguna.modeling_laguna import apply_rotary_pos_emb
8
+
9
+
10
+ try:
11
+ from flash_attn import flash_attn_func
12
+ except ImportError:
13
+
14
+ def flash_attn_func(
15
+ query_states,
16
+ key_states,
17
+ value_states,
18
+ dropout_p=0.0,
19
+ softmax_scale=None,
20
+ causal=False,
21
+ **kwargs,
22
+ ):
23
+ if key_states.shape[2] != query_states.shape[2]:
24
+ repeat = query_states.shape[2] // key_states.shape[2]
25
+ key_states = key_states.repeat_interleave(repeat, dim=2)
26
+ value_states = value_states.repeat_interleave(repeat, dim=2)
27
+
28
+ scale = softmax_scale or query_states.shape[-1] ** -0.5
29
+ attn_weights = torch.einsum("bqhd,bkhd->bhqk", query_states, key_states) * scale
30
+ if causal:
31
+ q_len = query_states.shape[1]
32
+ kv_len = key_states.shape[1]
33
+ causal_mask = torch.ones(
34
+ q_len, kv_len, dtype=torch.bool, device=query_states.device
35
+ ).triu(kv_len - q_len + 1)
36
+ attn_weights = attn_weights.masked_fill(
37
+ causal_mask[None, None], float("-inf")
38
+ )
39
+ attn_weights = torch.softmax(attn_weights, dim=-1, dtype=torch.float32).to(
40
+ query_states.dtype
41
+ )
42
+ if dropout_p:
43
+ attn_weights = torch.nn.functional.dropout(attn_weights, p=dropout_p)
44
+ return torch.einsum("bhqk,bkhd->bqhd", attn_weights, value_states)
45
+
46
+
47
+ @torch.no_grad()
48
+ def reorder_linear_weights(linear_module, full_attention_heads, repeat_num, reorder_channel):
49
+ full_attention_heads = torch.repeat_interleave(
50
+ full_attention_heads, repeats=repeat_num
51
+ ).to(linear_module.weight.device)
52
+ full_attn_mask = full_attention_heads > 0.5
53
+ if reorder_channel == "in":
54
+ reordered_weight = torch.cat(
55
+ [
56
+ linear_module.weight.data[:, full_attn_mask],
57
+ linear_module.weight.data[:, ~full_attn_mask],
58
+ ],
59
+ dim=1,
60
+ )
61
+ else:
62
+ reordered_weight = torch.cat(
63
+ [
64
+ linear_module.weight.data[full_attn_mask, :],
65
+ linear_module.weight.data[~full_attn_mask, :],
66
+ ],
67
+ dim=0,
68
+ )
69
+ linear_module.weight.data = reordered_weight
70
+ if linear_module.bias is not None:
71
+ linear_module.bias.data = torch.cat(
72
+ [
73
+ linear_module.bias.data[full_attn_mask],
74
+ linear_module.bias.data[~full_attn_mask],
75
+ ],
76
+ dim=0,
77
+ )
78
+ return linear_module
79
+
80
+
81
+ @torch.no_grad()
82
+ def reorder_full_attn_heads(full_attention_heads):
83
+ full_attn_mask = full_attention_heads > 0.5
84
+ num_full_attn_heads = full_attn_mask.sum().item()
85
+ full_attention_heads[:num_full_attn_heads] = 1
86
+ full_attention_heads[num_full_attn_heads:] = 0
87
+ return full_attention_heads
88
+
89
+
90
+ def _num_key_value_heads(module):
91
+ return getattr(module, "num_key_value_heads", module.config.num_key_value_heads)
92
+
93
+
94
+ def _shape_qkv(module, hidden_states):
95
+ bsz, q_len, _ = hidden_states.size()
96
+ num_key_value_heads = _num_key_value_heads(module)
97
+ query_states = module.q_proj(hidden_states).view(
98
+ bsz, q_len, module.num_heads, module.head_dim
99
+ )
100
+ key_states = module.k_proj(hidden_states).view(
101
+ bsz, q_len, num_key_value_heads, module.head_dim
102
+ )
103
+ value_states = module.v_proj(hidden_states).view(
104
+ bsz, q_len, num_key_value_heads, module.head_dim
105
+ )
106
+ return module.q_norm(query_states), module.k_norm(key_states), value_states
107
+
108
+
109
+ def _apply_gate(module, attn_output, hidden_states):
110
+ input_shape = hidden_states.shape[:-1]
111
+ gate = F.softplus(module.g_proj(hidden_states).float()).to(attn_output.dtype)
112
+ attn_output = attn_output.reshape(*input_shape, module.num_heads, module.head_dim)
113
+ attn_output = attn_output * gate.unsqueeze(-1)
114
+ return attn_output.reshape(*input_shape, module.num_heads * module.head_dim)
115
+
116
+
117
+ def laguna_duo_attention_forward(
118
+ self,
119
+ hidden_states: torch.Tensor,
120
+ attention_mask: Optional[torch.Tensor] = None,
121
+ position_ids: Optional[torch.LongTensor] = None,
122
+ position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
123
+ past_key_value: Optional[Tuple[torch.Tensor]] = None,
124
+ output_attentions: bool = False,
125
+ use_cache: bool = False,
126
+ **kwargs,
127
+ ):
128
+ bsz, q_len, _ = hidden_states.size()
129
+ query_states, key_states, value_states = _shape_qkv(self, hidden_states)
130
+
131
+ kv_seq_len = key_states.shape[1]
132
+ if past_key_value is not None:
133
+ kv_seq_len += past_key_value[0].shape[2]
134
+
135
+ if position_embeddings is None:
136
+ raise ValueError("Duo Laguna requires position_embeddings")
137
+ query_states, key_states = apply_rotary_pos_emb(
138
+ query_states,
139
+ key_states,
140
+ *position_embeddings,
141
+ unsqueeze_dim=2,
142
+ )
143
+
144
+ if not hasattr(self, "full_attn_head_mask") or self.full_attn_head_mask is None:
145
+ self.full_attn_head_mask = self.full_attention_heads > 0.5
146
+ self.num_full_attn_head = self.full_attn_head_mask.sum().item()
147
+ self.num_streaming_attn_head = _num_key_value_heads(self) - self.num_full_attn_head
148
+ self.num_full_query_head = self.num_full_attn_head * self.num_key_value_groups
149
+ self.num_streaming_query_head = self.num_heads - self.num_full_query_head
150
+
151
+ full_key_states = key_states[:, :, : self.num_full_attn_head, :]
152
+ full_value_states = value_states[:, :, : self.num_full_attn_head, :]
153
+ streaming_key_states = key_states[:, :, self.num_full_attn_head :, :]
154
+ streaming_value_states = value_states[:, :, self.num_full_attn_head :, :]
155
+
156
+ if past_key_value is not None:
157
+ past_full_kv = past_key_value[0].transpose(1, 2)
158
+ past_streaming_kv = past_key_value[1].transpose(1, 2)
159
+ full_key_states = torch.cat([past_full_kv[:bsz], full_key_states], dim=1)
160
+ full_value_states = torch.cat([past_full_kv[bsz:], full_value_states], dim=1)
161
+ streaming_key_states = torch.cat(
162
+ [past_streaming_kv[:bsz], streaming_key_states], dim=1
163
+ )
164
+ streaming_value_states = torch.cat(
165
+ [past_streaming_kv[bsz:], streaming_value_states], dim=1
166
+ )
167
+
168
+ if q_len == kv_seq_len:
169
+ attn_output = flash_attn_func(
170
+ query_states, key_states, value_states, causal=True, dropout_p=0.0
171
+ )
172
+ else:
173
+ full_attn_output = None
174
+ streaming_attn_output = None
175
+ if self.num_full_attn_head > 0:
176
+ full_attn_output = flash_attn_func(
177
+ query_states[:, :, : self.num_full_query_head, :],
178
+ full_key_states,
179
+ full_value_states,
180
+ causal=True,
181
+ dropout_p=0.0,
182
+ )
183
+ if self.num_streaming_attn_head > 0:
184
+ streaming_attn_output = flash_attn_func(
185
+ query_states[:, :, self.num_full_query_head :, :],
186
+ streaming_key_states,
187
+ streaming_value_states,
188
+ causal=True,
189
+ dropout_p=0.0,
190
+ )
191
+ if full_attn_output is None:
192
+ attn_output = streaming_attn_output
193
+ elif streaming_attn_output is None:
194
+ attn_output = full_attn_output
195
+ else:
196
+ attn_output = torch.cat([full_attn_output, streaming_attn_output], dim=2)
197
+
198
+ attn_output = self.o_proj(_apply_gate(self, attn_output, hidden_states))
199
+
200
+ if streaming_key_states.shape[1] > self.recent_size + self.sink_size:
201
+ recent_key_states = streaming_key_states[:, -self.recent_size :, :, :].clone()
202
+ streaming_key_states[:, self.sink_size : self.sink_size + self.recent_size].copy_(
203
+ recent_key_states
204
+ )
205
+ streaming_key_states = streaming_key_states[:, : self.sink_size + self.recent_size]
206
+
207
+ recent_value_states = streaming_value_states[:, -self.recent_size :, :, :].clone()
208
+ streaming_value_states[
209
+ :, self.sink_size : self.sink_size + self.recent_size
210
+ ].copy_(recent_value_states)
211
+ streaming_value_states = streaming_value_states[
212
+ :, : self.sink_size + self.recent_size
213
+ ]
214
+
215
+ past_key_value = (
216
+ (
217
+ torch.cat([full_key_states, full_value_states], dim=0).transpose(1, 2),
218
+ torch.cat([streaming_key_states, streaming_value_states], dim=0).transpose(
219
+ 1, 2
220
+ ),
221
+ )
222
+ if use_cache
223
+ else None
224
+ )
225
+ return attn_output, None, past_key_value
226
+
227
+
228
+ def laguna_for_causal_lm_forward(
229
+ self,
230
+ input_ids=None,
231
+ attention_mask=None,
232
+ position_ids=None,
233
+ past_key_values=None,
234
+ inputs_embeds=None,
235
+ labels=None,
236
+ use_cache=None,
237
+ output_attentions=None,
238
+ output_hidden_states=None,
239
+ return_dict=None,
240
+ logits_to_keep=0,
241
+ **kwargs,
242
+ ):
243
+ output_hidden_states = (
244
+ output_hidden_states
245
+ if output_hidden_states is not None
246
+ else self.config.output_hidden_states
247
+ )
248
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
249
+ outputs = self.model(
250
+ input_ids=input_ids,
251
+ attention_mask=attention_mask,
252
+ position_ids=position_ids,
253
+ past_key_values=past_key_values,
254
+ inputs_embeds=inputs_embeds,
255
+ use_cache=use_cache,
256
+ output_attentions=output_attentions,
257
+ output_hidden_states=output_hidden_states,
258
+ return_dict=return_dict,
259
+ **kwargs,
260
+ )
261
+ hidden_states = outputs[0]
262
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
263
+ logits = self.lm_head(hidden_states[:, slice_indices if self.training else slice(-1, None), :])
264
+ loss = None
265
+ if labels is not None:
266
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
267
+ if not return_dict:
268
+ output = (logits,) + outputs[1:]
269
+ return (loss,) + output if loss is not None else output
270
+ return MoeCausalLMOutputWithPast(
271
+ loss=loss,
272
+ logits=logits,
273
+ past_key_values=outputs.past_key_values,
274
+ hidden_states=outputs.hidden_states,
275
+ attentions=outputs.attentions,
276
+ router_logits=None,
277
+ )
278
+
279
+
280
+ def laguna_model_forward(
281
+ self,
282
+ input_ids=None,
283
+ attention_mask=None,
284
+ position_ids=None,
285
+ past_key_values=None,
286
+ inputs_embeds=None,
287
+ use_cache=None,
288
+ output_attentions=None,
289
+ output_hidden_states=None,
290
+ return_dict=None,
291
+ **kwargs,
292
+ ):
293
+ output_attentions = (
294
+ output_attentions
295
+ if output_attentions is not None
296
+ else self.config.output_attentions
297
+ )
298
+ output_hidden_states = (
299
+ output_hidden_states
300
+ if output_hidden_states is not None
301
+ else self.config.output_hidden_states
302
+ )
303
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
304
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
305
+
306
+ if input_ids is not None and inputs_embeds is not None:
307
+ raise ValueError("You cannot specify both input_ids and inputs_embeds")
308
+ if inputs_embeds is None:
309
+ inputs_embeds = self.embed_tokens(input_ids)
310
+ batch_size, seq_length, _ = inputs_embeds.shape
311
+
312
+ past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0
313
+ if position_ids is None:
314
+ position_ids = torch.arange(
315
+ past_key_values_length,
316
+ seq_length + past_key_values_length,
317
+ dtype=torch.long,
318
+ device=inputs_embeds.device,
319
+ ).unsqueeze(0)
320
+ else:
321
+ position_ids = position_ids.view(-1, seq_length).long()
322
+
323
+ hidden_states = inputs_embeds
324
+ all_hidden_states = () if output_hidden_states else None
325
+ all_self_attns = () if output_attentions else None
326
+ next_decoder_cache = () if use_cache else None
327
+
328
+ position_embeddings = {}
329
+ for layer_type in set(self.config.layer_types):
330
+ position_embeddings[layer_type] = self.rotary_emb(hidden_states, position_ids, layer_type)
331
+
332
+ for idx, decoder_layer in enumerate(self.layers):
333
+ if output_hidden_states:
334
+ all_hidden_states += (hidden_states,)
335
+ past_key_value = past_key_values[idx] if past_key_values is not None else None
336
+ layer_outputs = decoder_layer(
337
+ hidden_states,
338
+ attention_mask=None,
339
+ position_ids=position_ids,
340
+ past_key_value=past_key_value,
341
+ output_attentions=output_attentions,
342
+ use_cache=use_cache,
343
+ position_embeddings=position_embeddings[self.config.layer_types[idx]],
344
+ )
345
+ hidden_states = layer_outputs[0]
346
+ if use_cache:
347
+ next_decoder_cache += (layer_outputs[2 if output_attentions else 1],)
348
+ if output_attentions:
349
+ all_self_attns += (layer_outputs[1],)
350
+
351
+ hidden_states = self.norm(hidden_states)
352
+ if output_hidden_states:
353
+ all_hidden_states += (hidden_states,)
354
+
355
+ next_cache = next_decoder_cache if use_cache else None
356
+ if not return_dict:
357
+ return tuple(
358
+ v
359
+ for v in [hidden_states, next_cache, all_hidden_states, all_self_attns]
360
+ if v is not None
361
+ )
362
+ return MoeModelOutputWithPast(
363
+ last_hidden_state=hidden_states,
364
+ past_key_values=next_cache,
365
+ hidden_states=all_hidden_states,
366
+ attentions=all_self_attns,
367
+ router_logits=None,
368
+ )
369
+
370
+
371
+ def laguna_decoder_layer_forward(
372
+ self,
373
+ hidden_states,
374
+ attention_mask=None,
375
+ position_ids=None,
376
+ past_key_value=None,
377
+ output_attentions=False,
378
+ use_cache=False,
379
+ position_embeddings=None,
380
+ **kwargs,
381
+ ):
382
+ residual = hidden_states
383
+ hidden_states = self.input_layernorm(hidden_states)
384
+ hidden_states, self_attn_weights, present_key_value = self.self_attn(
385
+ hidden_states=hidden_states,
386
+ attention_mask=attention_mask,
387
+ position_ids=position_ids,
388
+ position_embeddings=position_embeddings,
389
+ past_key_value=past_key_value,
390
+ output_attentions=output_attentions,
391
+ use_cache=use_cache,
392
+ )
393
+ hidden_states = residual + hidden_states
394
+ residual = hidden_states
395
+ hidden_states = self.post_attention_layernorm(hidden_states)
396
+ hidden_states = self.mlp(hidden_states)
397
+ hidden_states = residual + hidden_states
398
+
399
+ outputs = (hidden_states,)
400
+ if output_attentions:
401
+ outputs += (self_attn_weights,)
402
+ if use_cache:
403
+ outputs += (present_key_value,)
404
+ return outputs
405
+
406
+
407
+ def enable_duo_laguna_eval(model, full_attention_heads, sink_size, recent_size):
408
+ model.model.forward = types.MethodType(laguna_model_forward, model.model)
409
+ for layer in model.model.layers:
410
+ layer.forward = types.MethodType(laguna_decoder_layer_forward, layer)
411
+
412
+ device = next(model.parameters()).device
413
+ dtype = next(model.parameters()).dtype
414
+ for idx, layer in enumerate(model.model.layers):
415
+ module = layer.self_attn
416
+ module.num_key_value_heads = _num_key_value_heads(module)
417
+ layer_full_attention_heads = torch.as_tensor(
418
+ full_attention_heads[idx], device=device, dtype=dtype
419
+ )
420
+ module.forward = types.MethodType(laguna_duo_attention_forward, module)
421
+ module.q_proj = reorder_linear_weights(
422
+ module.q_proj,
423
+ layer_full_attention_heads,
424
+ module.num_key_value_groups * module.head_dim,
425
+ "out",
426
+ )
427
+ module.k_proj = reorder_linear_weights(
428
+ module.k_proj, layer_full_attention_heads, module.head_dim, "out"
429
+ )
430
+ module.v_proj = reorder_linear_weights(
431
+ module.v_proj, layer_full_attention_heads, module.head_dim, "out"
432
+ )
433
+ module.g_proj = reorder_linear_weights(
434
+ module.g_proj, layer_full_attention_heads, module.num_key_value_groups, "out"
435
+ )
436
+ module.o_proj = reorder_linear_weights(
437
+ module.o_proj,
438
+ layer_full_attention_heads,
439
+ module.num_key_value_groups * module.head_dim,
440
+ "in",
441
+ )
442
+ layer_full_attention_heads = reorder_full_attn_heads(layer_full_attention_heads)
443
+ module.sink_size = sink_size
444
+ module.recent_size = recent_size
445
+ module.register_buffer("full_attention_heads", layer_full_attention_heads)
446
+
447
+ model.forward = types.MethodType(laguna_for_causal_lm_forward, model)
448
+ return model
figures/efficiency_decoding.jpg ADDED

Git LFS Details

  • SHA256: b424d80f195e5d4f94f818f71d07b152949c0398391af1bc6bfb7a43022343a4
  • Pointer size: 131 Bytes
  • Size of remote file: 554 kB
figures/efficiency_prefilling.jpg ADDED

Git LFS Details

  • SHA256: 90dd8638686982ca90800bc0efc5a2c47011ac74fb21b3953676d24518a460e3
  • Pointer size: 131 Bytes
  • Size of remote file: 569 kB
figures/kv_capacity.jpg ADDED

Git LFS Details

  • SHA256: 315ceacf89ab283fa594d0154c29c2c98edc7d6a20fab7fdf3e19c6e1ea01101
  • Pointer size: 131 Bytes
  • Size of remote file: 145 kB
figures/laguna_mixed_kv_reduction_pct.png ADDED
figures/laguna_optimized_gate_values_booksum.png ADDED
figures/method1.jpg ADDED

Git LFS Details

  • SHA256: e7fcbc66e850adccb346d3dac2498ea88cd36a0b23a2c9c87056bc4fed1b360d
  • Pointer size: 131 Bytes
  • Size of remote file: 281 kB
figures/method2.jpg ADDED

Git LFS Details

  • SHA256: c3e524dcc83cd25615a3e3713a7cbda4fdcce4a06f2025c77597cab9ec5239f6
  • Pointer size: 131 Bytes
  • Size of remote file: 272 kB
modeling_duo_laguna.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+
4
+ import torch
5
+ from huggingface_hub import hf_hub_download
6
+ from transformers.models.laguna.modeling_laguna import LagunaForCausalLM
7
+
8
+ from .duo_laguna_remote import enable_duo_laguna_eval
9
+
10
+
11
+ def _load_repo_json(pretrained_model_name_or_path, filename, revision=None):
12
+ if os.path.isdir(pretrained_model_name_or_path):
13
+ path = os.path.join(pretrained_model_name_or_path, filename)
14
+ else:
15
+ path = hf_hub_download(
16
+ repo_id=pretrained_model_name_or_path,
17
+ filename=filename,
18
+ revision=revision,
19
+ )
20
+ with open(path) as f:
21
+ return json.load(f)
22
+
23
+
24
+ def _load_duo_tensor(pretrained_model_name_or_path, filename, revision=None):
25
+ if os.path.isdir(pretrained_model_name_or_path):
26
+ path = os.path.join(pretrained_model_name_or_path, filename)
27
+ else:
28
+ path = hf_hub_download(
29
+ repo_id=pretrained_model_name_or_path,
30
+ filename=filename,
31
+ revision=revision,
32
+ )
33
+ return torch.load(path, map_location="cpu", weights_only=True)
34
+
35
+
36
+ class DuoLagunaForCausalLM(LagunaForCausalLM):
37
+ @classmethod
38
+ def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
39
+ duo_attention = kwargs.pop("duo_attention", True)
40
+ duo_sink_size = kwargs.pop("duo_sink_size", None)
41
+ duo_recent_size = kwargs.pop("duo_recent_size", None)
42
+ duo_heads_file = kwargs.pop("duo_heads_file", None)
43
+ revision = kwargs.get("revision")
44
+ config_dict = _load_repo_json(
45
+ pretrained_model_name_or_path,
46
+ "config.json",
47
+ revision=revision,
48
+ )
49
+ duo_config = config_dict.get("duo_attention")
50
+ base_model_name_or_path = kwargs.pop("duo_base_model_name_or_path", None)
51
+ if duo_config is not None:
52
+ base_model_name_or_path = (
53
+ base_model_name_or_path
54
+ or duo_config.get("base_model_name_or_path")
55
+ or duo_config.get("base_model")
56
+ )
57
+ base_revision = kwargs.pop("duo_base_revision", None)
58
+ if duo_config is not None:
59
+ base_revision = base_revision or duo_config.get("base_model_revision")
60
+
61
+ load_path = base_model_name_or_path or pretrained_model_name_or_path
62
+ if base_revision is not None:
63
+ kwargs["revision"] = base_revision
64
+
65
+ model = super().from_pretrained(
66
+ load_path,
67
+ *model_args,
68
+ **kwargs,
69
+ )
70
+ if base_revision is not None and revision is not None:
71
+ kwargs["revision"] = revision
72
+
73
+ if not duo_attention:
74
+ return model
75
+
76
+ if duo_config is None:
77
+ duo_config = getattr(model.config, "duo_attention", None)
78
+ if duo_config is None:
79
+ raise ValueError(
80
+ "This repository does not define config.duo_attention; "
81
+ "reload with duo_attention=False to use the unpatched Laguna model."
82
+ )
83
+
84
+ full_attention_heads = _load_duo_tensor(
85
+ pretrained_model_name_or_path,
86
+ duo_heads_file or duo_config["full_attention_heads_file"],
87
+ revision=revision,
88
+ )
89
+ sink_size = duo_sink_size or duo_config["sink_size"]
90
+ recent_size = duo_recent_size or duo_config["recent_size"]
91
+
92
+ enable_duo_laguna_eval(
93
+ model,
94
+ full_attention_heads,
95
+ sink_size=sink_size,
96
+ recent_size=recent_size,
97
+ )
98
+ model.duo_attention_config = {
99
+ **duo_config,
100
+ "sink_size": sink_size,
101
+ "recent_size": recent_size,
102
+ }
103
+ return model
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ torch
2
+ transformers>=5.9.0
3
+ huggingface_hub
4
+ numpy