11# Evo2 SAE Feature Explorer (front-end)
22
3- Interactive dashboard for Evo2 SAE features — feature atlas, sequence inspector, and
4- generative steering.
3+ Interactive dashboard for Evo2 SAE features, with four tabs:
4+ ** Feature atlas ** , ** Sequence inspector ** , ** Generative steering** , and ** Sequence UMAP ** .
55
6- This directory is the ** front-end only** . Its backend is the standalone
7- [ ` evo2_sae ` ] ( ../src/evo2_sae ) engine — the viz is just a UI over its
8- ` serve ` mode, so there is no model code here.
6+ This directory is the ** front-end only** (React + Vite). Its backend is the standalone
7+ [ ` evo2_sae ` ] ( ../src/evo2_sae ) engine — the viz is just a UI over its HTTP API, so there is no
8+ model code here. The front-end always calls the API under ** ` /api ` ** (same path in dev and
9+ production), so the only thing that ever changes is * where* ` /api ` is served from.
10+
11+ ## Three ways to run
12+
13+ ### 1. One container — recommended for sharing / deploy
14+
15+ The recipe [ ` Dockerfile ` ] ( ../Dockerfile ) builds this front-end to static files and bakes them
16+ into the image, so a ** single container serves the dashboard and the API on one port** — no
17+ Node and no second process at runtime. This is what to hand a coworker or put behind an SSO proxy.
18+
19+ ``` bash
20+ # build from the REPO ROOT (the build context needs the recipes/evo2_megatron sibling):
21+ docker build -f interpretability/sparse_autoencoders/recipes/evo2/Dockerfile -t evo2-sae .
22+
23+ # run with a GPU + your checkpoints, then open http://localhost:8001
24+ docker run --gpus all -p 8001:8001 \
25+ -e EVO2_CKPT_DIR=/ckpt/evo2 -e SAE_CKPT_PATH=/ckpt/sae.pt -e EMBEDDING_LAYER=26 \
26+ -v /path/to/checkpoints:/ckpt evo2-sae scripts/launch_inference.sh serve
27+ # -> dashboard + API both on http://localhost:8001 (/ = UI, /api = backend)
28+ ```
29+
30+ The first build compiles the megatron stack (~ 30 min) and is layer-cached afterward; a Node build
31+ stage produces the static bundle (` DASHBOARD_DIST ` ) and the server mounts it at ` / ` . No Node ends
32+ up in the runtime image. See the [ recipe Dockerfile] ( ../Dockerfile ) for the layer layout.
33+
34+ ### 2. Local dev — UI iteration with hot reload
35+
36+ Needs ** Node ≥ 18** (for Vite), plus a GPU + checkpoints for the live tabs. Two processes:
937
1038``` bash
11- # 1. Backend : loads Evo2 + the SAE and serves the HTTP API on :8001
12- ../scripts/launch_inference.sh serve # or: python -m evo2_sae.cli serve
39+ # backend : loads Evo2 + the SAE, serves the API under /api on :8001
40+ ../scripts/launch_inference.sh serve # or: python -m evo2_sae.cli serve
1341
14- # 2. Dashboard (from recipes/evo2): stages data (if any) + starts Vite
15- python ../scripts/launch_dashboard.py # inspector + steering tabs
16- python ../scripts/launch_dashboard.py --data-dir /path/to/data # + Feature-atlas tab
42+ # front-end: Vite dev server on :5176 (hot reload)
43+ ../scripts/launch_dashboard.py # stages atlas data if --data-dir is given, then runs Vite
44+ # or, for raw front-end dev: npm install && npm run dev
1745```
1846
19- ` launch_dashboard.py ` is the entry point — it validates/stages the atlas parquets into
20- ` public/ ` (when ` --data-dir ` is given) and runs Vite. The ** inspector** and ** steering** tabs
21- work with no atlas data (they call the backend); the ** Feature-atlas** tab needs the three
22- parquets (` features_atlas ` , ` feature_metadata ` , ` feature_examples ` ) via ` --data-dir ` —
23- producing them is a separate offline step. (` npm install && npm run dev ` also works for raw
24- front-end dev, but skips data staging.)
47+ Vite proxies ` /api ` ** straight through** to ` http://localhost:8001 ` (no path rewrite — see
48+ ` vite.config.js ` ), so dev hits the same ` /api/* ` paths as the single-container build. Point it at a
49+ different backend with ` VITE_BACKEND ` . Configure the backend via the env vars in ` launch_inference.sh ` .
2550
26- The Vite dev server proxies ` /api ` → ` http://localhost:8001 ` (see ` vite.config.js ` ); point it
27- elsewhere with ` VITE_BACKEND ` . Configure the backend via the env vars in ` launch_inference.sh ` .
51+ To reach a remote box, tunnel the Vite port only (Vite proxies ` /api ` on the box):
52+
53+ ``` bash
54+ tsh ssh -L 5176:localhost:5176 < gpu-box> # then open http://localhost:5176
55+ ```
2856
29- ## Running without a backend (offline / static)
57+ ### 3. Offline / static — no backend
3058
31- The dashboard degrades gracefully: it probes ` /health ` , and when there's ** no live backend** it
59+ The dashboard degrades gracefully: it probes ` /api/ health ` , and when there's ** no live backend** it
3260hides the tabs that need the model and keeps the ones that read static files.
3361
3462| Tab | Needs backend? | Offline source |
@@ -38,22 +66,35 @@ hides the tabs that need the model and keeps the ones that read static files.
3866| ** Generative steering** | yes | hidden offline |
3967| ** Sequence inspector** | yes | hidden offline |
4068
41- So with no backend you get the ** Feature atlas** always, and ** Sequence UMAP** if you precompute
42- its bundle. Steering and the live inspector require ` serve ` .
69+ So with no backend you always get the ** Feature atlas** , plus ** Sequence UMAP** if you precompute its
70+ bundle. Steering and the live inspector require ` serve ` .
4371
4472``` bash
45- # (one-time, needs the 7B ) precompute all the static artifacts into one dir:
73+ # (one-time, needs the model ) precompute the static artifacts into one dir:
4674python ../scripts/dashboard.py atlas --activations-dir $STORE --output-dir dashboard_data # atlas tab
4775python ../scripts/dashboard.py examples --examples-fasta lib.fa --output-dir dashboard_data # example cards
4876python ../scripts/dashboard.py embeddings --examples-fasta lib.fa --output-dir dashboard_data # Sequence-UMAP bundle
4977# (env: SAE_CKPT_PATH, EVO2_CKPT_DIR, FEATURE_ANNOTATIONS — same as launch_inference.sh)
5078
51- # serve the static dashboard — NO backend, NO GPU:
79+ # serve the static dashboard — NO backend, NO GPU (needs Node for the dev server, or `npm run build`) :
5280python ../scripts/launch_dashboard.py --data-dir dashboard_data
5381```
5482
55- ` dashboard.py embeddings ` writes ` sequmap_embeddings.json ` (the same shape ` /gene_embed ` returns;
56- bounded by sequence count). The viz auto-detects it (override the path with ` ?embeddings=<url> ` ).
57- With all artifacts staged, ` npm run build ` produces a fully static site you can host anywhere
58- (HF Spaces static / S3 / Pages) — interactive steering/inspector light up automatically if a
59- backend is later reachable.
83+ ` dashboard.py embeddings ` writes ` sequmap_embeddings.json ` (the same shape ` /api/gene_embed ` returns).
84+ The viz auto-detects it (override the path with ` ?embeddings=<url> ` ). With all artifacts staged,
85+ ` npm run build ` produces a fully static site you can host anywhere (HF Spaces static / S3 / Pages) —
86+ the interactive steering/inspector tabs light up automatically if a backend later becomes reachable.
87+
88+ ## Tabs
89+
90+ - ** Feature atlas** — browse every SAE feature: firing rate, decoder-space UMAP, top-activating
91+ examples, labels. Reads precomputed static files.
92+ - ** Sequence inspector** — paste a sequence, see per-base SAE activations (top-k or picked features).
93+ Live encode.
94+ - ** Generative steering** — generate DNA while clamping chosen features on the continuation, vs. the
95+ unsteered baseline. Live generation.
96+ - ** Sequence UMAP** — embed a set of sequences (pooled per-feature vectors), UMAP them, color/re-project
97+ by a feature. Live backend or a precomputed bundle.
98+
99+ Each tab shows its own ** Limitations** note in-app (context-length caps, the ±300 steering clamp,
100+ stochastic 2-D UMAP, etc.).
0 commit comments