File size: 3,611 Bytes
45424d1
 
 
095bd48
 
45424d1
095bd48
45424d1
 
095bd48
45424d1
 
 
 
 
 
095bd48
45424d1
 
 
 
 
095bd48
 
45424d1
 
 
 
 
 
 
 
 
 
095bd48
45424d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
095bd48
45424d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# app.py  (Hugging Face Space - runs GPT-2 + TransformerLens locally)
import os
import json
import streamlit as st
import requests
from datetime import datetime

# Import your model utilities (make sure model_utils.py is in the same repo on HF)
from model_utils import generate_text, run_activation_patching  # uploaded at /mnt/data/model_utils.py

# Configure Render URL (set your actual Render URL here)
# Example: https://activation-patching-api.onrender.com
RENDER_API_BASE = st.secrets.get("render_url") or st.sidebar.text_input(
    "Render API base URL", value="https://activation-patching-api.onrender.com"
)
SAVE_ENDPOINT = RENDER_API_BASE.rstrip("/") + "/save"

st.title("Mechanistic Analysis Interface (HF Space)")
st.write("This Streamlit app runs GPT-2 + activation patching locally, then saves metadata to your Render backend.")

prompt = st.text_area("Enter your sentence / prompt", height=150)
max_length = st.sidebar.slider("Max generation length", 20, 200, 60)

if st.button("Run Experiment"):
    if not prompt.strip():
        st.warning("Please enter a prompt.")
    else:
        with st.spinner("Generating text with GPT-2..."):
            try:
                generated = generate_text(prompt, max_length=max_length)
            except Exception as e:
                st.error(f"Error running generation: {e}")
                raise

        st.subheader("Generated Text")
        st.write(generated)

        with st.spinner("Running activation patching (TransformerLens)..."):
            try:
                activations = run_activation_patching(prompt)
            except Exception as e:
                st.error(f"Error running activation patching: {e}")
                raise

        st.subheader("Activation traces (sample)")
        # activations can be large — summarize for display
        sample = {k: (v.shape if hasattr(v, "shape") else type(v).__name__) for k, v in list(activations.items())[:10]}
        st.json(sample)

        # Ask explanation agent or placeholder — for now, simple summary:
        explanation = "Explanation placeholder: top influencing layers ... (expand with LangGraph later)"

        st.subheader("Explanation")
        st.write(explanation)

        # Prepare data to save to Render
        payload = {
            "prompt": prompt,
            "generated_text": generated,
            # Convert activations to a compact serializable form: keep shapes and optionally min/max
            "activation_traces": json.dumps({
                k: {
                    "shape": getattr(v, "shape", None),
                    "min": float(v.min()) if hasattr(v, "min") else None,
                    "max": float(v.max()) if hasattr(v, "max") else None
                } for k, v in activations.items()
            }),
            "explanation": explanation
        }

        # Save to Render
        try:
            res = requests.post(SAVE_ENDPOINT, json=payload, timeout=30)
            st.write("Save status:", res.status_code)
            st.write("Save response:", res.text)
            if res.ok:
                data = res.json()
                st.success(f"Experiment saved with ID {data.get('id')}")
            else:
                st.error(f"Failed to save experiment: {res.text}")
        except Exception as e:
            st.error(f"Error saving to Render: {e}")

st.markdown("---")
st.write("Notes:")
st.write("- This app runs heavy ML locally in the HF Space container; Render is used only to persist metadata.")
st.write("- If you want LangGraph explanation, we can call a low-cost open model here or run agents locally.")