Skip to content

feat(partition): per-block diagnostic floats + payoff measurement - #111

Merged
jascal merged 3 commits into
mainfrom
impl/encoding-partition-per-block-diagnostics
May 21, 2026
Merged

feat(partition): per-block diagnostic floats + payoff measurement#111
jascal merged 3 commits into
mainfrom
impl/encoding-partition-per-block-diagnostics

Conversation

@jascal

@jascal jascal commented May 21, 2026

Copy link
Copy Markdown
Owner

Summary

Two bundled pieces, both directly extending Phase 2 (#109):

  1. Per-block diagnostic floats — closes the Phase 2 v1 deferral. BlockReport.rank_ratio + post_A + informative_metric now populate end-to-end (forge_mse stays caller-provided like the top-level field).

  2. Partition payoff measurement — A/B comparison of uniform vs partitioned compression on a synth SAE, validating the proposal's projected substrate-cost reduction.

Per-block diagnostics

Each block's diagnostics are scoped to its own sliced sub-W_dec + per-block local plan, then computed via the same _compute_rank_ratio / _compute_post_A / _informative_metric helpers the top-level uses. Empty-block edge case (no clusters → all cross-block dropped) leaves diagnostics as None.

Two new tests:

  • test_block_report_diagnostic_floats_are_populated — sensible values (rank_ratio in [0,1], post_A finite, informative_metric in the expected literal set).
  • test_block_report_diagnostics_none_for_empty_blockNone for zero-cluster blocks.

Partition payoff measurement

uniform partition reduction
substrate cost (kept reps) 2048 slots 368 slots 5.6×
substrate cost (full SAE) 4096 slots 736 slots 5.6×

Setup: 32-feature × 64-d_model synth SAE; 16 pairs (2-feature clusters).

Run 1 (uniform Rung5): every feature gets the 128-slot encoding (current pre-partition workflow).
Run 2 (partitioned): 4 heavy features keep Rung5 (128-slot); 28 tail features drop to MPSRung1 (8-slot).

The 5.6× falls within the proposal's 5-10× projected range. Exact factor depends on heavy:tail ratio + encoding choice — a more realistic 0.5-2% heavy on a production SAE gives 10-20× reduction.

Caveats (documented in commit + script):

  • This is substrate cost (polygram Dictionary encoding budget), not forged-transformer parameter count. Forge-side savings depend on host-weight-projection through the basis; substrate reduction is necessary but not sufficient.
  • Per-block rank_ratio/post_A on this synth setup are degenerate (synth SAE is intentionally low-rank-ish for the test budget). On a real SAE-Lens-trained SAE, these diagnostics carry the per-block reconstruction-quality signal.

The measurement validates the partition feature's projected payoff at synth scale. The next experiment (out of scope) is the same A/B at GPT-2 + jbloom SAE scale once sae-forge's add-block-structured-sae Phase 2 wires the --encoding-partition CLI flag.

Artefacts

  • runs/partition_payoff_measurement.json (force-added) — the measurement output for the historical record.

Test plan

  • 2 new per-block-diagnostic tests pass.
  • Full polygram suite: 1079 → 1081 (no regressions).
  • Ruff clean.
  • Payoff measurement ran end-to-end on synth SAE; 5.6× reduction recorded.
  • CI verifies on Linux runners.

🤖 Generated with Claude Code

jascal and others added 2 commits May 21, 2026 11:23
Two bundled pieces:

1. Per-block diagnostic floats (closes Phase 2 v1 deferral)

   BlockReport.rank_ratio + post_A + informative_metric now populate
   end-to-end from _build_block_report. Each block's diagnostics are
   scoped to its own sliced sub-W_dec + per-block local plan, then
   computed via the same _compute_rank_ratio / _compute_post_A /
   _informative_metric helpers the top-level CompressionReport uses.

   Empty-block edge case: when a block has no clusters (e.g. all
   cross-block dropped), the diagnostics stay None. Tests:

     test_block_report_diagnostic_floats_are_populated — populated
       with sensible values (rank_ratio in [0,1], post_A finite,
       informative_metric in the expected literal set).
     test_block_report_diagnostics_none_for_empty_block — None for
       blocks with zero clusters.

   Phase 2 v1 BlockReport's None placeholders for rank_ratio / post_A /
   informative_metric are gone. forge_mse stays None — it's
   caller-provided (set by the host repo's forge pipeline), same as
   the top-level CompressionReport.forge_mse.

2. Partition payoff measurement (validates the substrate-cost projection)

   /tmp/partition_payoff_measurement.py (one-shot script; output
   persisted in runs/partition_payoff_measurement.json) compares
   two compressions of the same 32-feature × 64-d_model synth SAE:

     Run 1: uniform Rung5(n_amp_qubits=4) — every feature gets the
       128-slot encoding (current pre-partition workflow).
     Run 2: partitioned heavy(0..3)Rung5 + tail(4..31)MPSRung1 —
       4 heavy features keep the 128-slot capacity; 28 tail features
       drop to 8-slot capacity.

   Measured substrate cost (slots = encoding-slot-count × n_features):

                                  uniform    partition    reduction
     kept cluster reps only:       2048         368        5.6x
     full input SAE:               4096         736        5.6x

   The 5.6x falls within the proposal's 5-10x projected range. The
   exact factor depends on heavy:tail ratio and encoding choice —
   the synth setup here is 4:28 heavy:tail; a more realistic ratio
   (say 0.5%-2% heavy) would give 10-20x reduction on production
   SAEs.

   Important caveats noted in the script + this commit:
     - This is SUBSTRATE cost (polygram Dictionary encoding budget),
       not forged-transformer parameter count. The forge's
       parameter count depends on the projection of host weights
       through the basis; substrate reduction is necessary but not
       sufficient for forge-side savings.
     - Per-block rank_ratio/post_A on this synth setup are degenerate
       (very low rank_ratio, near-zero post_A) because the synth
       SAE is intentionally low-rank-ish for the test budget. On a
       real SAE-Lens-trained SAE, these diagnostics carry the
       per-block reconstruction-quality signal.

   The measurement validates the partition feature's projected
   payoff at synth scale. The next experiment (out of scope for
   this PR) is the same A/B at GPT-2 + jbloom SAE scale once
   sae-forge's add-block-structured-sae Phase 2 wires the
   --encoding-partition CLI flag.

Test count: 1079 -> 1081 (+2). Full suite green; ruff clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ran the proposal's projected payoff measurement against a real SAE
(jbloom GPT-2 first 64 features) with a heuristic partition (decoder
L2 norm × confirmed-pair count) and sae-forge's actual forge path.
Result: the partition reduces polygram-substrate cost as claimed,
but does NOT propagate to forge faithfulness in the current
sae-forge architecture.

Live measurement

  same input SAE, same ValidationReport from
  DecoderGeometryConfirmer (4 confirmed pairs at threshold 0.1):

  metric                           uniform     partition    reduction
  n_features_kept                  4           4             —
  n_clusters                       4           4             —
  substrate cost (kept reps)       512 slots   32 slots     16x
  substrate cost (full SAE)        8192 slots  992 slots    8.26x
  forge_faithfulness_kl            10.0484     10.0484      0.00%

Key finding: forge KL is IDENTICAL between uniform and partition.

Why

  sae-forge's ForgePipeline reads W_dec from the polygram-compressed
  safetensors. The polygram encoding family (Rung5 vs MPSRung1)
  affects only HOW the surviving features are surfaced as a polygram
  Dictionary — it does NOT change W_dec or the safetensors bytes
  the forge consumes. So the forged transformer is identical
  regardless of which encoding the partition chose.

  The partition's payoff (substrate cost reduction) is real and
  measurable at the polygram-Dictionary representation level. But
  the projected forge_kl improvement (5-10x → 10-30%) is based on
  an assumption that doesn't hold: encoding choice does not
  propagate through sae-forge today.

For the partition to actually lift forge faithfulness, sae-forge
needs to consume the per-block encoding info. That's the
unspecified work the add-block-structured-sae proposal hints at
but doesn't fully solve. Concrete possibilities:

  - Allocate different attention capacity per block in the forged
    transformer
  - Per-block axis-assignment during the projection step
  - Per-block sub-bases composed at forge time

None of these are in sae-forge today; they're open research questions.

Practical issues with heuristic partitioning on real SAEs

  Two findings about real SAE-Lens-trained SAEs vs synth:

  1. DecoderGeometryConfirmer is sparse on real SAEs. At threshold
     0.5, ZERO confirmed pairs were found on the 64-feature slice.
     SAE-Lens trains for feature orthogonality; the polygram
     'redundant pair' notion barely applies. Threshold had to drop
     to 0.1 to get 4 pairs.

  2. decoder_norm^2 is degenerate as a heaviness score. SAE-Lens
     normalises decoder rows to unit norm, so all features have
     decoder_norm = 1.0 exactly. The heaviness signal disappears.

  Real heuristic partitioning would need to use activation-side
  signals (firing rate, KL impact under ablation) computed from a
  BehaviouralValidator — much more expensive than geometry alone.

Recommendation

  Reframe the partition feature's value proposition:
    - WORKS: polygram-Dictionary substrate cost reduction
      (validated at 8-16x here).
    - DOES NOT WORK (yet): forge-side payoff through sae-forge.
      Requires sae-forge to wire per-block encoding consumption
      into the forge pipeline. That's a separate proposal worth
      filing if forge-side payoff is desired.

  The partition feature is still valuable for analysts inspecting
  polygram-compressed SAEs — the BlockReport surfaces per-block
  cluster diagnostics + scale_compression_ratio + rank_ratio that
  aren't otherwise available. Just don't expect the forge to
  honor the encoding choice today.

Artefacts

  - runs/real_partition_experiment.json (full measurement output)
  - runs/real_partition_experiment.py (the script; reproducible
    against a fresh sae-forge venv with the jbloom SAE cached)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jascal

jascal commented May 21, 2026

Copy link
Copy Markdown
Owner Author

Reality check: real-SAE A/B reveals the partition is polygram-only

Per request, ran the production-scale experiment with a real SAE (jbloom GPT-2 first 64 features), heuristic-driven partition (decoder L2 × pair count), real DecoderGeometryConfirmer ValidationReport, and a full sae-forge ForgePipeline.run_synthetic on both compressions.

Findings

metric uniform Rung5 partition heavy/tail reduction
substrate cost (kept reps) 512 slots 32 slots 16×
substrate cost (full SAE) 8192 slots 992 slots 8.26×
forge_faithfulness_kl 10.0484 10.0484 0% (identical!)

The partition reduces polygram-Dictionary substrate cost as projected, but does NOT lift forge faithfulness in the current sae-forge pipeline.

Mechanism

sae-forge reads W_dec from the polygram-compressed safetensors. The polygram encoding family choice doesn't affect W_dec. So the partition's encoding-family decisions are invisible to the forge as currently wired.

The proposal's projected forge_faithfulness_kl improvement (10-30%) was based on an assumption that encoding choice propagates through sae-forge — it doesn't, today.

What this PR is + isn't

This PR still ships the per-block diagnostic floats (Phase 2 v1 deferral) — those are mechanically correct and useful. What it does NOT validate is the proposal's forge-side payoff claim. That claim needs separate work in sae-forge (per-block encoding consumption in the forge pipeline).

Reframing the partition feature's value:

  • ✅ Polygram-Dictionary substrate cost reduction (validated at 8-16×)
  • ✅ Per-block diagnostic visibility for analysts (BlockReport surfaces metrics not otherwise available)
  • ❌ Forge-side payoff (needs sae-forge wiring; out of scope for polygram-only changes)

Also revealed (practical issues for partition heuristics)

  1. DecoderGeometryConfirmer is sparse on real SAE-Lens SAEs (0 pairs at threshold 0.5; 4 pairs at 0.1). SAE-Lens trains for orthogonality; geometry-based confirmation barely applies.
  2. decoder_norm² is degenerate as a heaviness signal — SAE-Lens normalises decoder rows to unit norm. A real heuristic partition needs activation-side signals (firing rate, KL impact under ablation).

Artefacts

  • runs/real_partition_experiment.json — full measurement output.
  • runs/real_partition_experiment.py — the reproducible script.

Recommendation

Honest framing: this experiment is more valuable as a negative result than as validation of the proposal's projected payoff. The partition feature works at the polygram level but doesn't automatically improve forge quality. That requires deliberate sae-forge work that's not yet specified.

Updates CHANGELOG to reflect what the real-SAE experiment revealed:

  - WORKS: per-block diagnostics (rank_ratio, post_A,
    informative_metric on BlockReport) + polygram-Dictionary
    substrate cost reduction (8-16x measured on real SAE).

  - UNPROVEN: forge-side payoff. The polygram encoding-family
    choice does not propagate through sae-forge's current forge
    path. The proposal's projected 10-30% forge KL lift is not
    supported by the measurement — uniform and partitioned
    compressions produce IDENTICAL forge_faithfulness_kl
    (10.0484 in both A/B runs).

The skeptical-path framing: this is a useful negative result, not
a failure. The partition feature is valuable as a polygram-side
analyst tool. The hypothesised forge-side payoff requires separate
sae-forge work that nobody has specified yet — and may not be the
right investment to make.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jascal
jascal merged commit 8d73844 into main May 21, 2026
2 checks passed
@jascal
jascal deleted the impl/encoding-partition-per-block-diagnostics branch May 21, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant