Skip to content

Commit def4457

Browse files
Fix URLs based on repo transfer and prep for DOI snapshot (#41)
Co-authored-by: Matthew Thompson <thompson.4509@osu.edu>
1 parent 8cd4e17 commit def4457

87 files changed

Lines changed: 3369 additions & 3204 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Check zenodo metadata
2+
3+
on:
4+
push:
5+
paths:
6+
- '.zenodo.json'
7+
- '.github/workflows/validate-zenodo.yaml'
8+
9+
jobs:
10+
check-zenodo-metadata:
11+
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v6
16+
- uses: actions/setup-node@v6
17+
with:
18+
node-version: '24'
19+
- name: Install dependencies
20+
run: npm install zenodraft@0.14.1
21+
- name: Check .zenodo.json file
22+
run: |
23+
npx zenodraft metadata validate .zenodo.json

.zenodo.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"creators": [
3+
{
4+
"name": "Stevens, Samuel",
5+
"orcid": "https://orcid.org/0009-0000-9493-7766",
6+
"affiliation": "The Ohio State University"
7+
}
8+
],
9+
"description": "saev is a package for training sparse autoencoders (SAEs) on vision transformers (ViTs) in PyTorch.",
10+
"keywords": [
11+
"imageomics",
12+
"sparse autoencoders",
13+
"interpretability",
14+
"computer vision"
15+
],
16+
"title": "saev: Sparse Autoencoders for Vision Transformers",
17+
"version": "0.1.0",
18+
"license": "MIT",
19+
"publication_date": "2026-06-18",
20+
"grants": [
21+
{
22+
"id": "021nxhr62::2118240"
23+
}
24+
],
25+
"related_identifiers": [
26+
{
27+
"identifier": "10.48550/arXiv.2502.06755",
28+
"relation": "isSupplementTo",
29+
"resource_type": "publication-preprint"
30+
},
31+
{
32+
"identifier": "10.48550/arXiv.2511.17735",
33+
"relation": "isSupplementTo",
34+
"resource_type": "publication-preprint"
35+
}
36+
]
37+
}

CITATION.cff

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ authors:
1313
email: samuel.robert.stevens@gmail.com
1414
orcid: 'https://orcid.org/0009-0000-9493-7766'
1515
affiliation: The Ohio State University
16-
repository-code: 'https://github.com/OSU-NLP-Group/saev'
17-
url: 'https://osu-nlp-group.github.io/saev/'
16+
repository-code: 'https://github.com/Imageomics/saev'
17+
url: 'https://imageomics.github.io/saev/'
1818
repository-artifact: 'https://pypi.org/project/saev/'
1919
abstract: >-
2020
saev is a package for training sparse autoencoders (SAEs)
@@ -23,7 +23,14 @@ keywords:
2323
- sparse autoencoders
2424
- interpretability
2525
- computer vision
26-
license: CC-BY-4.0
27-
commit: 6a34b6916fda7b04cc2d89749b3ad6425a8f39e6
28-
date-released: '2025-11-16'
29-
26+
license: MIT
27+
date-released: '2026-06-18'
28+
identifiers:
29+
- description: "The GitHub release URL of tag v0.1.0."
30+
type: url
31+
value: "https://github.com/Imageomics/saev/releases/tag/v0.1.0"
32+
- description: "The GitHub URL of the commit tagged with v0.1.0."
33+
type: url
34+
value: "https://github.com/Imageomics/saev/tree/<commit-hash>" # Update on release
35+
version: 0.1.0
36+
#doi: <version-agnostic DOI from Zenodo>

LICENSE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
MIT License
22

3+
Copyright (c) 2024-2026 Samuel Stevens
4+
35
Copyright (c) 2023 Joseph Bloom
46

57
Permission is hereby granted, free of charge, to any person obtaining a copy

