asharrm commited on
Commit
67b0040
Β·
verified Β·
1 Parent(s): 47d9f24

Model card: detailed v1.0 -> v1.1 weight-edit write-up

Browse files
Files changed (1) hide show
  1. README.md +94 -24
README.md CHANGED
@@ -144,34 +144,104 @@ semantic-ID generative retrieval work.
144
  - **Versions in this repo:** `v1.1/` (recommended: `final/` plus the head edit below), `final/` (end of round 8), and the
145
  `pass7/` and `pass6/` checkpoints.
146
 
147
- ## What's new in v1.1
148
 
149
- v1.0 (`final/`) sometimes listed the same song twice in one playlist (5% of tracks, e.g. *Leonard Cohen –
150
- Everybody Knows* three times). We fixed this by **editing the weights directly**, with no extra training:
 
151
 
152
- 1. **Collect:** 400 playlists the model wrote itself, with 239 repeated items and 3,692 fresh ones.
153
- 2. **Correlate:** a linear probe finds where "about to repeat" is most visible. It peaks at layers 16–19.
154
- 3. **Attribute causally:** gradient Γ— activation (attribution patching) scores every MLP neuron and attention head by
155
- how much it raises the log-probability of a *repeated* song address relative to a fresh one.
156
- 4. **Intervene:** 21 candidate edits are scored on held-out playlists against random-unit controls. Switching off
157
- "repeat-promoting" neurons or ablating the probe direction lowered repeats *and* normal picks alike. Boosting the four
158
- strongest **repeat-suppressing heads** (L22 h8, L22 h7, L26 h7, L16 h14) was selective.
159
- 5. **Apply:** multiply those heads' columns in `o_proj` by 2. That is 4 Γ— 128 columns, about 0.03% of the weights.
160
 
161
- | Metric (greedy, 110 prompts) | v1.0 `final/` | **v1.1** |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  |---|---|---|
163
- | Repeated tracks inside a playlist | 5.0% | **1.8%** |
164
- | Song addresses that exist | 99.9% | 99.9% |
165
- | Song name matches its address | 96.6% | **98.0%** |
166
- | Distinct songs across 40 unrelated prompts | 90.9% | 93.0% |
167
- | Overlap with teacher playlists (trained prompts) | 7.2% | 5.6% |
168
-
169
- **Side effect:** when a genre has few memorized songs, v1.1 drifts to a neighbouring style more often instead of
170
- repeating. For example, "banda" gave cumbia and mambo.
171
-
172
- This follows ideas from recent interpretability work: *Neural Networks Are Already Clean* (Cammarata, Goodfire), the
173
- "Evil Qwen" single-neuron steering reproductions (HedwigAI), the copy-suppression heads catalogued by neuron-lens, and
174
- *Sparks of Weight-Space Programming* (Takehi et al., MIT CSAIL).
 
 
 
 
 
 
175
 
176
  ## Evaluation (v1.0 `final/`, greedy, 110 prompts; v1.1 numbers above)
177
 
 
144
  - **Versions in this repo:** `v1.1/` (recommended: `final/` plus the head edit below), `final/` (end of round 8), and the
145
  `pass7/` and `pass6/` checkpoints.
146
 
147
+ ## What's new in v1.1: fixing repeats by editing the weights
148
 
149
+ v1.0 (`final/`) sometimes listed the same song twice in one playlist. About **5% of tracks were repeats**, e.g.
150
+ *Leonard Cohen – Everybody Knows* three times in "dark cabaret heartbreak". The usual fix is more fine-tuning. Instead
151
+ we found the circuit responsible and **edited it directly: no gradient steps, no new data, about 0.03% of the weights**.
152
 
153
+ ### 1. Collect the behaviour
154
+ Greedy-decode 400 playlists from training prompts that the evaluation does not use. Label every list item as
155
+ **repeat** (its 3-token song address already appeared earlier in the list) or **fresh**: 239 repeats and 3,692 fresh.
 
 
 
 
 
156
 
