codemaivanngu commited on
Commit
593092d
·
verified ·
1 Parent(s): 5960155

add padding-trigger ablation for the 4096-cap parity bug

Browse files
Files changed (1) hide show
  1. diag/diagnose_padding_trigger.py +55 -26
diag/diagnose_padding_trigger.py CHANGED
@@ -102,17 +102,6 @@ def main() -> None:
102
  n_r = int(lengths[r])
103
  lone_ids = ids[r:r + 1, :n_r].clone()
104
 
105
- with torch.inference_mode():
106
- ref = model(input_ids=lone_ids.cuda(), use_cache=False).logits[0]
107
-
108
- def forward_row(x, a, positions):
109
- with torch.inference_mode():
110
- out = model(input_ids=x.cuda(),
111
- attention_mask=(a.cuda() if a is not None else None),
112
- position_ids=(positions.cuda() if positions is not None else None),
113
- use_cache=False).logits
114
- return out[r] if out.dim() == 3 else out[0]
115
-
116
  def positions_for(a):
117
  p = a.long().cumsum(-1) - 1
118
  p.masked_fill_(a == 0, 1)
@@ -168,26 +157,66 @@ def main() -> None:
168
  pad_ids[0, :n_r] = ids[r, :n_r]
169
  pad_attn[0, :n_r] = 1
170
 
171
- plans: list[tuple[str, Any, Any, Any]] = [
172
- ("base", ids, attn, pos_stored),
173
- ("base_nopos", ids, attn, None),
174
- ("pad_zero", torch.where(attn.bool(), ids, torch.zeros_like(ids)), attn, pos_stored),
175
- ("attn_prefix", ids, prefix, None),
176
- ("attn_all_ones", ids, torch.ones_like(attn), None),
177
- ("long_only_pad", pad_ids, pad_attn, None),
178
- ("long_only", lone_ids, torch.ones_like(lone_ids), None),
 
 
 
 
 
 
 
 
 
 
 
 
179
  ]
180
  variants: dict[str, dict[str, Any]] = {}
181
- for name, x, a, p in plans:
182
- got = forward_row(x, a, p)
183
- if name == "long_only":
184
- variants[name] = max_logit_delta(got, ref)
185
- else:
186
- variants[name] = max_logit_delta(got, ref)
187
- del got
 
 
188
  torch.cuda.empty_cache()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  print("TRIGGER_VARIANT=" + json.dumps({"variant": name, **variants[name]},
190
  sort_keys=True), flush=True)
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  report["variants"] = variants
193
  ranked = sorted((v["max_abs_dlogit"], k) for k, v in variants.items())
 
102
  n_r = int(lengths[r])
103
  lone_ids = ids[r:r + 1, :n_r].clone()
104
 
 
 
 
 
 
 
 
 
 
 
 
105
  def positions_for(a):
106
  p = a.long().cumsum(-1) - 1
107
  p.masked_fill_(a == 0, 1)
 
157
  pad_ids[0, :n_r] = ids[r, :n_r]
158
  pad_attn[0, :n_r] = 1
159
 
160
+ n_rows = int(ids.shape[0])
161
+ # One reference per row: that row forwarded alone, no mask and no position_ids.
162
+ # This is the semantics SGLang serves, and it is what the fix must reproduce.
163
+ refs: list[Any] = []
164
+ for i in range(n_rows):
165
+ n_i = int(lengths[i])
166
+ with torch.inference_mode():
167
+ refs.append(model(input_ids=ids[i:i + 1, :n_i].cuda(),
168
+ use_cache=False).logits[0])
169
+ torch.cuda.empty_cache()
170
+
171
+ plans: list[tuple[str, Any, Any, Any, list[int]]] = [
172
+ ("base", ids, attn, pos_stored, list(range(n_rows))),
173
+ ("base_nopos", ids, attn, None, list(range(n_rows))),
174
+ ("pad_zero", torch.where(attn.bool(), ids, torch.zeros_like(ids)), attn,
175
+ pos_stored, list(range(n_rows))),
176
+ ("attn_prefix", ids, prefix, None, list(range(n_rows))),
177
+ ("attn_all_ones", ids, torch.ones_like(attn), None, list(range(n_rows))),
178
+ ("long_only_pad", pad_ids, pad_attn, None, [r]),
179
+ ("long_only", lone_ids, torch.ones_like(lone_ids), None, [r]),
180
  ]
181
  variants: dict[str, dict[str, Any]] = {}
182
+ per_variant_row: dict[str, dict[str, Any]] = {}
183
+ for name, x, a, p, row_map in plans:
184
+ with torch.inference_mode():
185
+ out = model(input_ids=x.cuda(),
186
+ attention_mask=(a.cuda() if a is not None else None),
187
+ position_ids=(p.cuda() if p is not None else None),
188
+ use_cache=False).logits
189
+ out3 = out if out.dim() == 3 else out.unsqueeze(0)
190
+ del out
191
  torch.cuda.empty_cache()
192
+ per_variant_row[name] = {}
193
+ for j, capture_row in enumerate(row_map):
194
+ n_i = int(lengths[capture_row])
195
+ d = max_logit_delta(out3[j, :n_i], refs[capture_row])
196
+ per_variant_row[name][str(capture_row)] = d
197
+ print("TRIGGER_VARIANT_ROW=" + json.dumps(
198
+ {"variant": name, "row": capture_row, "length": n_i,
199
+ "max_abs_dlogit": d["max_abs_dlogit"],
200
+ "mean_abs_dlogit": round(d["mean_abs_dlogit"], 6)}, sort_keys=True),
201
+ flush=True)
202
+ del out3
203
+ torch.cuda.empty_cache()
204
+ # Headline = the longest row, which is the one the parity guard trips on.
205
+ variants[name] = per_variant_row[name][str(r)]
206
  print("TRIGGER_VARIANT=" + json.dumps({"variant": name, **variants[name]},
207
  sort_keys=True), flush=True)
208
+ del refs
209
+ torch.cuda.empty_cache()
210
+ report["per_variant_row"] = per_variant_row
211
+ # Does dropping position_ids reproduce the per-row reference for EVERY row?
212
+ fixed = {k: round(v["max_abs_dlogit"], 6)
213
+ for k, v in per_variant_row.get("base_nopos", {}).items()}
214
+ broken = {k: round(v["max_abs_dlogit"], 6)
215
+ for k, v in per_variant_row.get("base", {}).items()}
216
+ report["fix_check"] = {"base_max_per_row": broken, "base_nopos_max_per_row": fixed,
217
+ "fix_removes_the_effect_on_all_rows":
218
+ all(v == 0.0 for v in fixed.values()) if fixed else None}
219
+ print("TRIGGER_FIX_CHECK=" + json.dumps(report["fix_check"], sort_keys=True), flush=True)
220
 
221
  report["variants"] = variants
222
  ranked = sorted((v["max_abs_dlogit"], k) for k, v in variants.items())