Module neuralops.tests.test_salt_f
Functions
def test_attention_aware_gamma_init()-
Expand source code
def test_attention_aware_gamma_init(): """Gamma init from sensitivity changes the values.""" W = torch.randn(64, 64) layer = SALTLinear(64, 64, rank=16, original_weight=W) # Default gamma = 1 assert (layer.gamma == 1.0).all() # Set custom sensitivity sens = torch.tensor([1.0] * 8 + [10.0] * 8) layer.init_gamma_from_sensitivity(sens) # High sensitivity should give higher gamma assert layer.gamma[8:].mean() > layer.gamma[:8].mean() print("[OK] test_attention_aware_gamma_init")Gamma init from sensitivity changes the values.
def test_fisher_weighted_svd()-
Expand source code
def test_fisher_weighted_svd(): """Fisher weighting changes the SVD.""" W = torch.randn(64, 64) F = torch.ones(64) F[10:20] = 100.0 # some high-activation dims layer_fisher = SALTLinear(64, 64, rank=16, original_weight=W, fisher_diag=F) layer_plain = SALTLinear(64, 64, rank=16, original_weight=W, fisher_diag=None) # Different SVD directions should be captured diff = (layer_fisher.U - layer_plain.U).abs().mean() assert diff > 0.01, "Fisher should change U" print(f"[OK] test_fisher_weighted_svd (diff={diff:.4f})")Fisher weighting changes the SVD.
def test_merge_model()-
Expand source code
def test_merge_model(): """merge_model_salt replaces SALTLinear with nn.Linear.""" class TestModel(nn.Module): def __init__(self): super().__init__() self.q = SALTLinear(32, 32, rank=8) def forward(self, x): return self.q(x) model = TestModel() merged = merge_model_salt(model) assert isinstance(merged.q, nn.Linear), \ f"Expected nn.Linear, got {type(merged.q)}" print("[OK] test_merge_model")merge_model_salt replaces SALTLinear with nn.Linear.
def test_merge_to_linear()-
Expand source code
def test_merge_to_linear(): """Merged linear produces the same output.""" W = torch.randn(64, 64) layer = SALTLinear(64, 64, rank=16, original_weight=W) x = torch.randn(2, 8, 64) out_before = layer(x) merged = layer.merge_to_linear() out_after = merged(x) err = (out_before - out_after).norm() / (out_before.norm() + 1e-8) assert err < 1e-5, f"Merge error too high: {err}" print(f"[OK] test_merge_to_linear (err={err:.2e})")Merged linear produces the same output.
def test_per_projection_adaptive_rank()-
Expand source code
def test_per_projection_adaptive_rank(): """Different projections get different ranks.""" class FakeConfig: num_attention_heads = 4 hidden_size = 64 head_dim = 16 attn = SALTAttention(config=FakeConfig(), rank=16) ranks = attn.proj_ranks # Just verify all keys exist and are positive assert all(r > 0 for r in ranks.values()) print(f"[OK] test_per_projection_adaptive_rank (ranks={ranks})")Different projections get different ranks.
def test_registry_registration()-
Expand source code
def test_registry_registration(): """SALT keys are registered.""" from neuralops.core.registry import ATTENTION_REGISTRY assert "salt" in ATTENTION_REGISTRY assert "salt_attention" in ATTENTION_REGISTRY assert "salt_f" in ATTENTION_REGISTRY assert "salt_f_attention" in ATTENTION_REGISTRY print("[OK] test_registry_registration")SALT keys are registered.
def test_salt_linear_construction()-
Expand source code
def test_salt_linear_construction(): """Basic SALTLinear construction.""" W = torch.randn(64, 64) layer = SALTLinear(64, 64, rank=16, original_weight=W) assert layer.rank == 16 print("[OK] test_salt_linear_construction")Basic SALTLinear construction.
def test_salt_linear_init_recovers_W_r()-
Expand source code
def test_salt_linear_init_recovers_W_r(): """Init should give W_r (truncated SVD).""" W = torch.randn(64, 64) layer = SALTLinear(64, 64, rank=16, original_weight=W) W_r = layer.weight # Compare with truncated SVD U, S, Vt = torch.linalg.svd(W, full_matrices=False) W_r_expected = (U[:, :16] * S[:16].unsqueeze(0)) @ Vt[:16, :] err = (W_r - W_r_expected).norm() / (W_r_expected.norm() + 1e-8) assert err < 1e-5, f"Init should match W_r, err={err}" print(f"[OK] test_salt_linear_init_recovers_W_r (err={err:.2e})")Init should give W_r (truncated SVD).