Mechanistic Interpretability Library
0
stars
5
commits
Python
primary language
Aug 29, 2025
updated
A model-agnostic toolkit for Sparse Autoencoder training, analysis, and steering in mechanistic interpretability research.
# Clone repository
git clone https://github.com/eldarhac/integral-superposition.git
cd integral-superposition
# Install in development mode
pip install -e .
# Optional: Install additional dependencies
pip install -e ".[viz]" # For UMAP visualization
pip install -e ".[kaggle]" # For Kaggle dataset loading
pip install -e ".[full]" # Install all optional dependencies
from integral_superposition import backends, data, dump, DumpConfig
# Load model
backend = backends.HFCausalLM.from_pretrained("google/gemma-3-270m")
# Load dataset - Option 1: From Kaggle (matches original notebook)
df = data.load_kaggle_dataset(
"kotartemiy/topic-labeled-news-dataset",
"labelled_newscatcher_dataset.csv",
text_col="title",
label_col="topic"
)
# Load dataset - Option 2: From local file
# df = data.load_titles_csv("dataset.csv", text_col="title", label_col="topic")
# Load dataset - Option 3: Auto-detect
# df = data.load_dataset_auto("kotartemiy/topic-labeled-news-dataset")
# Configure and dump
cfg = DumpConfig(layer=13, max_len=32, batch_size=64)
dump.dump_layer_activations(df, "title", "topic", backend, cfg, "acts_shards")
from integral_superposition import sae, SAEConfig
cfg = SAEConfig(k=2048, lr=3e-4, l1=1e-3, epochs=2)
model = sae.SparseAutoencoder(d_model=640, k=2048)
# Train on dumped activations
sae.train_sae(model, shard_iterator, cfg, device)
sae.save_sae(model, "sae_weights.pt")
from integral_superposition import analysis
# Find top-activating tokens
top_sets = analysis.top_tokens.topk_sets_per_latent(model, act_files, device)
# Compute enrichment statistics
summary = analysis.enrichment.fisher_enrichment(top_sets, labels_global)
from integral_superposition import merge
# Cluster by decoder similarity
dist = merge.cluster.cosine_dist_from_decoder(model.dec.weight.data.numpy())
labels = merge.cluster.agglomerative_labels(dist, n_clusters=256)
medoids = merge.medoid.medoids_from_labels(dist, labels)
# Refit decoder
M = merge.medoid.merge_matrix_from_labels(labels, medoids)
W_new = merge.refit.merge_and_refit_decoder(data_iter, model, M)
from integral_superposition import steering
# Create latent modifier
modifier = steering.set_or_scale_latent(latent_j=42, set_to=100.0)
# Register steering hook
handle = steering.register_prehook_last_row(backend, layer_idx=13, sae=model, latent_map=modifier)
# Generate with intervention
outputs = backend.generate(**inputs, max_new_tokens=10)
handle.remove()
Complete examples are provided in the examples/ directory:
01_dump_activations.py - Extract activations from language model02_train_sae.py - Train Sparse Autoencoder03_analyze_latents.py - Compute enrichment and statistics04_merge_and_refit.py - Cluster and merge similar latents05_plot_maps.py - Create 2D visualizations06_steer_generation.py - Intervention experimentsRun examples:
cd examples
python 01_dump_activations.py
python 02_train_sae.py
python 03_analyze_latents.py
# ... etc
The package supports multiple data sources:
from integral_superposition import data
# Direct Kaggle loading
df = data.load_kaggle_dataset(
dataset_id="kotartemiy/topic-labeled-news-dataset",
filename="labelled_newscatcher_dataset.csv",
text_col="title",
label_col="topic"
)
# CSV files with custom separators
df = data.load_titles_csv("path/to/dataset.csv", text_col="title", label_col="topic")
# Train/test split
train_df, test_df = data.split_df(df, train=0.8, seed=42)
# Automatically detect local file or Kaggle dataset
df = data.load_dataset_auto("kotartemiy/topic-labeled-news-dataset")
df = data.load_dataset_auto("/path/to/local/file.csv")
integral_superposition/
├── backends/ # Model abstraction layer
│ ├── base_model.py # Abstract backend interface
│ ├── hf_causal_lm.py # HuggingFace implementation
│ └── io_store.py # File I/O utilities
├── data/ # Dataset handling
│ ├── datasets.py # CSV loading and preprocessing
│ └── tokenize.py # Tokenization utilities
├── dump/ # Activation extraction
│ └── activations.py # Batched dumping to shards
├── sae/ # Sparse Autoencoder
│ ├── model.py # SAE model definition
│ ├── train.py # Training loop
│ └── load.py # Inference utilities
├── analysis/ # Latent analysis
│ ├── enrichment.py # Fisher exact enrichment
│ ├── top_tokens.py # Top-k extraction
│ ├── jaccard_sparse.py # Sparse Jaccard similarity
│ ├── reducer.py # Dimensionality reduction
│ └── stats.py # Statistical utilities
├── merge/ # Latent clustering/merging
│ ├── cluster.py # Agglomerative clustering
│ ├── medoid.py # Medoid selection
│ └── refit.py # Decoder refitting
├── steering/ # Model interventions
│ └── hooks.py # Forward hook utilities
└── viz/ # Visualization
├── panels.py # Interactive HTML panels
└── maps.py # 2D scatter plots
Use Pydantic models for type-safe configuration:
from integral_superposition import DumpConfig, SAEConfig, Paths
dump_cfg = DumpConfig(layer=13, max_len=32, batch_size=64, dtype="bf16")
sae_cfg = SAEConfig(k=2048, lr=3e-4, l1=1e-3, epochs=2, batch_size=4096)
paths = Paths(shards_dir="acts", sae_path="model.pt", summary_csv="results.csv")
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
MIT License. See LICENSE for details.
If you use this toolkit in your research, please cite:
@software{integral_superposition,
title={Integral Superposition: Model-Agnostic SAE Toolkit},
author={Research Team},
year={2024},
url={https://github.com/example/integral-superposition}
}
5 commits
Python
100.0%
Mechanistic Interpretability Library
0
stars
5
commits
Python
primary language
Aug 29, 2025
updated
A model-agnostic toolkit for Sparse Autoencoder training, analysis, and steering in mechanistic interpretability research.
# Clone repository
git clone https://github.com/eldarhac/integral-superposition.git
cd integral-superposition
# Install in development mode
pip install -e .
# Optional: Install additional dependencies
pip install -e ".[viz]" # For UMAP visualization
pip install -e ".[kaggle]" # For Kaggle dataset loading
pip install -e ".[full]" # Install all optional dependencies
from integral_superposition import backends, data, dump, DumpConfig
# Load model
backend = backends.HFCausalLM.from_pretrained("google/gemma-3-270m")
# Load dataset - Option 1: From Kaggle (matches original notebook)
df = data.load_kaggle_dataset(
"kotartemiy/topic-labeled-news-dataset",
"labelled_newscatcher_dataset.csv",
text_col="title",
label_col="topic"
)
# Load dataset - Option 2: From local file
# df = data.load_titles_csv("dataset.csv", text_col="title", label_col="topic")
# Load dataset - Option 3: Auto-detect
# df = data.load_dataset_auto("kotartemiy/topic-labeled-news-dataset")
# Configure and dump
cfg = DumpConfig(layer=13, max_len=32, batch_size=64)
dump.dump_layer_activations(df, "title", "topic", backend, cfg, "acts_shards")
from integral_superposition import sae, SAEConfig
cfg = SAEConfig(k=2048, lr=3e-4, l1=1e-3, epochs=2)
model = sae.SparseAutoencoder(d_model=640, k=2048)
# Train on dumped activations
sae.train_sae(model, shard_iterator, cfg, device)
sae.save_sae(model, "sae_weights.pt")
from integral_superposition import analysis
# Find top-activating tokens
top_sets = analysis.top_tokens.topk_sets_per_latent(model, act_files, device)
# Compute enrichment statistics
summary = analysis.enrichment.fisher_enrichment(top_sets, labels_global)
from integral_superposition import merge
# Cluster by decoder similarity
dist = merge.cluster.cosine_dist_from_decoder(model.dec.weight.data.numpy())
labels = merge.cluster.agglomerative_labels(dist, n_clusters=256)
medoids = merge.medoid.medoids_from_labels(dist, labels)
# Refit decoder
M = merge.medoid.merge_matrix_from_labels(labels, medoids)
W_new = merge.refit.merge_and_refit_decoder(data_iter, model, M)
from integral_superposition import steering
# Create latent modifier
modifier = steering.set_or_scale_latent(latent_j=42, set_to=100.0)
# Register steering hook
handle = steering.register_prehook_last_row(backend, layer_idx=13, sae=model, latent_map=modifier)
# Generate with intervention
outputs = backend.generate(**inputs, max_new_tokens=10)
handle.remove()
Complete examples are provided in the examples/ directory:
01_dump_activations.py - Extract activations from language model02_train_sae.py - Train Sparse Autoencoder03_analyze_latents.py - Compute enrichment and statistics04_merge_and_refit.py - Cluster and merge similar latents05_plot_maps.py - Create 2D visualizations06_steer_generation.py - Intervention experimentsRun examples:
cd examples
python 01_dump_activations.py
python 02_train_sae.py
python 03_analyze_latents.py
# ... etc
The package supports multiple data sources:
from integral_superposition import data
# Direct Kaggle loading
df = data.load_kaggle_dataset(
dataset_id="kotartemiy/topic-labeled-news-dataset",
filename="labelled_newscatcher_dataset.csv",
text_col="title",
label_col="topic"
)
# CSV files with custom separators
df = data.load_titles_csv("path/to/dataset.csv", text_col="title", label_col="topic")
# Train/test split
train_df, test_df = data.split_df(df, train=0.8, seed=42)
# Automatically detect local file or Kaggle dataset
df = data.load_dataset_auto("kotartemiy/topic-labeled-news-dataset")
df = data.load_dataset_auto("/path/to/local/file.csv")
integral_superposition/
├── backends/ # Model abstraction layer
│ ├── base_model.py # Abstract backend interface
│ ├── hf_causal_lm.py # HuggingFace implementation
│ └── io_store.py # File I/O utilities
├── data/ # Dataset handling
│ ├── datasets.py # CSV loading and preprocessing
│ └── tokenize.py # Tokenization utilities
├── dump/ # Activation extraction
│ └── activations.py # Batched dumping to shards
├── sae/ # Sparse Autoencoder
│ ├── model.py # SAE model definition
│ ├── train.py # Training loop
│ └── load.py # Inference utilities
├── analysis/ # Latent analysis
│ ├── enrichment.py # Fisher exact enrichment
│ ├── top_tokens.py # Top-k extraction
│ ├── jaccard_sparse.py # Sparse Jaccard similarity
│ ├── reducer.py # Dimensionality reduction
│ └── stats.py # Statistical utilities
├── merge/ # Latent clustering/merging
│ ├── cluster.py # Agglomerative clustering
│ ├── medoid.py # Medoid selection
│ └── refit.py # Decoder refitting
├── steering/ # Model interventions
│ └── hooks.py # Forward hook utilities
└── viz/ # Visualization
├── panels.py # Interactive HTML panels
└── maps.py # 2D scatter plots
Use Pydantic models for type-safe configuration:
from integral_superposition import DumpConfig, SAEConfig, Paths
dump_cfg = DumpConfig(layer=13, max_len=32, batch_size=64, dtype="bf16")
sae_cfg = SAEConfig(k=2048, lr=3e-4, l1=1e-3, epochs=2, batch_size=4096)
paths = Paths(shards_dir="acts", sae_path="model.pt", summary_csv="results.csv")
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
MIT License. See LICENSE for details.
If you use this toolkit in your research, please cite:
@software{integral_superposition,
title={Integral Superposition: Model-Agnostic SAE Toolkit},
author={Research Team},
year={2024},
url={https://github.com/example/integral-superposition}
}
5 commits
Python
100.0%