AQIT 0.1.0
Loading...
Searching...
No Matches
check_weights_check.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2"""`aquin check-weights --check` — save JSON + diagram to the current working directory."""
3
4from __future__ import annotations
5
6import json
7from datetime import datetime, timezone
8from pathlib import Path
9from typing import Any
10
11_JSON_NAME = "check-weights-check.json"
12_PNG_NAME = "check-weights-check.png"
13
14_STATUS_COLORS = {
15 "high_risk": "#f87171",
16 "suspicious": "#fbbf24",
17 "clean": "#78716c",
19
20
22 result: dict[str, Any],
23 *,
24 tool_name: str | None,
25 cwd: str | Path,
26) -> tuple[Path, Path]:
27 cwd = Path(cwd)
28 json_path = cwd / _JSON_NAME
29 png_path = cwd / _PNG_NAME
30
31 payload = {
32 "saved_at": datetime.now(timezone.utc).isoformat(),
33 "tool": tool_name,
34 **result,
35 }
36 json_path.write_text(json.dumps(payload, indent=2, default=str), encoding="utf-8")
37 _plot_check_weights_check(result, png_path)
38 return json_path, png_path
39
40
41def _plot_check_weights_check(result: dict[str, Any], png_path: Path) -> None:
42 import matplotlib
43
44 matplotlib.use("Agg")
45 import matplotlib.pyplot as plt
46
47 if result.get("error"):
48 fig, ax = plt.subplots(figsize=(6, 2), facecolor="#0f1117")
49 ax.axis("off")
50 ax.text(0.5, 0.5, f"Error: {result['error']}", ha="center", va="center", wrap=True, color="#e5e7eb")
51 fig.savefig(png_path, dpi=140, bbox_inches="tight", facecolor="#0f1117")
52 plt.close(fig)
53 return
54
55 model = str(result.get("model_id") or "")
56 verdict = str(result.get("verdict") or "—")
57 composite = float(result.get("composite_risk") or 0)
58 rank = result.get("rank") if isinstance(result.get("rank"), dict) else {}
59
60 fig, axes = plt.subplots(1, 2, figsize=(11, 4.8), facecolor="#0f1117")
61 fig.suptitle(
62 f"Weight health — {model} · {verdict} · risk {composite:.1%}",
63 color="#e5e7eb",
64 fontsize=11,
65 y=1.02,
66 )
67
68 _plot_trojan_panel(axes[0], result)
69 _plot_rank_panel(axes[1], rank)
70
71 fig.tight_layout()
72 fig.savefig(png_path, dpi=140, bbox_inches="tight", facecolor="#0f1117")
73 plt.close(fig)
74
75
76def _plot_trojan_panel(ax: Any, result: dict[str, Any]) -> None:
77 scored = result.get("scored_tensors") or []
78 top = sorted(scored, key=lambda t: float(t.get("risk_score") or 0), reverse=True)[:18]
79
80 ax.set_title("Trojan scan (top tensors)", color="#e5e7eb", fontsize=10)
81 if not top:
82 ax.axis("off")
83 ax.text(0.5, 0.5, "No tensor scores.", ha="center", va="center", color="#9ca3af")
84 return
85
86 labels = [
87 f"L{t.get('layer_idx', '?')} {str(t.get('name', '')).split('.')[-1][:12]}"
88 for t in top
89 ]
90 vals = [float(t.get("risk_score") or 0) for t in top]
91 colors = [_STATUS_COLORS.get(str(t.get("status") or ""), "#78716c") for t in top]
92 y_pos = list(range(len(top)))
93
94 ax.barh(y_pos, vals, color=colors, height=0.72)
95 ax.set_yticks(y_pos)
96 ax.set_yticklabels(labels, fontsize=7, color="#d1d5db")
97 ax.invert_yaxis()
98 ax.set_xlim(0, max(max(vals) * 1.1, 0.1))
99 ax.set_xlabel("Risk score", color="#9ca3af", fontsize=8)
100 ax.tick_params(axis="x", colors="#6b7280", labelsize=7)
101 ax.grid(axis="x", alpha=0.2, color="#4b5563")
102 for spine in ax.spines.values():
103 spine.set_color("#374151")
104
105
106def _plot_rank_panel(ax: Any, rank: dict[str, Any]) -> None:
107 matrices = rank.get("matrices") or []
108 threshold = float(rank.get("collapse_threshold") or 0.1)
109
110 ax.set_title("Stable rank by layer (min per layer)", color="#e5e7eb", fontsize=10)
111 if not matrices:
112 ax.axis("off")
113 ax.text(0.5, 0.5, "No rank data.", ha="center", va="center", color="#9ca3af")
114 return
115
116 by_layer: dict[int, float] = {}
117 for row in matrices:
118 layer = int(row.get("layer", 0))
119 stable = float(row.get("stable_rank") or 0)
120 by_layer[layer] = min(by_layer.get(layer, stable), stable)
121
122 layers = sorted(by_layer)
123 vals = [by_layer[li] for li in layers]
124
125 ax.plot(layers, vals, color="#6366f1", linewidth=2, marker="o", markersize=3)
126 ax.axhline(threshold, color="#f87171", linestyle="--", linewidth=1, alpha=0.7, label=f"collapse < {threshold}")
127 for li, v in zip(layers, vals):
128 if v < threshold:
129 ax.scatter([li], [v], color="#f87171", s=28, zorder=3)
130
131 ax.set_xlabel("Layer", color="#9ca3af", fontsize=8)
132 ax.set_ylabel("Min stable rank", color="#9ca3af", fontsize=8)
133 ax.tick_params(colors="#6b7280", labelsize=7)
134 ax.grid(alpha=0.2, color="#4b5563")
135 ax.legend(fontsize=7, facecolor="#1f2937", edgecolor="#374151", labelcolor="#d1d5db")
136 for spine in ax.spines.values():
137 spine.set_color("#374151")
tuple[Path, Path] write_check_weights_check(dict[str, Any] result, *, str|None tool_name, str|Path cwd)
None _plot_rank_panel(Any ax, dict[str, Any] rank)
None _plot_trojan_panel(Any ax, dict[str, Any] result)
None _plot_check_weights_check(dict[str, Any] result, Path png_path)