2"""Weight delta analysis: base vs fine-tuned checkpoint (LLM)."""
4from __future__
import annotations
7from collections
import defaultdict
8from pathlib
import Path
17_LAYER_RE = re.compile(
r"(?:^|\.)(?:layers?|layer|block)\.?(\d+)(?:\.|$)", re.I)
19_DEFAULT_LORA_ALPHA = 16.0
20_SMOKE_LORA_PATH = Path.home() /
".aquin" /
"smoke" /
"weight-diff-lora.pt"
24 m = _LAYER_RE.search(key.replace(
"_",
"."))
25 return int(m.group(1))
if m
else -1
30 for tag
in (
"q_proj",
"k_proj",
"v_proj",
"o_proj",
"gate_proj",
"up_proj",
"down_proj",
"query",
"key",
"value"):
33 if "mlp" in kl
and "gate" in kl:
35 if "mlp" in kl
and "down" in kl:
41 parts = key.split(
".")
42 return parts[-2]
if len(parts) >= 2
else parts[-1]
46 """Tiny LoRA state_dict so desktop smoke can run without a real fine-tune."""
47 dest = _SMOKE_LORA_PATH
50 dest.parent.mkdir(parents=
True, exist_ok=
True)
51 r, d = _DEFAULT_LORA_R, 32
53 "model.layers.0.self_attn.q_proj.lora_A": torch.randn(r, d) * 0.05,
54 "model.layers.0.self_attn.q_proj.lora_B": torch.randn(d, r) * 0.05,
55 "model.layers.1.self_attn.v_proj.lora_A": torch.randn(r, d) * 0.05,
56 "model.layers.1.self_attn.v_proj.lora_B": torch.randn(d, r) * 0.05,
58 torch.save(state, dest)
63 return any(
"lora_a" in k.lower()
or "lora_b" in k.lower()
for k
in state)
72 base_norm: float |
None =
None,
74 l2 = float(delta.norm().item())
75 rel = (l2 / max(base_norm, 1e-9))
if base_norm
is not None and base_norm > 1e-9
else 0.0
76 stable, nuclear = _matrix_ranks(delta)
81 "delta_l2": round(l2, 6),
82 "delta_l2_relative": round(rel, 6),
83 "delta_stable_rank": stable,
84 "delta_nuclear_ratio": nuclear,
88def _layer_profile(matrices: list[dict[str, Any]]) -> list[dict[str, Any]]:
89 totals: dict[int, float] = defaultdict(float)
90 counts: dict[int, int] = defaultdict(int)
92 layer = int(row[
"layer"])
95 totals[layer] += float(row[
"delta_l2"])
100 "delta_l2": round(totals[layer], 6),
101 "n_matrices": counts[layer],
103 for layer
in sorted(totals)
111 checkpoint_name: str,
112 checkpoint_path: str,
114 matrices: list[dict[str, Any]],
115 step: int |
None =
None,
117 sorted_m = sorted(matrices, key=
lambda x: x[
"delta_l2"], reverse=
True)
118 total_l2 = round(sum(m[
"delta_l2"]
for m
in matrices), 6)
119 max_l2 = round(max((m[
"delta_l2"]
for m
in matrices), default=0.0), 6)
121 round(sum(m[
"delta_stable_rank"]
for m
in matrices) / len(matrices), 4)
126 "type":
"weightDiff",
127 "baseModelId": model_id,
128 "ftCheckpointName": checkpoint_name,
129 "checkpointPath": checkpoint_path,
131 "deltaMode": delta_mode,
132 "trainingStep": step,
133 "nMatrices": len(matrices),
134 "totalDeltaL2": total_l2,
135 "maxDeltaL2": max_l2,
136 "meanDeltaStableRank": mean_stable,
138 "topChanged": sorted_m[:25],
139 "matrices": sorted_m,
143def _iter_tl_matrix_pairs(tl_base: Any, tl_ft: Any) -> list[tuple[int, str, str, torch.Tensor, torch.Tensor]]:
144 n_layers = int(getattr(tl_base.cfg,
"n_layers", 0)
or len(tl_base.blocks))
145 pairs: list[tuple[int, str, str, torch.Tensor, torch.Tensor]] = []
146 for layer
in range(n_layers):
147 block_b = tl_base.blocks[layer]
148 block_f = tl_ft.blocks[layer]
150 attn_f = block_f.attn
153 specs: list[tuple[str, torch.Tensor, torch.Tensor]] = [
154 (
"Q", attn.W_Q, attn_f.W_Q),
155 (
"K", attn.W_K, attn_f.W_K),
156 (
"V", attn.W_V, attn_f.W_V),
157 (
"O", attn.W_O, attn_f.W_O),
158 (
"MLP_up", mlp_b.W_in, mlp_f.W_in),
159 (
"MLP_down", mlp_b.W_out, mlp_f.W_out),
161 if hasattr(mlp_b,
"W_gate"):
162 specs.append((
"MLP_gate", mlp_b.W_gate, mlp_f.W_gate))
163 for name, wb, wf
in specs:
164 pairs.append((layer, name, f
"blocks.{layer}.{name}", wb.detach(), wf.detach()))
170 checkpoint_path: str | Path,
172 checkpoint_name: str =
"checkpoint",
174 from transformers
import AutoModelForCausalLM
179 short = resolve_model_id(model_id)
180 cfg = get_config(short)
181 state, step = load_checkpoint_state(checkpoint_path)
186 checkpoint_name=checkpoint_name,
187 checkpoint_path=str(checkpoint_path),
191 hf_name = cfg[
"hf_name"]
192 trust = bool(cfg.get(
"trust_remote_code",
False))
193 base_model = AutoModelForCausalLM.from_pretrained(
195 torch_dtype=torch.float32,
197 low_cpu_mem_usage=
True,
198 trust_remote_code=trust,
200 base_sd = {k: v.detach().float().cpu()
for k, v
in base_model.state_dict().items()}
203 matrices: list[dict[str, Any]] = []
204 for key, ft_w
in state.items():
205 base_w = base_sd.get(key)
206 if base_w
is None or not isinstance(ft_w, torch.Tensor):
208 wf = ft_w.detach().float().cpu()
209 if base_w.shape != wf.shape
or base_w.ndim < 2:
214 base_norm = float(_to_2d(base_w).norm().item())
227 checkpoint_name=checkpoint_name,
228 checkpoint_path=str(checkpoint_path),
229 delta_mode=
"hf_state_dict",
237 state_dict: dict[str, Any],
239 checkpoint_name: str =
"checkpoint",
240 checkpoint_path: str =
"",
241 step: int |
None =
None,
242 lora_r: int = _DEFAULT_LORA_R,
243 lora_alpha: float = _DEFAULT_LORA_ALPHA,
245 pairs: dict[str, dict[str, torch.Tensor]] = {}
246 for key, tensor
in state_dict.items():
249 prefix = key.split(
".lora_A")[0].split(
".lora_a")[0]
250 pairs.setdefault(prefix, {})[
"A"] = tensor.float()
251 elif ".lora_b" in kl:
252 prefix = key.split(
".lora_B")[0].split(
".lora_b")[0]
253 pairs.setdefault(prefix, {})[
"B"] = tensor.float()
255 scale = lora_alpha / max(lora_r, 1)
256 matrices: list[dict[str, Any]] = []
257 for prefix, ab
in pairs.items():
260 if a
is None or b
is None:
262 if b.ndim == 2
and a.ndim == 2:
263 delta = (b @ a) * scale
265 delta = (b.reshape(-1, 1) @ a.reshape(1, -1)) * scale
281 checkpoint_name=checkpoint_name,
282 checkpoint_path=checkpoint_path,
283 delta_mode=
"lora_effective",
291 checkpoint_path: str | Path,
293 checkpoint_name: str |
None =
None,
297 ckpt = Path(checkpoint_path)
298 if not ckpt.exists():
299 raise FileNotFoundError(f
"Checkpoint not found: {ckpt}")
301 name = checkpoint_name
or ckpt.stem
302 short = resolve_model_id(model_id)
309 model_id = args.get(
"model_id")
or get_active_model_id()
or "llama-3.2-1b"
310 checkpoint = args.get(
"checkpoint")
311 raw = str(checkpoint
or "").strip()
312 if not raw
or raw.lower()
in (
"none",
"null",
"default",
"-"):
316 model_id = resolve_model_id(str(model_id))
317 except ValueError
as exc:
318 return {
"error": str(exc)}
324 checkpoint_name=args.get(
"name"),
326 except Exception
as exc:
327 return {
"error": str(exc)}
dict[str, Any] _matrix_entry(*, int layer, str matrix, str module, torch.Tensor delta, float|None base_norm=None)
int _layer_from_key(str key)
Path ensure_smoke_lora_checkpoint()
bool _has_lora_keys(dict[str, Any] state)
list[dict[str, Any]] _layer_profile(list[dict[str, Any]] matrices)
str _matrix_label_from_key(str key)
dict[str, Any] _finalize_payload(*, str model_id, str mode, str checkpoint_name, str checkpoint_path, str delta_mode, list[dict[str, Any]] matrices, int|None step=None)
list[tuple[int, str, str, torch.Tensor, torch.Tensor]] _iter_tl_matrix_pairs(Any tl_base, Any tl_ft)
dict[str, Any] run_weight_diff(str model_id, str|Path checkpoint_path, *, str|None checkpoint_name=None)
dict[str, Any] run_llm_lora_weight_diff(str model_id, dict[str, Any] state_dict, *, str checkpoint_name="checkpoint", str checkpoint_path="", int|None step=None, int lora_r=_DEFAULT_LORA_R, float lora_alpha=_DEFAULT_LORA_ALPHA)
dict[str, Any] run_weight_diff_from_args(dict[str, Any] args)
dict[str, Any] run_llm_hf_weight_diff(str model_id, str|Path checkpoint_path, *, str checkpoint_name="checkpoint")