oopere commited on
Commit
47afdb8
Β·
verified Β·
1 Parent(s): e5522da

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +170 -9
README.md CHANGED
@@ -17,23 +17,184 @@ tags:
17
 
18
  ## Model Description
19
 
20
- This model is a surgically optimized version of **meta-llama/Llama-3.2-3B**, created as part of **Chapter 8** in the book **"Rearchitecting LLMs"**.
21
 
22
  * **Book:** [Rearchitecting LLMs](https://hubs.la/Q040tvtp0)
23
  * **Framework:** [OptiPFair](https://github.com/peremartra/optipfair)
24
  * **Technique:** Attention Optimization (Physical Attention Layer Removal)
25
  * **Chapter:** Chapter 8 - Attention Optimization
 
 
26
 
27
  [![linkedin-profile-banner-martra](https://cdn-uploads.huggingface.co/production/uploads/640f7924f2d7c41a1e9eced1/sa4ivCbm8kk6C9NAPmb-x.jpeg)](https://hubs.la/Q040tvsK0)
28
 
29
- ## Benchmarks
 
 
 
 
 
 
 
 
 
 
30
 
31
- The following table shows the performance of the pruned model (where 3 redundant attention layers were dropped) compared to the baseline (`meta-llama/Llama-3.2-3B`) across several general knowledge benchmarks:
 
 
32
 
33
- | Benchmark | Metric | Baseline Score | Pruned Score |
 
 
 
 
 
 
34
  | :--- | :--- | :--- | :--- |
35
- | **ARC Easy** | acc_norm | 0.7180 | 0.7104 |
36
- | **HellaSwag** | acc_norm | 0.7405 | 0.7274 |
37
- | **LAMBADA OpenAI** | accuracy | 0.6969 | 0.6189 |
38
- | **PIQA** | acc_norm | 0.7813 | 0.7693 |
39
- | **WinoGrande** | accuracy | 0.6961 | 0.6843 |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  ## Model Description
19
 
20
+ This model is a surgically optimized version of **meta-llama/Llama-3.2-3B**, created as part of **Chapter 8** in the book **"Rearchitecting LLMs"**.
21
 
22
  * **Book:** [Rearchitecting LLMs](https://hubs.la/Q040tvtp0)
23
  * **Framework:** [OptiPFair](https://github.com/peremartra/optipfair)
24
  * **Technique:** Attention Optimization (Physical Attention Layer Removal)
25
  * **Chapter:** Chapter 8 - Attention Optimization
26
+ * **Notebook:** [CH08_NB03_Remove_Attention_](https://github.com/peremartra/Rearchitecting-LLMs/blob/main/CH08/CH08_NB03_Remove_Attention_.ipynb)
27
+ * **Paper:** [What Matters in Transformers? Not All Attention is Needed](https://arxiv.org/abs/2406.15786) β€” He et al., 2024
28
 
29
  [![linkedin-profile-banner-martra](https://cdn-uploads.huggingface.co/production/uploads/640f7924f2d7c41a1e9eced1/sa4ivCbm8kk6C9NAPmb-x.jpeg)](https://hubs.la/Q040tvsK0)
30
 
31
+ ---
32
+
33
+ ## Implementation
34
+
35
+ ### How It Works
36
+
37
+ Unlike KV cache quantization, this technique **permanently removes** the least important attention modules from the model architecture. The result is a smaller model β€” fewer parameters, less VRAM, faster inference β€” that can be saved and reloaded without any custom inference engine.
38
+
39
+ The importance of each attention sublayer is measured via **cosine similarity between its input and output**, including the residual connection. A layer whose output is nearly identical to its input is doing very little work and is a strong candidate for removal.
40
+
41
+ The metric, as defined in the paper, is:
42
 
43
+ ```
44
+ S = 1 - CosineSim(X_A, Y_A)
45
+ ```
46
 
47
+ Where `X_A` is the hidden state arriving at the attention sublayer (captured before `input_layernorm`) and `Y_A` is the hidden state after the attention computation and its residual (`X_A + Attention(LayerNorm(X_A))`). Including the residual in the measurement prevents underestimating layers that rely on it to preserve information flow.
48
+
49
+ ### Calibration Data
50
+
51
+ Importance scores are computed over **400 samples** from [Cosmopedia](https://huggingface.co/datasets/HuggingFaceTB/cosmopedia), weighted to cover the same range of tasks as the evaluation benchmarks:
52
+
53
+ | Subset | Weight | Samples | Activates |
54
  | :--- | :--- | :--- | :--- |
55
+ | stories | 0.300 | 120 | Contextual reasoning (hellaswag, winogrande) |
56
+ | web_samples_v2 | 0.200 | 80 | Contextual reasoning |
57
+ | web_samples_v1 | 0.150 | 60 | Contextual reasoning |
58
+ | wikihow | 0.150 | 60 | Procedural understanding (piqa) |
59
+ | openstax | 0.125 | 50 | Academic reasoning (arc_easy) |
60
+ | stanford | 0.075 | 30 | Academic reasoning |
61
+
62
+ ### Measuring Layer Importance
63
+
64
+ Hooks are anchored at two points inside each `LlamaDecoderLayer`:
65
+
66
+ ```python
67
+ def setup_attention_hooks(model):
68
+ hooks = []
69
+ for i, layer in enumerate(model.model.layers):
70
+ # X_A: hidden state before attention transformation
71
+ hooks.append(layer.input_layernorm.register_forward_pre_hook(make_input_hook(i)))
72
+ # Y_A: hidden state after attention + residual
73
+ hooks.append(layer.post_attention_layernorm.register_forward_pre_hook(make_output_hook(i)))
74
+ return hooks, ...
75
+ ```
76
+
77
+ The resulting importance scores for Llama-3.2-3B (ascending β€” lowest = most redundant):
78
+
79
+ ```
80
+ Layer Score
81
+ ------ ----------
82
+ 21 0.006152 ← dropped
83
+ 18 0.006841 ← dropped
84
+ 22 0.007109 ← dropped
85
+ 2 0.007285
86
+ ...
87
+ 1 0.110186
88
+ 0 0.278848 ← most important, never touched
89
+ ```
90
+
91
+ Layers 0 and 1 are clearly the most active and are never candidates for removal. The intermediate region (roughly layers 2–25) clusters near zero. Layers 26 and 27 recover, consistent with their role in consolidating representations before the language model head.
92
+
93
+ ### Physical Deletion
94
+
95
+ The 3 selected layers (18, 21, 22) are physically removed. For each layer, both `self_attn` and `input_layernorm` are deleted and the layer's `forward()` is patched to route hidden states directly to the MLP block:
96
+
97
+ ```python
98
+ def drop_attention_layer(model, layer_idx):
99
+ layer = model.model.layers[layer_idx]
100
+
101
+ # Release attention parameters from memory
102
+ delattr(layer, "self_attn")
103
+ delattr(layer, "input_layernorm")
104
+
105
+ def forward_no_attn(self, hidden_states, ...) -> Tuple[torch.Tensor]:
106
+ # Attention block is skipped β€” hidden states flow through unchanged
107
+ # MLP block: normalize, transform, add residual
108
+ residual = hidden_states
109
+ hidden_states = self.post_attention_layernorm(hidden_states)
110
+ hidden_states = self.mlp(hidden_states)
111
+ hidden_states = residual + hidden_states
112
+ return hidden_states
113
+
114
+ PrunedLayer = type("PrunedDecoderLayer", (type(layer),), {"forward": forward_no_attn})
115
+ layer.__class__ = PrunedLayer
116
+ ```
117
+
118
+ The dropped layer indices are stored in `config.json` so the model can be reloaded correctly:
119
+
120
+ ```json
121
+ "dropped_attn_layers": [18, 21, 22]
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Loading the Model
127
+
128
+ The model uses a custom class (`PrunedLlamaForCausalLM`) that re-applies the attention bypass automatically at load time. A single `trust_remote_code=True` flag is all that's needed:
129
+
130
+ ```python
131
+ from transformers import AutoModelForCausalLM, AutoTokenizer
132
+
133
+ model = AutoModelForCausalLM.from_pretrained(
134
+ "oopere/llama-3.2-3b-attn-drop-3",
135
+ torch_dtype=torch.float16,
136
+ device_map="auto",
137
+ trust_remote_code=True,
138
+ )
139
+ tokenizer = AutoTokenizer.from_pretrained("oopere/llama-3.2-3b-attn-drop-3")
140
+ ```
141
+
142
+ > **Note:** This model was developed and tested on a **Google Colab T4 GPU (free tier)**. Use `torch.float16` on T4; switch to `torch.bfloat16` on Ampere-class GPUs or newer (L4, A100, etc.).
143
+
144
+ ---
145
+
146
+ ## Benchmarks
147
+
148
+ The following table compares the pruned model against the baseline (`meta-llama/Llama-3.2-3B`) on general knowledge benchmarks (0-shot):
149
+
150
+ | Benchmark | Metric | Baseline | Pruned | Ξ” |
151
+ | :--- | :--- | :---: | :---: | :---: |
152
+ | **ARC Easy** | acc_norm | 0.7180 | 0.7104 | -1.06% |
153
+ | **HellaSwag** | acc_norm | 0.7405 | 0.7274 | -1.77% |
154
+ | **LAMBADA OpenAI** | accuracy | 0.6969 | 0.6189 | -11.19% |
155
+ | **PIQA** | acc_norm | 0.7813 | 0.7693 | -1.54% |
156
+ | **WinoGrande** | accuracy | 0.6961 | 0.6843 | -1.70% |
157
+
158
+ ### What the numbers mean
159
+
160
+ Removing 3 attention modules eliminates approximately **75M parameters (~150MB in FP16)**, representing a ~10.7% reduction in dynamic memory growth per generated token.
161
+
162
+ Four of the five benchmarks show contained degradation of **1–2%**. ARC-Easy, HellaSwag, PIQA, and WinoGrande are all multiple-choice or binary-selection tasks: the model receives a context and must pick the correct continuation from a closed set of alternatives. This type of task primarily activates factual reasoning and local semantic coherence. A 1–2% drop is consistent with having removed layers that the importance scores already identified as redundant β€” **the model is still reasoning**.
163
+
164
+ **LAMBADA is a different story.** This benchmark requires predicting the last word of a paragraph from the full preceding context β€” a task that demands generative coherence across several sentences. The 11.2 percentage point drop contrasts sharply with the behavior on all other evaluations.
165
+
166
+ ### The repetition problem
167
+
168
+ The difference becomes immediately visible in free-text generation:
169
+
170
+ **Baseline:**
171
+ ```
172
+ France and the largest city in the country. It is located in the north-central part of the
173
+ country, on the banks of the Seine River. The city is known for its rich history, culture,
174
+ and architecture.
175
+ ```
176
+
177
+ **Pruned model:**
178
+ ```
179
+ France. It is the largest city in France and the second largest city in Europe. The city is
180
+ located on the River Seine in the north of France. Paris is the most visited city in the
181
+ world. It is the most visited city in the world. It is the most visited city in the world.
182
+ ```
183
+
184
+ The pruned model falls into a repetition loop it cannot exit. The same pattern was reproduced with Llama-3.1-8B.
185
+
186
+ The reason is structural: **attention modules do not only transform token information β€” they also participate in suppressing the probability of recently generated tokens**. When several are removed, that suppression weakens and the model tends to reinforce the most probable next token instead of advancing. LAMBADA captures exactly this limitation, which explains why its drop is ten times larger than the rest of the benchmarks.
187
+
188
+ ### When to use this model
189
+
190
+ This technique is **viable when outputs are short and structured** β€” question answering, classification, information extraction, or any task where responses are a few tokens long. It is **problematic for open-ended generation**, where repetition loops degrade output quality significantly.
191
+
192
+ > ⚠️ This is not a neutral optimization. It carries a meaningful trade-off that is worth understanding before applying it in practice.
193
+
194
+ ---
195
+
196
+ ## Intended Use
197
+
198
+ This model is intended as a **learning artifact** for readers of *Rearchitecting LLMs* (Chapter 8 Hands-On Lab). It demonstrates that a non-trivial fraction of attention layers in a modern LLM can be physically removed with surprisingly small benchmark loss β€” and that the real cost only becomes visible in free-text generation. No custom inference stack is required to load or run it.
199
+
200
+ It is not intended for production use.