README.md

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
![PyPI Downloads](https://static.pepy.tech/badge/saev)
44
![MIT License](https://img.shields.io/badge/License-MIT-efefef)
5-
![GitHub Repo stars](https://img.shields.io/github/stars/OSU-NLP-group/saev?style=flat&label=GitHub%20%E2%AD%90)
5+
![GitHub Repo stars](https://img.shields.io/github/stars/Imageomics/saev?style=flat&label=GitHub%20%E2%AD%90)
66

77
Training sparse autoencoders (SAEs) on vision transformers (ViTs), implemented in PyTorch.
88

99
## Docs
1010

11-
- [Docs](https://osu-nlp-group.github.io/saev/api)
12-
- [Colab Notebook for SAE Inference](https://colab.research.google.com/github/OSU-NLP-Group/saev/blob/main/examples/inference.ipynb)
13-
- [User guide](https://osu-nlp-group.github.io/saev/api/users/guide)
14-
- [API reference](https://osu-nlp-group.github.io/saev/api/api/saev/)
11+
- [Docs](https://imageomics.github.io/saev/api)
12+
- [Colab Notebook for SAE Inference](https://colab.research.google.com/github/Imageomics/saev/blob/main/examples/inference.ipynb)
13+
- [User guide](https://imageomics.github.io/saev/api/users/guide)
14+
- [API reference](https://imageomics.github.io/saev/api/api/saev/)
1515

1616
## Research
1717

@@ -24,16 +24,6 @@ Trained SAE checkpoints are available at:
2424

2525
- [Huggingface Models](https://huggingface.co/collections/osunlp/sae-v-67ab8c4fdf179d117db28195)
2626

27-
If you want to cite the software, please cite it as:
28-
29-
```bib
30-
@software{stevens2025saev,
31-
author = {Stevens, Samuel},
32-
license = {CC-BY-4.0},
33-
month = apr,
34-
title = {{saev}},
35-
url = {https://github.com/OSU-NLP-Group/saev},
36-
year = {2025}
37-
}
38-
```
27+
## Citation
3928

29+
If you want to cite the software, please use the "Cite this repository" link on the GitHub page, which will provide you with the appropriate citation format.

contrib/birdsong/notebooks/001_explore.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ def _finalize_df(rows: list[dict[str, object]]):
270270
)
271271

272272
df = (
273-
df.unnest("config/sae", "config/train_data/metadata", separator="/")
273+
df
274+
.unnest("config/sae", "config/train_data/metadata", separator="/")
274275
.unnest("config/sae/activation", separator="/")
275276
.unnest(
276277
"config/sae/activation/aux",

contrib/birdsong/notebooks/clips.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ def add_target(obs: pl.DataFrame, fields: list[str]) -> pl.DataFrame:
9292
obs = obs.with_columns([pl.col(field).fill_null("unknown") for field in fields])
9393

9494
combos = (
95-
obs.select(fields)
95+
obs
96+
.select(fields)
9697
.unique(maintain_order=True) # first-seen ordering
9798
.with_columns(pl.arange(0, pl.len(), dtype=pl.Int32).alias("target"))
9899
)
@@ -101,7 +102,8 @@ def add_target(obs: pl.DataFrame, fields: list[str]) -> pl.DataFrame:
101102

102103
target2fields = {
103104
target: tuple(rest)
104-
for target, *rest in obs.unique(pl.col("target"))
105+
for target, *rest in obs
106+
.unique(pl.col("target"))
105107
.select("target", *fields)
106108
.iter_rows()
107109
}

contrib/freshwater_fish/scripts/make_gallery.py

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ def build_features(
7474
"""Collect features that have pre-rendered images on disk."""
7575
features = []
7676
available = {
77-
int(d.name)
78-
for d in images_dpath.iterdir()
79-
if d.is_dir() and d.name.isdigit()
77+
int(d.name) for d in images_dpath.iterdir() if d.is_dir() and d.name.isdigit()
8078
}
8179

8280
for row in var_df.iter_rows(named=True):
@@ -275,15 +273,49 @@ def build_features(
275273

276274
def main():
277275
parser = argparse.ArgumentParser(description=__doc__)
278-
parser.add_argument("--run", type=pathlib.Path, required=True, help="Run directory (e.g. /fs/ess/.../runs/um6hbn05)")
279-
parser.add_argument("--shard", type=str, required=True, help="Shard ID (e.g. 8692dfa9)")
280-
parser.add_argument("--dataset", type=pathlib.Path, default=None, help="Dataset root (segfolder with images/ dir, for label ordering)")
281-
parser.add_argument("--split", type=str, default="validation", help="Dataset split name (default: validation)")
282-
parser.add_argument("--hf-config", type=str, default="trait_segmentation", help="HuggingFace FishVista config name")
283-
parser.add_argument("--hf-split", type=str, default="val", help="HuggingFace split name (default: val)")
284-
parser.add_argument("--out", type=pathlib.Path, default=pathlib.Path("gallery.html"), help="Output HTML path")
276+
parser.add_argument(
277+
"--run",
278+
type=pathlib.Path,
279+
required=True,
280+
help="Run directory (e.g. /fs/ess/.../runs/um6hbn05)",
281+
)
282+
parser.add_argument(
283+
"--shard", type=str, required=True, help="Shard ID (e.g. 8692dfa9)"
284+
)
285+
parser.add_argument(
286+
"--dataset",
287+
type=pathlib.Path,
288+
default=None,
289+
help="Dataset root (segfolder with images/ dir, for label ordering)",
290+
)
291+
parser.add_argument(
292+
"--split",
293+
type=str,
294+
default="validation",
295+
help="Dataset split name (default: validation)",
296+
)
297+
parser.add_argument(
298+
"--hf-config",
299+
type=str,
300+
default="trait_segmentation",
301+
help="HuggingFace FishVista config name",
302+
)
303+
parser.add_argument(
304+
"--hf-split",
305+
type=str,
306+
default="val",
307+
help="HuggingFace split name (default: val)",
308+
)
309+
parser.add_argument(
310+
"--out",
311+
type=pathlib.Path,
312+
default=pathlib.Path("gallery.html"),
313+
help="Output HTML path",
314+
)
285315
parser.add_argument("--quality", type=int, default=80, help="JPEG quality (0-100)")
286-
parser.add_argument("--title", type=str, default="", help="Gallery subtitle/description")
316+
parser.add_argument(
317+
"--title", type=str, default="", help="Gallery subtitle/description"
318+
)
287319
args = parser.parse_args()
288320

289321
inference_dpath = args.run / "inference" / args.shard
@@ -313,7 +345,10 @@ def main():
313345
n_imgs = sum(len(f["images"]) for f in features)
314346
logger.info("Total images: %d", n_imgs)
315347

316-
title = args.title or f"SAE run {args.run.name}, shard {args.shard} | {len(features)} features, {n_imgs} images"
348+
title = (
349+
args.title
350+
or f"SAE run {args.run.name}, shard {args.shard} | {len(features)} features, {n_imgs} images"
351+
)
317352
html = HTML_TEMPLATE.replace("FEATURES_JSON", json.dumps(features))
318353
html = html.replace("TITLE_PLACEHOLDER", title)
319354
html = html.replace("RUN_ID_PLACEHOLDER", args.run.name)

contrib/interactive_interp/semseg/interactive.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ def make_upsampled_pred(
570570
logits_WHC: Float[Tensor, "width height classes"],
571571
) -> Uint8[Tensor, "width height"]:
572572
return (
573-
torch.nn.functional.interpolate(
573+
torch.nn.functional
574+
.interpolate(
574575
logits_WHC.max(axis=-1).indices.view((1, 1, 16, 16)).float(),
575576
scale_factor=14,
576577
)

contrib/interactive_interp/semseg/training.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ def __getitem__(self, i: int) -> dict[str, object]:
358358

359359
pw, ph = self.patch_size_px
360360
patch_labels = (
361-
einops.rearrange(pixel_labels, "(w pw) (h ph) -> w h (pw ph)", pw=pw, ph=ph)
361+
einops
362+
.rearrange(pixel_labels, "(w pw) (h ph) -> w h (pw ph)", pw=pw, ph=ph)
362363
.mode(axis=-1)
363364
.values
364365
)

0 commit comments

Comments
 (0)