AQIT 0.1.0
Loading...
Searching...
No Matches
features_cli.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2"""aquin features compare"""
3
4from __future__ import annotations
5
6import sys
7
8
9def _parse_flag(args: list[str], name: str) -> str | None:
10 for i, a in enumerate(args):
11 if a == name and i + 1 < len(args):
12 return args[i + 1]
13 return None
14
15
16def _print_help() -> None:
17 print("Feature-level utilities over saved captures.")
18 print("")
19 print("Usage: aquin features compare --from <capture_dir> [--group <field>] [--top N] [--encode-sae] [--sae-layer N]")
20 print("")
21 print("Notes:")
22 print(" - compare reads saved capture metadata + SAE feature matrix")
23 print(" - if the capture has residuals but no SAE matrix, encodes with the loaded SAE")
24 print(" - --group is a probe metadata field (group, label, lang, …); default group")
25
26
27def _cmd_features_compare(args: list[str]) -> None:
28 if not args or args[0] in ("-h", "--help", "help"):
29 print("Usage: aquin features compare --from <capture_dir> [--group <field>] [--top N] [--encode-sae] [--sae-layer N]")
30 sys.exit(0 if args and args[0] in ("-h", "--help", "help") else 1)
32 from aquin.compute.activation_replay import compare_capture_features
33
34 source = _parse_flag(args, "--from") or _parse_flag(args, "--dir")
35 group = _parse_flag(args, "--group") or "group"
36 top_raw = _parse_flag(args, "--top")
37 sae_layer_raw = _parse_flag(args, "--sae-layer")
38 encode_sae = "--no-encode-sae" not in args
39 if not source:
40 print("Error: --from <capture_dir> is required")
41 sys.exit(1)
42 try:
43 top_k = int(top_raw) if top_raw else 10
44 except ValueError:
45 print("Error: --top must be an integer")
46 sys.exit(1)
47 try:
48 sae_layer = int(sae_layer_raw) if sae_layer_raw else None
49 except ValueError:
50 print("Error: --sae-layer must be an integer")
51 sys.exit(1)
52
53 try:
54 result = compare_capture_features(
55 source,
56 group=group,
57 top_k=top_k,
58 encode_sae=encode_sae,
59 sae_layer=sae_layer,
60 )
61 except Exception as e:
62 print(f"Error: {e}")
63 sys.exit(1)
64
65 print(
66 f"[features compare] model={result.get('model_id', '—')} "
67 f"group={result.get('group', '—')} groups={result.get('n_groups', 0)} "
68 f"sae_layer={result.get('sae_layer', '—')}"
69 )
70 sizes = result.get("group_sizes") or {}
71 if sizes:
72 print("[features compare] sizes: " + " ".join(f"{k}={v}" for k, v in sizes.items()))
73 if result.get("group_inferred"):
74 print("[features compare] probes had no cohort metadata; split into a/b")
75 print("")
76 for row in result.get("features") or []:
77 groups = row.get("groups") or {}
78 group_s = " ".join(f"{k}={v:.4f}" for k, v in groups.items())
79 print(f"f{row.get('feature_idx', '?')} spread={row.get('spread', 0):.4f} {group_s}")
80
81
82def cmd_features(args: list[str]) -> None:
83 if not args or args[0] in ("-h", "--help", "help"):
85 return
86 sub = args[0]
87 rest = args[1:]
88 if sub == "compare":
90 return
91 print(f"Unknown features subcommand: {sub}")
92 print("Run: aquin features --help")
93 sys.exit(1)
None cmd_features(list[str] args)
str|None _parse_flag(list[str] args, str name)
None _cmd_features_compare(list[str] args)