Naphula commited on
Commit
439bda2
·
verified ·
1 Parent(s): f44a139

Upload cosine_magnitude_audit_v2.py

Browse files
Files changed (1) hide show
  1. cosine_magnitude_audit_v2.py +104 -0
cosine_magnitude_audit_v2.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ from safetensors.torch import safe_open
4
+ import yaml
5
+
6
+ # --- CONFIGURATION ---
7
+ YAML_PATH = "B:/24B/C82/mergekit_config.yml"
8
+ FINAL_MERGE_DIR = "B:/24B/C82"
9
+ LAYERS_TO_SCAN = [
10
+ "model.layers.30.mlp.down_proj.weight"
11
+ ]
12
+ # ---------------------
13
+
14
+ def load_tensor(model_dir, tensor_name):
15
+ """Finds and loads a tensor from a directory of safetensors."""
16
+ for file in os.listdir(model_dir):
17
+ if file.endswith(".safetensors"):
18
+ filepath = os.path.join(model_dir, file)
19
+ with safe_open(filepath, framework="pt", device="cpu") as f:
20
+ if tensor_name in f.keys():
21
+ return f.get_tensor(tensor_name).float()
22
+ raise ValueError(f"Tensor {tensor_name} not found in {model_dir}")
23
+
24
+ def get_latent_metrics(tv):
25
+ """Calculates structural metrics of the task vector."""
26
+ # 1. Global Energy (Frobenius Norm)
27
+ f_norm = torch.linalg.norm(tv).item()
28
+
29
+ # 2. Spectral Norm (Intensity of dominant feature)
30
+ # Measures the largest singular value (L2 operator norm)
31
+ s_norm = torch.linalg.norm(tv, ord=2).item()
32
+
33
+ # 3. Stable Rank (Knowledge Breadth / Complexity)
34
+ # Calculation: ||A||_F^2 / ||A||_2^2
35
+ # Higher = more diverse features preserved; Lower = collapsed/overfit
36
+ s_rank = (f_norm**2) / (s_norm**2) if s_norm > 0 else 0
37
+
38
+ return f_norm, s_norm, s_rank
39
+
40
+ def main():
41
+ print("Loading YAML config...")
42
+ with open(YAML_PATH, 'r') as f:
43
+ config = yaml.safe_load(f)
44
+
45
+ base_path = config['base_model']
46
+ donor_paths = [m['model'] for m in config['models']]
47
+
48
+ print(f"\nScanning {len(LAYERS_TO_SCAN)} MLP layers for structural influence...\n")
49
+
50
+ for layer in LAYERS_TO_SCAN:
51
+ print(f"--- Layer: {layer} ---")
52
+ try:
53
+ # Load Base and Final
54
+ base_w = load_tensor(base_path, layer)
55
+ final_w = load_tensor(FINAL_MERGE_DIR, layer)
56
+ final_tv = final_w - base_w
57
+
58
+ # Calculate metrics for the Final Merged Model
59
+ final_f, final_s, final_rk = get_latent_metrics(final_tv)
60
+
61
+ print(f"Final Model Latent Metrics:")
62
+ print(f" Energy (Frobenius): {final_f:.4f}")
63
+ print(f" Intensity (Spectral): {final_s:.4f}")
64
+ print(f" Complexity (S-Rank): {final_rk:.2f}")
65
+ print("")
66
+
67
+ results = []
68
+ for donor in donor_paths:
69
+ donor_w = load_tensor(donor, layer)
70
+ donor_tv = donor_w - base_w
71
+
72
+ # Get structural metrics for donor
73
+ d_f, d_s, d_rk = get_latent_metrics(donor_tv)
74
+
75
+ # Calculate Cosine Similarity (Alignment)
76
+ cos_sim = torch.nn.functional.cosine_similarity(
77
+ final_tv.flatten(), donor_tv.flatten(), dim=0
78
+ ).item()
79
+
80
+ name = donor.split("/")[-1][:40]
81
+ results.append({
82
+ 'name': name,
83
+ 'sim': cos_sim,
84
+ 'energy': d_f,
85
+ 'intens': d_s,
86
+ 'cmplx': d_rk
87
+ })
88
+
89
+ # Sort by highest alignment
90
+ results.sort(key=lambda x: x['sim'], reverse=True)
91
+
92
+ print(f"{'Donor Model':<42} | {'Align':<8} | {'Energy':<8} | {'Intens':<8} | {'Cmplx'}")
93
+ print("-" * 90)
94
+ for r in results:
95
+ # Energy is relative to the final model (e.g. 0.90x)
96
+ rel_energy = r['energy'] / final_f if final_f > 0 else 0
97
+ print(f"{r['name']:<42} | {r['sim']:>7.3f} | {rel_energy:>7.2f}x | {r['intens']:>8.3f} | {r['cmplx']:>6.2f}")
98
+ print("\n")
99
+
100
+ except Exception as e:
101
+ print(f"Skipping layer due to error: {e}")
102
+
103
+ if __name__ == "__main__":
104
+ main()