AQIT 0.1.0
Loading...
Searching...
No Matches
weight_diff_cli.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2"""aquin diff weight — base vs checkpoint weight delta analysis."""
3
4import sys
5
6from aquin.cli_flags import reject_legacy_output_flags
7from pathlib import Path
8from typing import Any
9
10
11def _parse_flag(args: list[str], name: str) -> str | None:
12 for i, a in enumerate(args):
13 if a == name and i + 1 < len(args):
14 return args[i + 1]
15 return None
16
17
18def _has_flag(args: list[str], name: str) -> bool:
19 return name in args
20
21
22def _ensure_compute_env() -> None:
23 from aquin.compute.loader_shim import apply as _shim_apply
24 from aquin.engine.local_server import start as _start_local_server
25
26 _shim_apply()
27 _start_local_server()
28
29
30def _resolve_model_id() -> str:
31 from aquin.compute.model_loader import get_active_model_id, resolve_model_id
32
33 active = (get_active_model_id() or "").strip()
34 if not active:
35 print("Error: no model loaded. Run: aquin load --model <id>")
36 sys.exit(1)
37 try:
38 return resolve_model_id(active)
39 except ValueError as e:
40 print(f"Error: {e}")
41 sys.exit(1)
42
43
44def _print_help() -> None:
45 print("Compare base vs fine-tuned checkpoint weights (LLM).")
46 print("")
47 print("Prerequisite: aquin load --model <id>")
48 print("")
49 print("Usage: aquin diff weight --checkpoint <path>")
50 print(" [--name <label>] [--prompts <json|jsonl>] [--no-behavioral]")
51 print(" [--save <path>]")
52 print("")
53 print(" --checkpoint Fine-tuned .pt state_dict or HF save_pretrained directory.")
54 print(" --name Label for checkpoint in output and web card.")
55 print(" --prompts Probe file for behavioral model-diff (LLM only).")
56 print(" --no-behavioral Skip generation-based behavioral scores (faster).")
57 print(" --save Write schema_version=1 JSON export.")
58 print("")
59 print("Reports per-layer ||dW||, rank/collapse signals, merge verdict (pass/warn/fail),")
60 print("and optional behavioral probes on LLM checkpoints.")
61 print("")
62 print("Example:")
63 print(" aquin diff weight --checkpoint ~/runs/checkpoint.pt --save weight-diff.json")
64 print("")
65 print("Docs: https://aquin.app/docs/checkpoint-sae")
66
67
68def cmd_weight_diff(args: list[str]) -> None:
69 if _has_flag(args, "--help") or _has_flag(args, "-h"):
71 return
73 reject_legacy_output_flags(args)
74
75 checkpoint = _parse_flag(args, "--checkpoint")
76 if not checkpoint:
77 print("Error: --checkpoint is required.")
78 print("")
80 sys.exit(1)
81
82 ckpt = Path(checkpoint).expanduser()
83 if not ckpt.exists():
84 print(f"Error: checkpoint not found: {checkpoint}")
85 sys.exit(1)
86
87 if _parse_flag(args, "--model") is not None:
88 print("Error: diff weight uses the loaded session model only.")
89 sys.exit(1)
90
91 prompts_arg = _parse_flag(args, "--prompts")
92 if prompts_arg:
93 from aquin.compute.activation_capture import resolve_prompts_path
94
95 resolved = resolve_prompts_path(Path(prompts_arg).expanduser())
96 if resolved is None:
97 print(f"Error: probe file not found: {prompts_arg}")
98 sys.exit(1)
99 prompts_arg = str(resolved)
100
102
103 from aquin.cli import _build_tool_ctx
104 from aquin.engine.sync_dispatch import dispatch_with_sync, require_active_session
105
106 mid = _resolve_model_id()
107 ctx = _build_tool_ctx(model_id=mid)
108 require_active_session(ctx, label="aquin diff weight")
109
110 tool_args: dict[str, Any] = {
111 "model_id": mid,
112 "checkpoint": str(ckpt),
113 "name": _parse_flag(args, "--name") or ckpt.stem,
114 "save": _parse_flag(args, "--save"),
115 "no_behavioral": _has_flag(args, "--no-behavioral"),
116 }
117 if prompts_arg:
118 tool_args["prompts"] = prompts_arg
119 try:
120 print(f"[diff weight] model={mid} checkpoint={ckpt.name}")
121 result = dispatch_with_sync("run_merge_analysis", tool_args, ctx)
122 except Exception as e:
123 print(f"Error: {e}")
124 sys.exit(1)
125
126 from aquin.cli_output import print_tool_result
127
128 print_tool_result("diff weight", result)
129
130 if isinstance(result, dict):
131 if result.get("error"):
132 sys.exit(1)
133 if result.get("mergeVerdict") == "fail":
134 sys.exit(2)
bool _has_flag(list[str] args, str name)
str|None _parse_flag(list[str] args, str name)
None cmd_weight_diff(list[str] args)