AQIT
0.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
saes.py
Go to the documentation of this file.
1
# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2
# This file is part of the Aquin Engine. Unauthorized copying, modification,
3
# distribution, or use of this file, via any medium, is strictly prohibited.
4
# Proprietary and confidential. See LICENSE for terms.
5
6
from
__future__
import
annotations
7
8
import
os
9
import
sys
10
from
pathlib
import
Path
11
12
13
_BASE_URL =
"https://api.aquin.app"
14
15
16
def
_base_url
() -> str:
17
return
os.environ.get(
"AQUIN_BASE_URL"
, _BASE_URL).rstrip(
"/"
)
18
19
20
def
_get_api_key
(cfg: dict) -> str:
21
key = cfg.get(
"api_key"
)
or
os.environ.get(
"AQUIN_API_KEY"
)
or
""
22
if
not
key:
23
print(
"No API key found. Set AQUIN_API_KEY, or use aquin load sae --path <file.pt>."
)
24
sys.exit(1)
25
return
key
26
27
28
# ── Public (no auth) ─────────────────────────────────────────────────────────
29
30
def
list_saes
(model: str |
None
=
None
) -> list[dict]:
31
import
requests
32
from
aquin.user_errors
import
die
33
34
try
:
35
resp = requests.get(f
"{_base_url()}/api/public/saes"
, timeout=15)
36
resp.raise_for_status()
37
except
Exception
as
exc:
38
die(message=
"Could not load SAE catalog. Try again shortly."
, exc=exc, label=
"load sae"
)
39
data = resp.json()
40
if
model:
41
data = [s
for
s
in
data
if
s[
"model_slug"
] == model
or
s[
"model_name"
].lower() == model.lower()]
42
return
data
43
44
45
def
get_sae
(id: str) -> dict:
46
import
requests
47
from
aquin.user_errors
import
die, sanitize_error_string
48
49
resp = requests.get(f
"{_base_url()}/api/public/saes/{id}"
, timeout=15)
50
if
resp.status_code == 404:
51
die(sanitize_error_string(f
"SAE '{id}' not found"
))
52
try
:
53
resp.raise_for_status()
54
except
Exception
as
exc:
55
die(message=
"Could not load SAE info. Try again shortly."
, exc=exc, label=
"info sae"
)
56
return
resp.json()
57
58
59
# ── Authenticated ─────────────────────────────────────────────────────────────
60
61
def
pull_sae
(id: str, output: str | Path, api_key: str) ->
None
:
62
import
requests
63
64
out = Path(output)
65
out.parent.mkdir(parents=
True
, exist_ok=
True
)
66
67
resp = requests.get(
68
f
"{_base_url()}/api/public/saes/{id}/pull"
,
69
headers={
"Authorization"
: f
"Bearer {api_key}"
},
70
stream=
True
,
71
timeout=600,
72
allow_redirects=
True
,
73
)
74
75
if
resp.status_code == 503:
76
out.unlink(missing_ok=
True
)
77
print(f
"Error: SAE '{id}' is invalid in catalog storage (not real weights)."
, file=sys.stderr)
78
print(
"Contact Aquin support or use: aquin load sae --path <local.pt> --layer <n>"
, file=sys.stderr)
79
sys.exit(1)
80
if
resp.status_code == 401:
81
from
aquin.auth_config
import
print_token_rejected
82
print_token_rejected(api_key)
83
if
resp.status_code == 403:
84
data = resp.json()
85
print(data.get(
"error"
,
"Access not granted."
))
86
sys.exit(1)
87
if
resp.status_code == 404:
88
print(f
"SAE '{id}' is not in the Aquin SAE library."
, file=sys.stderr)
89
print(
""
, file=sys.stderr)
90
print(
"Try: aquin load sae <model-l{n}>"
, file=sys.stderr)
91
print(
" aquin load sae --path <file.pt> --layer <n>"
, file=sys.stderr)
92
print(
""
, file=sys.stderr)
93
print(
94
"Train your own: aquin sae train --layer <n> --name <tag>"
,
95
file=sys.stderr,
96
)
97
sys.exit(1)
98
try
:
99
resp.raise_for_status()
100
except
Exception
as
exc:
101
from
aquin.user_errors
import
die
102
die(
103
message=f
"Could not download SAE '{id}'. Set AQUIN_API_KEY or use --path <file.pt>."
,
104
exc=exc,
105
label=
"load sae"
,
106
)
107
108
total = int(resp.headers.get(
"content-length"
, 0))
109
downloaded = 0
110
with
open(out,
"wb"
)
as
f:
111
for
chunk
in
resp.iter_content(chunk_size=1024 * 1024):
112
f.write(chunk)
113
downloaded += len(chunk)
114
if
total:
115
pct = downloaded / total * 100
116
mb = downloaded / 1_000_000
117
print(f
"\r {mb:.1f} MB / {total/1_000_000:.1f} MB ({pct:.0f}%)"
, end=
""
, flush=
True
)
118
print(f
"\r Saved to {out} "
)
119
120
from
aquin.compute.torch_io
import
(
121
is_valid_sae_checkpoint_path,
122
looks_like_invalid_norm_blob,
123
looks_like_json_error_blob,
124
)
125
126
if
looks_like_json_error_blob(out)
or
not
is_valid_sae_checkpoint_path(out):
127
out.unlink(missing_ok=
True
)
128
print(f
"Error: download for '{id}' was not a valid SAE checkpoint."
, file=sys.stderr)
129
print(
"Catalog storage may be corrupt — train locally:"
, file=sys.stderr)
130
print(
" aquin sae train --model <id> --layer <n> --name <tag> --quick"
, file=sys.stderr)
131
print(
" aquin load sae --user <tag> --layer <n>"
, file=sys.stderr)
132
sys.exit(1)
133
134
try
:
135
row =
get_sae
(id)
136
except
Exception:
137
row = {}
138
if
row.get(
"meta_key"
):
139
layer = row.get(
"layer"
)
140
norm_name = f
"norm_layer{layer}.pt"
if
layer
is
not
None
else
"norm.pt"
141
norm_out = out.parent / norm_name
142
norm_resp = requests.get(
143
f
"{_base_url()}/api/public/saes/{id}/pull-norm"
,
144
headers={
"Authorization"
: f
"Bearer {api_key}"
},
145
stream=
True
,
146
timeout=600,
147
allow_redirects=
True
,
148
)
149
if
norm_resp.status_code == 200:
150
with
open(norm_out,
"wb"
)
as
f:
151
for
chunk
in
norm_resp.iter_content(chunk_size=1024 * 1024):
152
f.write(chunk)
153
if
looks_like_invalid_norm_blob(norm_out):
154
norm_out.unlink(missing_ok=
True
)
155
print(
156
f
" Note: norm stats unavailable for '{id}' (catalog storage issue) — inspect works without them"
,
157
file=sys.stderr,
158
)
159
else
:
160
print(f
" Saved norm to {norm_out}"
)
161
elif
norm_resp.status_code == 503:
162
print(
163
f
" Warning: norm for '{id}' is invalid in catalog storage — inspect will run without normalization"
,
164
file=sys.stderr,
165
)
166
elif
norm_resp.status_code != 404:
167
print(f
" Warning: norm download failed ({norm_resp.status_code})"
, file=sys.stderr)
168
169
170
# ── SDK client namespace ──────────────────────────────────────────────────────
171
172
class
SaesNamespace
:
173
def
__init__(self, api_key: str |
None
=
None
):
174
self._api_key = api_key
175
176
def
list
(self, model: str |
None
=
None
) -> list[dict]:
177
return
list_saes
(model=model)
178
179
def
get
(self, id: str) -> dict:
180
return
get_sae
(id)
181
182
def
pull
(self, id: str |
None
=
None
, model: str |
None
=
None
,
183
layer: int |
None
=
None
, output: str | Path =
"./sae.pt"
) ->
None
:
184
if
id
is
None
:
185
if
model
is
None
:
186
raise
ValueError(
"Provide id or model."
)
187
rows =
list_saes
(model=model)
188
if
layer
is
not
None
:
189
rows = [r
for
r
in
rows
if
r[
"layer"
] == layer]
190
if
not
rows:
191
raise
ValueError(f
"No SAE found for model={model} layer={layer}"
)
192
id = rows[0][
"id"
]
193
if
not
self.
_api_key
:
194
raise
ValueError(
"api_key required for pull(). Pass it to aquin.Client()."
)
195
pull_sae
(id, output, self.
_api_key
)
aquin.saes.SaesNamespace
Definition
saes.py:176
aquin.saes.SaesNamespace.__init__
__init__(self, str|None api_key=None)
Definition
saes.py:177
aquin.saes.SaesNamespace.pull
None pull(self, str|None id=None, str|None model=None, int|None layer=None, str|Path output="./sae.pt")
Definition
saes.py:187
aquin.saes.SaesNamespace.get
dict get(self, str id)
Definition
saes.py:183
aquin.saes.SaesNamespace.list
list[dict] list(self, str|None model=None)
Definition
saes.py:180
aquin.saes.SaesNamespace._api_key
_api_key
Definition
saes.py:178
aquin.auth_config
Definition
auth_config.py:1
aquin.compute.torch_io
Definition
torch_io.py:1
aquin.saes.pull_sae
None pull_sae(str id, str|Path output, str api_key)
Definition
saes.py:65
aquin.saes.get_sae
dict get_sae(str id)
Definition
saes.py:49
aquin.saes._get_api_key
str _get_api_key(dict cfg)
Definition
saes.py:24
aquin.saes._base_url
str _base_url()
Definition
saes.py:20
aquin.saes.list_saes
list[dict] list_saes(str|None model=None)
Definition
saes.py:34
aquin.user_errors
Definition
user_errors.py:1
aquin
saes.py
AQIT · Aquin Labs Private Limited · Apache 2.0 · Generated by
1.18.0