Commit
·
59effb8
1
Parent(s):
b350371
tests
Browse files- app.py +0 -1
- cognitive_mapping_probe/__pycache__/concepts.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/llm_iface.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/orchestrator.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/prompts.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/resonance.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/utils.cpython-310.pyc +0 -0
- cognitive_mapping_probe/__pycache__/verification.cpython-310.pyc +0 -0
- tests/conftest.py +0 -70
- tests/test_core_logic.py +0 -125
app.py
CHANGED
|
@@ -104,7 +104,6 @@ with gr.Blocks(theme=theme, title="Cognitive Breaking Point Probe") as demo:
|
|
| 104 |
headers=["concept", "strength", "responded", "termination_reason", "generated_text"],
|
| 105 |
label="Detailed Run Data",
|
| 106 |
wrap=True,
|
| 107 |
-
height=400
|
| 108 |
)
|
| 109 |
with gr.Accordion("Raw JSON Output", open=False):
|
| 110 |
raw_json_output = gr.JSON()
|
|
|
|
| 104 |
headers=["concept", "strength", "responded", "termination_reason", "generated_text"],
|
| 105 |
label="Detailed Run Data",
|
| 106 |
wrap=True,
|
|
|
|
| 107 |
)
|
| 108 |
with gr.Accordion("Raw JSON Output", open=False):
|
| 109 |
raw_json_output = gr.JSON()
|
cognitive_mapping_probe/__pycache__/concepts.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/concepts.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/concepts.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/llm_iface.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/llm_iface.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/llm_iface.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/orchestrator.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/orchestrator.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/orchestrator.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/prompts.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/prompts.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/prompts.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/resonance.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/resonance.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/resonance.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/utils.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/utils.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/utils.cpython-310.pyc differ
|
|
|
cognitive_mapping_probe/__pycache__/verification.cpython-310.pyc
CHANGED
|
Binary files a/cognitive_mapping_probe/__pycache__/verification.cpython-310.pyc and b/cognitive_mapping_probe/__pycache__/verification.cpython-310.pyc differ
|
|
|
tests/conftest.py
DELETED
|
@@ -1,70 +0,0 @@
|
|
| 1 |
-
import pytest
|
| 2 |
-
import torch
|
| 3 |
-
from types import SimpleNamespace
|
| 4 |
-
from cognitive_mapping_probe.llm_iface import LLM
|
| 5 |
-
|
| 6 |
-
@pytest.fixture(scope="session")
|
| 7 |
-
def mock_llm_config():
|
| 8 |
-
"""Stellt eine minimale, Schein-Konfiguration für das LLM bereit."""
|
| 9 |
-
return SimpleNamespace(
|
| 10 |
-
hidden_size=128, # Kleinere Größe für schnelle Tests
|
| 11 |
-
num_hidden_layers=4,
|
| 12 |
-
num_attention_heads=4
|
| 13 |
-
)
|
| 14 |
-
|
| 15 |
-
@pytest.fixture
|
| 16 |
-
def mock_llm(mocker, mock_llm_config):
|
| 17 |
-
"""
|
| 18 |
-
Dies ist die wichtigste Fixture. Sie erstellt einen "Mock-LLM".
|
| 19 |
-
Anstatt ein echtes Modell von Hugging Face zu laden (was langsam ist und eine GPU erfordert),
|
| 20 |
-
simulieren wir sein Verhalten. Wir verwenden `mocker.patch`, um die echte Ladefunktion
|
| 21 |
-
`get_or_load_model` abzufangen und stattdessen unsere schnelle Mock-Instanz zurückzugeben.
|
| 22 |
-
"""
|
| 23 |
-
# Erstelle eine Schein-Tokenizer-Instanz
|
| 24 |
-
mock_tokenizer = mocker.MagicMock()
|
| 25 |
-
mock_tokenizer.eos_token_id = 1
|
| 26 |
-
mock_tokenizer.decode.return_value = "mocked text"
|
| 27 |
-
|
| 28 |
-
# Erstelle ein Schein-Modell-Objekt
|
| 29 |
-
mock_model = mocker.MagicMock()
|
| 30 |
-
|
| 31 |
-
# Konfiguriere das Schein-Modell so, dass es auf Aufrufe mit plausiblen Tensoren antwortet
|
| 32 |
-
def mock_model_forward(*args, **kwargs):
|
| 33 |
-
batch_size = 1
|
| 34 |
-
seq_len = kwargs.get("input_ids", torch.tensor([[0]])).shape[1]
|
| 35 |
-
|
| 36 |
-
# Simuliere die Ausgaben eines echten Transformer-Modells
|
| 37 |
-
mock_outputs = {
|
| 38 |
-
"hidden_states": tuple(
|
| 39 |
-
[torch.randn(batch_size, seq_len, mock_llm_config.hidden_size) for _ in range(mock_llm_config.num_hidden_layers + 1)]
|
| 40 |
-
),
|
| 41 |
-
"past_key_values": tuple(
|
| 42 |
-
[
|
| 43 |
-
(torch.randn(batch_size, mock_llm_config.num_attention_heads, seq_len, 16),
|
| 44 |
-
torch.randn(batch_size, mock_llm_config.num_attention_heads, seq_len, 16))
|
| 45 |
-
for _ in range(mock_llm_config.num_hidden_layers)
|
| 46 |
-
]
|
| 47 |
-
),
|
| 48 |
-
"logits": torch.randn(batch_size, seq_len, 32000) # Schein-Vokabulargröße
|
| 49 |
-
}
|
| 50 |
-
return SimpleNamespace(**mock_outputs)
|
| 51 |
-
|
| 52 |
-
mock_model.return_value = mock_model_forward
|
| 53 |
-
mock_model.config = mock_llm_config
|
| 54 |
-
mock_model.device = 'cpu'
|
| 55 |
-
|
| 56 |
-
# Erstelle eine Instanz unserer LLM-Klasse, aber mit den gemockten Komponenten
|
| 57 |
-
llm_instance = LLM.__new__(LLM)
|
| 58 |
-
llm_instance.model = mock_model
|
| 59 |
-
llm_instance.tokenizer = mock_tokenizer
|
| 60 |
-
llm_instance.config = mock_llm_config
|
| 61 |
-
llm_instance.seed = 42
|
| 62 |
-
llm_instance.set_all_seeds = mocker.MagicMock() # Mocke die Seeding-Funktion
|
| 63 |
-
|
| 64 |
-
# Der entscheidende Schritt: Patch die Ladefunktion, damit jeder Code, der sie aufruft,
|
| 65 |
-
# stattdessen unsere Mock-Instanz erhält.
|
| 66 |
-
mocker.patch('cognitive_mapping_probe.llm_iface.get_or_load_model', return_value=llm_instance)
|
| 67 |
-
mocker.patch('cognitive_mapping_probe.orchestrator.get_or_load_model', return_value=llm_instance)
|
| 68 |
-
mocker.patch('cognitive_mapping_probe.concepts.get_or_load_model', return_value=llm_instance)
|
| 69 |
-
|
| 70 |
-
return llm_instance
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tests/test_core_logic.py
DELETED
|
@@ -1,125 +0,0 @@
|
|
| 1 |
-
import torch
|
| 2 |
-
import pytest
|
| 3 |
-
from types import SimpleNamespace
|
| 4 |
-
|
| 5 |
-
from cognitive_mapping_probe.concepts import get_concept_vector
|
| 6 |
-
from cognitive_mapping_probe.resonance import run_silent_cogitation
|
| 7 |
-
from cognitive_mapping_probe.verification import generate_spontaneous_text
|
| 8 |
-
from cognitive_mapping_probe.orchestrator import run_cognitive_titration_experiment
|
| 9 |
-
|
| 10 |
-
def test_get_concept_vector(mock_llm):
|
| 11 |
-
"""
|
| 12 |
-
Testet die `get_concept_vector` Funktion.
|
| 13 |
-
ASSERT: Gibt einen Tensor der korrekten Form zurück, der nicht null ist.
|
| 14 |
-
"""
|
| 15 |
-
concept_vector = get_concept_vector(mock_llm, "test_concept")
|
| 16 |
-
|
| 17 |
-
assert isinstance(concept_vector, torch.Tensor)
|
| 18 |
-
assert concept_vector.shape == (mock_llm.config.hidden_size,)
|
| 19 |
-
assert torch.norm(concept_vector).item() > 0
|
| 20 |
-
|
| 21 |
-
def test_run_silent_cogitation_max_steps(mock_llm):
|
| 22 |
-
"""
|
| 23 |
-
Testet `run_silent_cogitation` im Standardfall (erreicht `max_steps`).
|
| 24 |
-
ASSERT: Läuft fehlerfrei durch und gibt 'max_steps_reached' zurück.
|
| 25 |
-
"""
|
| 26 |
-
_, _, _, termination_reason = run_silent_cogitation(
|
| 27 |
-
llm=mock_llm,
|
| 28 |
-
prompt_type="resonance_prompt",
|
| 29 |
-
num_steps=10,
|
| 30 |
-
temperature=0.7
|
| 31 |
-
)
|
| 32 |
-
assert termination_reason == "max_steps_reached"
|
| 33 |
-
|
| 34 |
-
def test_run_silent_cogitation_convergence(mock_llm, mocker):
|
| 35 |
-
"""
|
| 36 |
-
Testet den Konvergenzfall in `run_silent_cogitation`.
|
| 37 |
-
Wir patchen hier die `lm_head`-Ausgabe des Modells so, dass sie nach wenigen Schritten
|
| 38 |
-
einen stabilen Zustand erzwingt.
|
| 39 |
-
ASSERT: Die Funktion erkennt die Konvergenz korrekt und gibt 'converged' zurück.
|
| 40 |
-
"""
|
| 41 |
-
stable_hidden_state = torch.ones(1, 1, mock_llm.config.hidden_size)
|
| 42 |
-
|
| 43 |
-
# Mocke die Modell-Ausgaben, um Konvergenz zu simulieren
|
| 44 |
-
def convergence_side_effect(*args, **kwargs):
|
| 45 |
-
# Nach dem 5. Schritt geben wir immer denselben Zustand zurück
|
| 46 |
-
if 'past_key_values' in kwargs and kwargs['past_key_values'][0][0].shape[-2] > 5:
|
| 47 |
-
return SimpleNamespace(
|
| 48 |
-
hidden_states=(None,) * (mock_llm.config.num_hidden_layers + 1) + (stable_hidden_state,),
|
| 49 |
-
past_key_values=kwargs['past_key_values'],
|
| 50 |
-
logits=torch.randn(1, 1, 32000)
|
| 51 |
-
)
|
| 52 |
-
# Ansonsten normales Verhalten
|
| 53 |
-
return mock_llm.model.return_value(*args, **kwargs)
|
| 54 |
-
|
| 55 |
-
mock_llm.model.side_effect = convergence_side_effect
|
| 56 |
-
|
| 57 |
-
_, _, _, termination_reason = run_silent_cogitation(
|
| 58 |
-
llm=mock_llm,
|
| 59 |
-
prompt_type="resonance_prompt",
|
| 60 |
-
num_steps=20, # Mehr Schritte als nötig, um Konvergenz zu testen
|
| 61 |
-
temperature=0.7
|
| 62 |
-
)
|
| 63 |
-
assert termination_reason == "converged"
|
| 64 |
-
|
| 65 |
-
def test_generate_spontaneous_text(mock_llm):
|
| 66 |
-
"""
|
| 67 |
-
Testet die manuelle Textgenerierung.
|
| 68 |
-
ASSERT: Generiert einen nicht-leeren String.
|
| 69 |
-
"""
|
| 70 |
-
# Erstelle plausible Schein-Eingaben
|
| 71 |
-
dummy_state = torch.randn(1, 1, mock_llm.config.hidden_size)
|
| 72 |
-
dummy_kv_cache = tuple(
|
| 73 |
-
[
|
| 74 |
-
(torch.randn(1, mock_llm.config.num_attention_heads, 10, 16),
|
| 75 |
-
torch.randn(1, mock_llm.config.num_attention_heads, 10, 16))
|
| 76 |
-
for _ in range(mock_llm.config.num_hidden_layers)
|
| 77 |
-
]
|
| 78 |
-
)
|
| 79 |
-
|
| 80 |
-
text = generate_spontaneous_text(mock_llm, dummy_state, dummy_kv_cache, max_new_tokens=5)
|
| 81 |
-
|
| 82 |
-
assert isinstance(text, str)
|
| 83 |
-
assert text == "mocked text" # Unser Mock-Tokenizer gibt immer diesen Text zurück
|
| 84 |
-
|
| 85 |
-
def test_orchestrator_logic(mocker, mock_llm):
|
| 86 |
-
"""
|
| 87 |
-
Dies ist ein Integrationstest für den Orchestrator. Wir testen seine *Logik*,
|
| 88 |
-
indem wir seine teuren Abhängigkeiten (`run_silent_cogitation`) mocken.
|
| 89 |
-
Wir simulieren ein Szenario, in dem das Modell bei Stärke >= 1.5 "bricht".
|
| 90 |
-
ASSERT: Der Orchestrator zeichnet die Ergebnisse korrekt auf.
|
| 91 |
-
"""
|
| 92 |
-
# Mocke die `run_silent_cogitation`, um ihr Verhalten zu kontrollieren
|
| 93 |
-
def cognition_side_effect(*args, injection_strength=0.0, **kwargs):
|
| 94 |
-
reason = "converged" if injection_strength < 1.5 else "max_steps_reached"
|
| 95 |
-
# Gebe Schein-Tensoren zurück, die die richtige Struktur haben
|
| 96 |
-
return (
|
| 97 |
-
torch.randn(1, 1, mock_llm.config.hidden_size), # final_hidden_state
|
| 98 |
-
mocker.MagicMock(), # final_kv_cache
|
| 99 |
-
torch.tensor([[0]]), # final_token_id
|
| 100 |
-
reason
|
| 101 |
-
)
|
| 102 |
-
|
| 103 |
-
mocker.patch('cognitive_mapping_probe.orchestrator.run_silent_cogitation', side_effect=cognition_side_effect)
|
| 104 |
-
mocker.patch('cognitive_mapping_probe.orchestrator.generate_spontaneous_text', return_value="generated")
|
| 105 |
-
|
| 106 |
-
# Führe das Experiment mit den gemockten Funktionen aus
|
| 107 |
-
results = run_cognitive_titration_experiment(
|
| 108 |
-
model_id="mock_model",
|
| 109 |
-
prompt_type="resonance_prompt",
|
| 110 |
-
seed=42,
|
| 111 |
-
concepts_str="test",
|
| 112 |
-
strength_levels_str="0.0, 1.0, 1.5, 2.0",
|
| 113 |
-
num_steps=10,
|
| 114 |
-
temperature=0.7,
|
| 115 |
-
progress_callback=mocker.MagicMock() # Mocke auch den Progress-Callback
|
| 116 |
-
)
|
| 117 |
-
|
| 118 |
-
runs = results["runs"]
|
| 119 |
-
assert len(runs) == 4
|
| 120 |
-
|
| 121 |
-
# Überprüfe die Ergebnisse basierend auf unserer Mock-Logik
|
| 122 |
-
assert runs[0]['strength'] == 0.0 and runs[0]['termination_reason'] == 'converged' and runs[0]['responded'] is True
|
| 123 |
-
assert runs[1]['strength'] == 1.0 and runs[1]['termination_reason'] == 'converged' and runs[1]['responded'] is True
|
| 124 |
-
assert runs[2]['strength'] == 1.5 and runs[2]['termination_reason'] == 'max_steps_reached' and runs[2]['responded'] is False
|
| 125 |
-
assert runs[3]['strength'] == 2.0 and runs[3]['termination_reason'] == 'max_steps_reached' and runs[3]['responded'] is False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|