Download tests/test_memory.py from thefinalboss/fractus-cte: direct link, hf CLI and curl.
- Browser
- Download file 7.81 kB
-
https://huggingface.co/thefinalboss/fractus-cte/resolve/e9191b613b308720b389751cac9e8ad208363bed/tests/test_memory.py
- Command line
-
hf download hf://thefinalboss/fractus-cte@e9191b613b308720b389751cac9e8ad208363bed/tests/test_memory.py
-
curl -L -o test_memory.py https://huggingface.co/thefinalboss/fractus-cte/resolve/e9191b613b308720b389751cac9e8ad208363bed/tests/test_memory.py
7.81 kB
| """Tests for PersistentMemory (isolated from the engine).""" | |
| import tempfile, os | |
| import torch | |
| import pytest | |
| from fractus.memory import PersistentMemory | |
| def test_memory_recall_topk(): | |
| mem = PersistentMemory(d_model=5, max_memories=10) | |
| # Store 5 vectors; query should rank the closest first. | |
| for i in range(5): | |
| v = torch.zeros(5); v[i] = 1.0 | |
| mem.consolidate(v, context=f"mem{i}", importance=0.5) | |
| query = torch.zeros(5); query[0] = 1.0 # identical to mem0 | |
| results = mem.recall(query, top_k=3) | |
| assert len(results) == 3 | |
| assert results[0][0] == "mem0" # highest cosine | |
| assert results[0][1] > results[1][1] # descending | |
| def test_memory_consolidate_lru(): | |
| mem = PersistentMemory(d_model=4, max_memories=3) | |
| for i in range(5): | |
| mem.consolidate(torch.randn(4), context=f"mem{i}", importance=float(i) / 10) | |
| assert len(mem) == 3 | |
| # Lowest importance (mem0, imp=0.0) should have been evicted. | |
| contexts = mem.contexts | |
| assert "mem0" not in contexts | |
| def test_memory_save_load_roundtrip(): | |
| with tempfile.TemporaryDirectory() as d: | |
| path = os.path.join(d, "mem.pt") | |
| mem = PersistentMemory(d_model=4, max_memories=10, path=path) | |
| mem.consolidate(torch.tensor([1.0, 0, 0, 0]), context="hello", importance=0.8) | |
| mem.save() | |
| mem2 = PersistentMemory(d_model=4, max_memories=10, path=path) | |
| assert len(mem2) == 1 | |
| assert mem2.contexts[0] == "hello" | |
| assert torch.allclose(mem2.vectors[0], torch.tensor([1.0, 0, 0, 0])) | |
| def test_memory_inject_blend_ratio(): | |
| """inject with blend=0.05 → thought_state is 95% original + 5% memory.""" | |
| mem = PersistentMemory(d_model=4, max_memories=10) | |
| mem.consolidate(torch.tensor([0.0, 0.0, 0.0, 10.0]), context="big", importance=1.0) | |
| class FakeEngine: | |
| def __init__(self): | |
| self.thought_state = torch.tensor([[[1.0, 1.0, 1.0, 1.0]]]) # (1,1,4) | |
| eng = FakeEngine() | |
| before = eng.thought_state.clone() | |
| mem.inject(eng, blend=0.05, top_k=1) | |
| after = eng.thought_state | |
| # The memory vector is [0,0,0,10]; recalled contribution pushes toward it. | |
| # dim 3 (index 3) should increase strongly, while dims 0-2 should move only | |
| # by the (1-blend) shrinkage (~0.05 at blend=0.05), since the memory is 0 | |
| # there. The blend is convex: new = (1-blend)*thought + blend*memory. | |
| assert after[0, 0, 3] > before[0, 0, 3] # memory's non-zero dim increased | |
| # dims 0-2 are barely affected (small shrinkage, not a memory-driven push) | |
| assert abs(after[0, 0, 0].item() - before[0, 0, 0].item()) < 0.1 | |
| def test_memory_consolidate_if_salient_threshold(): | |
| mem = PersistentMemory(d_model=4, max_memories=10) | |
| v = torch.tensor([1.0, 0, 0, 0]) | |
| # Below threshold → no write. | |
| wrote = mem.consolidate_if_salient(v, salience_score=0.3, context="low") | |
| assert wrote is False | |
| assert len(mem) == 0 | |
| # Above threshold → write. | |
| wrote = mem.consolidate_if_salient(v, salience_score=0.9, context="high") | |
| assert wrote is True | |
| assert len(mem) == 1 | |
| def test_memory_consolidate_if_salient_dedup(): | |
| mem = PersistentMemory(d_model=4, max_memories=10) | |
| v = torch.tensor([1.0, 0, 0, 0]) | |
| mem.consolidate_if_salient(v, salience_score=0.9, context="first") | |
| # Same vector again (cosine ~1.0, within min_distance) → no write. | |
| wrote = mem.consolidate_if_salient(v, salience_score=0.9, context="dup", | |
| min_distance=0.1) | |
| assert wrote is False | |
| assert len(mem) == 1 | |
| # Different vector (cosine < 1 - min_distance) → write. | |
| v2 = torch.tensor([0.0, 1.0, 0, 0]) | |
| wrote = mem.consolidate_if_salient(v2, salience_score=0.9, context="new", | |
| min_distance=0.1) | |
| assert wrote is True | |
| assert len(mem) == 2 | |
| def test_cte_has_salience_head_and_memory_slot(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| assert hasattr(eng, "salience_head") | |
| assert hasattr(eng, "memory") | |
| assert eng.memory is None | |
| assert eng.memory_active is True | |
| def test_cte_attach_detach_memory(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| mem = PersistentMemory(d_model=128, max_memories=10) | |
| eng.attach_memory(mem) | |
| assert eng.memory is mem | |
| eng.detach_memory() | |
| assert eng.memory is None | |
| def test_cte_salience_head_outputs_in_range(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| eng.reset_thought(batch_size=1) | |
| obs = torch.tensor([42], dtype=torch.long) | |
| eng.tick(obs) | |
| # salience_head output is captured during tick; we check via a direct call. | |
| with torch.no_grad(): | |
| score = torch.sigmoid(eng.salience_head(eng.thought_state[:, 0, :])) | |
| assert 0.0 <= score.item() <= 1.0 | |
| def test_cte_consolidates_when_salient(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| # Force salience_head to output ~1.0 (set bias high). | |
| with torch.no_grad(): | |
| eng.salience_head.bias.fill_(10.0) | |
| mem = PersistentMemory(d_model=128, max_memories=10) | |
| eng.attach_memory(mem) | |
| eng.reset_thought(batch_size=1) | |
| obs = torch.tensor([42], dtype=torch.long) | |
| eng.tick(obs) | |
| assert len(mem) > 0, "should have consolidated a salient thought" | |
| def test_cte_skips_consolidate_when_not_salient(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| # Force salience_head to output ~0.0 (set bias very negative). | |
| with torch.no_grad(): | |
| eng.salience_head.bias.fill_(-10.0) | |
| mem = PersistentMemory(d_model=128, max_memories=10) | |
| eng.attach_memory(mem) | |
| eng.reset_thought(batch_size=1) | |
| obs = torch.tensor([42], dtype=torch.long) | |
| eng.tick(obs) | |
| assert len(mem) == 0, "should NOT have consolidated a non-salient thought" | |
| def test_cte_memory_active_toggle(): | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| eng = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, n_heads=2, d_head=64, n_levels=2, | |
| n_oscillators=8, coupling_rank=4, n_experts=4, top_k=2, | |
| expert_d_ff=128, siren_rank=32, | |
| ) | |
| with torch.no_grad(): | |
| eng.salience_head.bias.fill_(10.0) # salient | |
| mem = PersistentMemory(d_model=128, max_memories=10) | |
| eng.attach_memory(mem) | |
| eng.memory_active = False # disabled | |
| eng.reset_thought(batch_size=1) | |
| obs = torch.tensor([42], dtype=torch.long) | |
| eng.tick(obs) | |
| assert len(mem) == 0, "memory_active=False should prevent consolidation" | |