Spaces:
Sleeping
Sleeping
Commit History
-
Add task manager app and model prefetch script
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>5e3dd78 -
Merge claude/friendly-lichterman-da3b5d into main
75ddf93
-
Sanitize cache_dir: portable default + CACHE_DIR env override
Replace the hardcoded /Volumes/Flux cache path in config.yaml and the experiment_svd_truncation default with a portable "downloads" default, and add a CACHE_DIR env override in the Snakefile (mirroring OUTPUT_DIR). Point CACHE_DIR at a big external volume to reuse downloaded weights without committing a local path to the repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>15cbcc7 -
Track previously-untracked utility scripts and example config
These were present locally but never added: the HF dataset builder, the MP statistics compute/inspect scripts, the viewer-index generator, and the example correlations config. Code/config only — no secrets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>f51ee1f -
Merge W_OV equilibrium observables into main
7939cd5 -
Add QK/OV equilibrium observables to correlations stage
Gated by correlation.equilibrium (off by default): compute per-head commutator, irreversibility, and symmetric/antisymmetric observables from the QK and OV operators. Extends extract_head_stores to materialize the OV operator when equilibrium is requested, and threads --equilibrium through the correlations rule and run_correlations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1062742 -
Speed up primary element stats and cut peak memory
Replace the per-head np.histogram + scipy stats with one fused pass: O(n) uniform-bin histogram, shared-central-moment mean/std/skew/kurtosis (bit-identical to scipy), and a histogram plug-in differential_entropy that drops scipy's O(n log n) Vasicek sort. ~18x faster per-head element stats. Build W_QK one head at a time instead of the full (n_heads, d_model, d_model) tensor, removing an ~838 MB transient and a pointless device round-trip (W_QK is only histogrammed on CPU). This is what relieves swap thrashing for the large models. Also add a gated svd_via_gram option (off by default) deriving W_Q/W_K U,S from the d_head Gram eigendecomposition instead of a wide MPS->CPU-fallback SVD. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>fa476b7
-
Add tight-pair bond ultrametricity scores
For each tight pair (a,b) — mutual nearest neighbors or the k smallest-D pairs — average the Rammal index u over triples where (a,b) is the shortest edge; the bond score 1-<u> separates the ultrametric backbone (high) from specific contacts (low). Compared against a null computed the same way on a distance matrix with shuffled off-diagonals; low-score pairs are expected to match the most-negative D-C residual pairs, and bimodality marks the backbone-vs-contact split. tight_pair_scores returns the pair indices, per-bond scores, and null so they can be cross-referenced against the R eigenvectors. Persisted to the .npz/summary and surfaced in the dashboard with live method (MNN / smallest-D) and k controls, a score-vs-null histogram, and a flagged low-score table tagged with residual overlap. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>21da706 -
Add ultrametricity analysis stage for head-overlap matrices
Post-processing stage over the correlations Q_hh matrices. New module transformer_analysis.ultrametricity computes, per model and per metric (Frobenius chordal distance, Jensen-Shannon distance): - triple Rammal index u (3-point ultrametricity), per-head map, u-vs-layer-span, tight-pair co-occurrence, triangle-violation check - four-point additivity index u4 and Gromov delta-hyperbolicity - average-linkage dendrogram, cophenetic correlation, and the D=C+R residual decomposition (effective rank, eigenvalues/eigenvectors, sparsity verdict) - classical MDS / PCoA (eigenvalues + leading principal coordinates) - cophenetic correlation across linkage rules - an untrained null ensemble for the distance distribution run_ultrametricity.py reads the correlation .npz outputs (no model download), writes per-metric .npz + summary JSON, and logs to MLflow. Wired in as an optional snakemake stage (rules/ultrametricity.smk, ultrametricity_all target) with a config.yaml section. Co-Authored-By: …840479b
-
Eval: optional layer offload via accelerate for >RAM models
Adds an opt-in --offload-layers path that loads the model with accelerate.init_empty_weights + load_checkpoint_and_dispatch, so layers stream from disk through a bounded memory budget instead of all sitting resident. Unlocks models that don't fit in unified memory in fp16 (e.g. pythia-2.8b on a 16 GB M4) at the cost of much slower per-window inference. Numerics are unchanged — perplexity matches a non-offload reference within fp16 noise (verified on pythia-70m, delta ppl < 0.1%). CLI: --offload-layers turn it on --offload-folder PATH spill directory; defaults to tempfile.mkdtemp() on the system disk (best per-window bandwidth, auto-cleaned). Override to put it on an external drive when the system disk is tight on space. --max-memory-gpu STR e.g. "4GiB"; budget for the accelerator --max-memory-cpu STR e.g. "2GiB"; budget for CPU before disk spill evaluate_model owns the t…66a0324 -
Eval: load in the model's native dtype, add --dtype CLI flag
The eval pipeline hardcoded torch_dtype=torch.float32, which made models >1-2B unrunnable on local Apple Silicon (3-7B in fp32 spills into swap and grinds to a halt). Switch to torch_dtype="auto" by default — Llama/Mistral/Gemma2/OLMo2/SmolLM2 load in bf16, Pythia in fp16, GPT-2 in fp32, matching each model's published dtype. NLL is still computed in fp32 inside HF's ForCausalLMLoss (it explicitly upcasts logits.float() before cross-entropy), so the perplexity numbers stay well-defined. low_cpu_mem_usage=True avoids the transient fp32 copy during from_pretrained, ~halving peak load memory. Add a --dtype CLI knob on run_eval.py (auto|bf16|fp16|fp32) threaded through to evaluate_model so a numerics reference run is one flag away. Also log dtype and device as MLflow params for reproducibility. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>937097a
-
Fix transform/primary path mismatch when revision is null
reprocess_metrics looked for {model} but primary writes {model}_main, so revision-less runs silently skipped (the Snakemake sentinel was still touched, hiding the breakage). Use the same "main" fallback string in both places. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>2dcdcdf -
Log P(W) and std summary plots as MLflow artifacts in transform step
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>2999fae -
Fix mlflow.log_input in all remaining pipeline scripts
Same fix as run_primary.py: mlflow.log_input expects mlflow.data.Dataset, not a raw DatasetInput entity. Use MlflowClient().log_inputs() throughout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>88dbab4 -
Fix two OLMo 2 pipeline failures
mlflow.log_input expects an mlflow.data.Dataset, not a raw DatasetInput entity — use MlflowClient().log_inputs() which takes the lower-level type directly. torch.linalg.svd uses LAPACK gesdd which fails to converge on ill-conditioned weight matrices seen in OLMo 2. Add _svd() helper that catches LinAlgError and retries via numpy.linalg.svd (gesvd driver, always converges). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7b59fb4
-
Fix cache-dir default to use existing downloads volume
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>43aa427 -
Make factored W_QK SVD the default; clean up experiment
Factor matrix SVD for W_QK is now unconditional — it replaces the full d_model×d_model SVD regardless of low_rank_svd_approximation. Experiment script no longer passes top_k_svd_d_head so the comparison is a pure A-B of the two SVD methods with no truncation confound. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>989c8e0 -
Match nominal revision when running truncated experiment
Read the revision from the nominal dataset's rows and pass it to process_model so both runs use identical model weights. Also update the truncated output path to reflect the actual revision label. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>abc312e -
Refactor experiment_svd_truncation to support multiple models
Accept --models and --nominal-dirs as parallel lists; run each model in sequence and write combined results.json and per_head_comparison.csv. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2192ae0 -
Add d_head metadata, top-k-svd-d-head option, and SVD truncation experiment
- Log d_head explicitly in metadata.json (correct for GQA models where d_head != d_model/n_heads); strip redundant head_dim alias from serialized output - Add top_k_svd_d_head param to process_model: enables low-rank SVD with N=d_head without needing to know d_head at call time - Expose --low-rank-svd, --top-k-svd, --top-k-svd-d-head in run_primary.py; log all three to MLflow - _get_d_head in cross_model.py reads d_head directly from metadata when available - Add scripts/experiment_svd_truncation.py: runs d_head-truncated pipeline, compares compute time and per-head singular value accuracy against nominal results on disk Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e9f64da -
Namespace all outputs under experiment_dir, add MLflow run metadata
All pipeline outputs and sentinels now live under {output_dir}/{mlflow_experiment}/ instead of scattered across the project root and output_dir. Prevents clobbering across experiments and mirrors the MLflow hierarchy. Changes: - Snakefile: derive config["experiment_dir"], pre-create it, override eval.out dynamically; update all sentinel expand() paths - rules/*: sentinel touch paths and inter-rule deps use experiment_dir; correlations/figures dirs moved under experiment_dir - config.yaml: remove hardcoded eval.out (now derived in Snakefile) - scripts/run_*.py: add mlflow.note.content description, model tag, and DatasetInput (local source → output path) to every run Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0bf8fb1
-
Add OLMo 2, Llama 3.2, Gemma 2, SmolLM2 to model registry
Registers 11 new models across four families, all targeting the final checkpoint only (revisions=[]). OLMo 2 (4 sizes, allenai/, not gated): reuses extract_llama_qkv — architecture confirmed identical to LLaMA layout (separate q/k/v proj under model.layers.{i}.self_attn.*). Llama 3.2 1B and 3B (meta-llama/, gated): reuses extract_llama_qkv. Gemma 2 2B and 9B (google/, gated): adds extract_gemma2_qkv which reads head_dim explicitly from config.json (256 for both sizes) rather than deriving it from hidden_size // n_heads — these differ for Gemma 2. Reuses extract_llama_o and extract_llama_biases (same key prefix, bias-free). SmolLM2 135M/360M/1.7B (HuggingFaceTB/, not gated, instruct variants): reuses extract_llama_qkv — registered as LlamaForCausalLM in transformers. Also adds _read_head_dim() helper and fixes d_head computation in head_pipeline, pair_pipeline, and fuse_timesteps to use hf_config.head_dim when present (Gemma 2) rather than always computing d_model // n_heads. Adds…3c24019 -
Fix W_QK computation and dashboard data loading
head_analyzer.py: restore original W_Q^T @ W_K formula giving (d_model, d_model) per head — the true bilinear form in token space. Commit 8ff6453 had changed this to W_Q @ W_K^T → (head_dim, head_dim) for memory savings, but that changed the mathematical object entirely and corrupted statistics for all models. run_merge.py: fix incremental merge to read existing metadata before rmtree/move so Pythia entries aren't dropped when adding new models; also fix atomic save via temp-path to avoid HF datasets self-overwrite error. dashboards: remove campaign concept throughout; all pages now load from OUTPUT_DIR via load_dataset_with_metadata(ds_name=...) with no campaign param. get_available_campaigns() removed. cross_model, sandbox, animations, step_evolution, weights_dashboard, singular_values all updated. config.yaml: drop 'all' from targets (target_all already composes families). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9c80428 -
Add smk_list.py: colorized snakemake --list wrapper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b9ecb4f -
Add MLflow logging to correlations and eval stages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>dbd0f5c -
Wire QK decomposition weight types into primary pipeline
W_Q_gram, W_K_gram, QK_alignment are already computed in head_analyzer.py. This commit exposes weight_types through config.yaml → run_primary.py → process_model() → primary.smk so they can be overridden at runtime. Tests updated to cover all 6 weight types; histogram test restricted to raw weight types since gram entries exceed standard bin range. compute_qk_decomposition.py removed (data now lives in primary dataset). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a07e79a -
Refactor eval to per-run parquets + merge_eval, remove -j1 constraint
Each eval job now writes outputs/eval/{run_key}.parquet independently. merge_eval concatenates them into the final artifact. eval_all depends on merge_eval output rather than individual sentinels. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f49060a -
Add drop_columns option to transform stage for refined dataset reduction
- reprocess_metrics(): drop_columns param strips named columns before saving the refined dataset; primary is never touched so columns are always recoverable - run_transform.py: --drop-columns passthrough, logged to MLflow - transform.smk: reads transform.drop_columns from config, builds --drop-columns flag - config.yaml: transform.drop_columns: [] with note on common candidates (P_w, w_bins) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>2f68beb -
Write transform output to separate _refined directory
- reprocess_metrics(): rename out_dir→in_dir, add out_dir for refined output. Defaults to {dataset_path}_refined. Copies metadata.json into refined dir. - run_transform.py: add --out-dir arg (default {dataset-dir}_refined); logs out_dir to MLflow. - transform.smk: passes --out-dir {output_dir}/{run_key}_refined explicitly. - dashboard_utils.py: prefer {ds_name}_refined path when loading locally, fall back to {ds_name}. - run_merge.py: cross_model_merge prefers {dir}_refined over primary dir. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>aaaf91c -
Rename src modules for head/pair symmetry; add pair_figures.smk; split eval_metrics
src/transformer_analysis/: weight_analysis → head_pipeline attn_head_analysis → head_analyzer metrics → head_metrics correlation_analysis → pair_pipeline head_correlations → pair_analyzer eval_metrics.py (new — implementation extracted from compute_perplexity.py) scripts/: plot_correlations.py → plot_pair_correlations.py plot_corr_figures.py → plot_pair_correlations_batch.py compute_perplexity.py → deleted (impl in eval_metrics; thin wrapper run_eval.py) run_eval.py (new thin wrapper) rules/: correlations.smk — switched to sentinel output (consistent with other rules) pair_figures.smk (new — regenerate pair figures from .npz without re-running correlations) eval.smk — updated to call run_eval.py Snakefile: added correlations_all, pair_figures_all convenience targets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a81fd74 -
Add eval.smk, fix correlations input, remove superseded scripts
- rules/eval.smk: wraps compute_perplexity.py per run; sentinel-based, depends on transform; eval_all convenience target in Snakefile - rules/correlations.smk: fix input to use transform sentinel instead of bare dataset directory (which Snakemake couldn't track) - config.yaml: add eval block (corpus, pile_tokens, pile_cache, out) - Delete run_weight_analysis.py, run_all_correlations.py, merge_datasets.py (superseded by run_primary.py, run_correlations.py, run_merge.py) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6ae3047 -
Remove histogram_utils shim; update all imports to metrics/model_registry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e750974 -
feat: add Snakemake pipeline, MLflow tracking, metrics refactor, tests
Pipeline / workflow: - Snakefile + config.yaml orchestrate primary → transform → merge stages - rules/primary.smk, transform.smk, correlations.smk, merge.smk - Sentinel-file pattern (done/*.done) avoids directory-output conflicts - Incremental cross-model merge: appends new models without clobbering; --refresh flag for explicit replacement after re-transform - Per-model checkpoint merge rule for Pythia step-collapse CLI wrappers (scripts/): - run_primary.py — process_model() + MLflow logging - run_transform.py — reprocess_metrics() + MLflow logging (git sha tagged) - run_correlations.py — thin wrapper for run_multi_circuit_analysis() - run_merge.py — cross-model incremental merge + checkpoint merge Metrics refactor: - src/transformer_analysis/metrics.py: canonical home for all stat functions, bin configs, normality_metrics, singular_value_metrics, and adaptive binning helpers (make_weight_bins, make_sv_bins) - histogram_utils.py: backward-compat re-export shim; no logic c…24e1932 -
fix: use train split for monology/pile-uncopyrighted (no test split exists)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>41816e0 -
fix: switch Pile corpus source to monology/pile-uncopyrighted (parquet)
EleutherAI/pile uses a dataset script which datasets >= 2.20 no longer supports. monology/pile-uncopyrighted is the same corpus hosted as parquet files with identical {"text": ...} schema. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9f2b93b
-
fix: replace hardcoded local paths with portable defaults in eval scripts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>da43dab -
chore: align download paths to /Flux/Projects/transformer-analysis/downloads
prepare_eval_corpus.py now writes corpus cache there by default. compute_perplexity.py --cache defaults to the same location. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>17a7cd2 -
feat: add pre-materialized Pile corpus cache for repeated eval runs
prepare_eval_corpus.py downloads a fixed gzipped JSONL sample from The Pile test split (default 500 MB, configurable). compute_perplexity.py loads from this cache via --pile-cache, avoiding streaming overhead on repeated runs. Falls back to live streaming with a warning when no cache is provided. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b7a7e36 -
feat: add eval metrics pipeline (perplexity, paper reference, dashboard overlay)
- compute_perplexity.py: sliding-window eval on WikiText-103 or Pile subset, configurable via --corpus/--pile-tokens; uses eval_loop + NLLCollector pattern designed for future data-weighted statistics (dressed operators <W_QK>_{data}) - extract_paper_loss.py: fetch HF model-card benchmarks and compare vs reference - paper_reference_loss.csv: reference loss values from literature for validation - load_eval_metrics() in dashboard_utils.py: graceful parquet loader - step_evolution.py: optional secondary-axis overlay of eval metrics vs step Output schema: model, revision, step, metric, value, source, corpus 43 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>17def50
-
feat: add configurable binning strategy hooks to histogram_utils
Adds make_weight_bins() and make_sv_bins() with 'fixed' (default, preserves existing behavior), 'scott', and 'fd' strategies. The fixed path returns the same arrays as the existing defaults. Adaptive strategies require a data sample at call time. Wired through process_model() and the run_weight_analysis.py CLI as --binning-strategy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>54eb2a2
-
removing script from version control; tweaking tab ordering in dashboard, weights first now
67efdf3 -
re-organizing workflow
eb2f1cd
-
multiple collected uupdates
7fcd2da
-
fix: recompute NPR in extract_sv_stat when stored column is null
f94f515
-
New head correlations functionality
aeef957
-
adding per model scale factor freedom; snapshot button in visuals
80f54d5
-
refactor and rename run and merge scripts
86b9635
-
tweaks for performance in production runs; updates to dashboards
28bc568
-
fixing typos in run/merge; updating dashboards to finally work on HF space
2164f3a -
smoothing workflow glitches
8200df9