157
+ ### 2. Where is "about to repeat" visible? (correlational)
158
+ At the position that predicts each item's first address token, take the residual stream at every layer. The
159
+ difference of class means gives a direction, scored on a held-out half by Cohen's *d*:
160
+
161
+ | layers | 1–9 | 10–15 | **16–19** | 20–21 | 22–28 |
162
+ |---|---|---|---|---|---|
163
+ | Cohen's *d* | 0.6–1.1 | 0.4–0.95 | **1.4–1.6** | 1.05–1.3 | 0.4–0.9 |
164
+
165
+ The decision is most legible in the middle-late layers. Correlation is not causation, so we went one step further.
166
+
167
+ ### 3. Which units cause it? (attribution patching)
168
+ For each list item, target = log p(the item's 3 address tokens). For every MLP neuron (`down_proj` input) and every
169
+ attention head (its slice of the `o_proj` input), attribution = activation Γ— βˆ‚target/βˆ‚activation, summed over the
170
+ 3 predicting positions. Then:
171
+
172
+ repeat score = mean attribution on **repeated** items βˆ’ mean attribution on **fresh** items
173
+
174
+ The largest scores were *negative*, meaning units that push repeats down. These are **copy-suppression heads** that look
175
+ back at songs already listed and lower their probability:
176
+
177
+ | head | repeat score |
178
+ |---|---|
179
+ | L22 h8 | βˆ’0.068 |
180
+ | L22 h7 | βˆ’0.046 |
181
+ | L26 h7 | βˆ’0.042 |
182
+ | L16 h14 | βˆ’0.040 |
183
+ | (most repeat-promoting: L15 h6) | +0.028 |
184
+
185
+ ### 4. Test edits causally, against controls
186
+ Each candidate edit was applied to a fresh copy of the weights and scored by teacher forcing on held-out playlists
187
+ (eval prompts). Ξ” is the change in mean log-probability of repeated vs. fresh items; we want Ξ”repeat β‰ͺ Ξ”fresh β‰ˆ 0.
188
+
189
+ | edit | Ξ” repeat | Ξ” fresh | |
190
+ |---|---|---|---|
191
+ | 8 / 32 / 128 random neurons β†’ 0 (control) | 0.00 / 0.00 / βˆ’0.03 | 0.00 / 0.00 / βˆ’0.01 | control is flat βœ… |
192
+ | top 8 / 32 / 128 repeat-promoting neurons β†’ 0 | βˆ’0.33 / βˆ’0.91 / βˆ’1.90 | βˆ’0.27 / βˆ’0.65 / βˆ’1.49 | hurts everything ❌ |
193
+ | remove the probe direction (layers 15–19) | βˆ’0.41 | βˆ’0.41 | not selective ❌ |
194
+ | boost top anti-repeat neurons Γ—1.5–2 | βˆ’0.06 to βˆ’0.21 | βˆ’0.03 to βˆ’0.11 | too weak |
195
+ | top 2 / 4 repeat-promoting heads β†’ 0 | βˆ’0.49 / βˆ’0.82 | βˆ’0.26 / βˆ’0.53 | partly selective |
196
+ | **4 copy-suppression heads Γ—1.5** | **βˆ’0.68** | **βˆ’0.25** | selective βœ… |
197
+ | **4 copy-suppression heads Γ—2** | **βˆ’1.64** | **βˆ’0.60** | **chosen** βœ… |
198
+ | 4 copy-suppression heads Γ—3 | βˆ’3.81 | βˆ’1.51 | starts to damage |
199
+
200
+ ### 5. The edit
201
+ ```python
202
+ import torch
203
+ from transformers import AutoModelForCausalLM
204
+ m = AutoModelForCausalLM.from_pretrained("asharrm/juke-1.7b-dev", subfolder="final", torch_dtype=torch.bfloat16)
205
+ hd = m.config.head_dim # 128
206
+ with torch.no_grad():
207
+ for layer, head in [(22, 8), (22, 7), (26, 7), (16, 14)]:
208
+ m.model.layers[layer].self_attn.o_proj.weight[:, head * hd:(head + 1) * hd] *= 2.0
209
+ m.save_pretrained("juke-1.7b-v1.1")
210
+ ```
211
+ That is 4 Γ— 128 columns of `o_proj`: 1.05M of 1.7B weights, about **0.03%**.
212
+
213
+ ### 6. Result (greedy decoding, 110 prompts, real generation)
214
+
215
+ | metric | v1.0 `final/` | Γ—1.5 | **v1.1 (Γ—2)** |
216
+ |---|---|---|---|
217
+ | repeated tracks inside a playlist | 5.0% | 2.9% | **1.8%** |
218
+ | song addresses that exist | 99.9% | 100% | 99.9% |
219
+ | song name matches its address | 96.6% | 97.1% | **98.0%** |
220
+ | distinct songs across 40 unrelated prompts | 90.9% | 91.7% | 93.0% |
221
+ | overlap with teacher playlists (trained prompts) | 7.2% | 5.9% | 5.6% |
222
+
223
+ Before and after:
224
+
225
+ | prompt | v1.0 | v1.1 |
226
  |---|---|---|
227
+ | dark cabaret heartbreak | Leonard Cohen – Everybody Knows Γ—3 | The Dresden Dolls, Nellie McKay, Cold Cave, no repeats |
228
+ | wistful indie rock from the 2000s | The Postal Service – Sleeping In Γ—3 | Jimmy Eat World, Bright Eyes, Death Cab for Cutie, Dashboard Confessional, The Shins… |
229
+ | weird punk songs | The Adverts Γ—2 | Misfits, Bad Brains, Black Flag, Television, Dead Kennedys, The Undertones |
230
+
231
+ **Side effect:** where the model knows few songs in a genre, it now drifts to a neighbouring style more often instead of
232
+ repeating. For example, "banda" gave cumbia and mambo. The edit removes an obstacle; it cannot add songs the model never
233
+ learned, which matches the weight-space-programming finding below.
234
+
235
+ ### Why this worked
236
+ The training data never contained repeats, so the model learned a copy-suppression mechanism. It was simply too quiet,
237
+ and greedy decoding sometimes let a strongly-recalled song win twice. Turning up a mechanism that already exists is a
238
+ targeted fix. Switching off neurons that merely *correlate* with repeats damaged everything.
239
+
240
+ Inspired by: *Neural Networks Are Already Clean* (Cammarata, Goodfire, 2026). The "Evil Qwen" single-neuron reproductions
241
+ (HedwigAI, 2026), where the most active neurons were not the causal ones, so rank by causal attribution and check random
242
+ controls. Copy-suppression heads catalogued in neuron-lens (stdlogits). *Sparks of Weight-Space Programming* (Takehi,
243
+ Teoh, Zhang & Khattab, MIT CSAIL, 2026). Scripts: `repeat_direction.py`, `repeat_attrib.py`, `repeat_edit_test.py`,
244
+ `repeat_apply.py` in the juke repo.
245
 
246
  ## Evaluation (v1.0 `final/`, greedy, 110 prompts; v1.1 numbers above)
247