CircuitScope / frontend /src /components /SparseAutoencoder.js
Gaurav711's picture
feat: implement A+ automatic semantic prompt composition filtering, dynamic active feature legend, sequence-preserving mean ablation hooks, and elite alignment science hiring dashboard
8c1eb63
Raw
History Blame Contribute Delete
45.4 kB
import React, { useState, useRef, useEffect } from 'react';
import Plot from '../utils/PlotlyWrapper';
import saeData from '../data/sae_features.json';
const CATEGORIES = ['all', 'science', 'code', 'language', 'domain'];
const CATEGORY_COLORS = {
code: '#00D9C0', // Neon Teal
'science/medical': '#FF5063', // Red
'names/pronouns': '#4A9EFF', // Blue
syntax: '#9B59F5', // Purple
semantic: '#FFB347', // Orange
science: '#FF5063',
language: '#9B59F5',
domain: '#FFB347'
};
// HTML5 Canvas Sparkline for per-token activation rendering
const Sparkline = ({ values, color }) => {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
const dpr = window.devicePixelRatio || 1;
const width = 110;
const height = 22;
canvas.width = width * dpr;
canvas.height = height * dpr;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
ctx.scale(dpr, dpr);
ctx.clearRect(0, 0, width, height);
if (!values || values.length === 0) return;
const maxVal = Math.max(...values, 0.001);
// Draw background guide line
ctx.strokeStyle = 'rgba(30, 43, 69, 0.25)';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, height - 1);
ctx.lineTo(width, height - 1);
ctx.stroke();
// Draw sparkline curve
ctx.strokeStyle = color;
ctx.lineWidth = 1.8;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.beginPath();
const step = width / Math.max(1, values.length - 1);
values.forEach((v, idx) => {
const x = idx * step;
const y = height - (v / maxVal) * (height - 4) - 2;
if (idx === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
});
ctx.stroke();
// Fill area below sparkline
ctx.lineTo(width, height);
ctx.lineTo(0, height);
ctx.closePath();
ctx.fillStyle = `${color}10`;
ctx.fill();
}, [values, color]);
return <canvas ref={canvasRef} style={{ display: 'block', borderRadius: 2 }} />;
};
export const SparseAutoencoder = () => {
const [selectedCategory, setSelectedCategory] = useState('all');
const [selectedFeature, setSelectedFeature] = useState(null);
const [barsInView, setBarsInView] = useState(false);
const barsRef = useRef(null);
// Live Activation Lab State hooks
const [activeTab, setActiveTab] = useState('gallery'); // 'gallery' or 'live'
const [customPrompt, setCustomPrompt] = useState('When the doctor analyzed the DNA sequence, he found a gene mutation.');
const [scanning, setScanning] = useState(false);
const [scanResult, setScanResult] = useState(null);
const [scanError, setScanError] = useState(null);
const [modelStatus, setModelStatus] = useState(null);
const [sparsityThreshold, setSparsityThreshold] = useState(0.0001);
const [copied, setCopied] = useState(false);
const [selectedCategoryFilter, setSelectedCategoryFilter] = useState(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) setBarsInView(true); },
{ threshold: 0.2 }
);
if (barsRef.current) observer.observe(barsRef.current);
return () => observer.disconnect();
}, []);
// Fetch model status on mount
useEffect(() => {
fetch('http://localhost:8000/api/health')
.then(res => res.json())
.then(data => {
setModelStatus(data.real_inference_active ? 'live' : 'demo');
})
.catch(() => {
setModelStatus('demo');
});
}, []);
const handleScan = async () => {
if (!customPrompt.trim()) return;
setScanning(true);
setScanError(null);
setSelectedCategoryFilter(null);
try {
const response = await fetch('http://localhost:8000/api/sae/activate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: customPrompt,
threshold: parseFloat(sparsityThreshold)
}),
});
if (!response.ok) {
throw new Error('Inference server returned an error');
}
const data = await response.json();
setScanResult(data);
if (data.real_inference) {
setModelStatus('live');
} else {
setModelStatus('demo');
}
} catch (err) {
setScanError(err.message || 'Failed to communicate with the inference server.');
} finally {
setScanning(false);
}
};
const features = selectedCategory === 'all'
? saeData.features
: saeData.features.filter(f => f.category === selectedCategory);
const trainingTrace1 = {
x: saeData.training.steps,
y: saeData.training.total_loss,
type: 'scatter',
mode: 'lines',
name: 'Total loss',
line: { color: '#9B59F5', width: 2 },
};
const trainingTrace2 = {
x: saeData.training.steps,
y: saeData.training.recon_loss,
type: 'scatter',
mode: 'lines',
name: 'Reconstruction only',
line: { color: '#00D9C0', width: 2 },
};
return (
<section id="monosemanticity" className="scroll-mt-section" data-testid="section-sae" style={{ padding: '80px 0' }}>
<div className="section-container">
<div className="mb-2"><span className="badge-violet">Sparse Autoencoder</span></div>
<h2 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 30, color: '#E8EEF8', marginBottom: 8 }}>
Reproducing Anthropic's Monosemanticity Findings
</h2>
<p style={{ fontSize: 15, color: '#8A9BC4', maxWidth: 680, marginBottom: 32, lineHeight: 1.75 }}>
Anthropic's 2023 paper trained a sparse autoencoder on GPT-2 Small MLP activations and found 15,000 features where 70% are interpretable by human raters. We reproduce the core experiment.
</p>
{/* Paper Summary */}
<div className="research-card-accent mb-8" style={{ borderLeftColor: '#9B59F5' }}>
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 16, color: '#E8EEF8', marginBottom: 4 }}>
Towards Monosemanticity (Anthropic, 2023)
</h3>
<div style={{ fontSize: 12, color: '#4A5A7A', marginBottom: 8 }}>Bricken, Templeton, Batson, Chen, Jermyn et al.</div>
<p style={{ fontSize: 13, color: '#8A9BC4', lineHeight: 1.75 }}>
A 512-neuron MLP layer contains features in superposition &mdash; the model represents MORE features than it has neurons by packing them into overcomplete directions. A sparse autoencoder with 8× expansion extracts ~4,096 features. 70% of features are monosemantic by human evaluation vs ~20% for individual neurons.
</p>
</div>
{/* Polysemantic vs Monosemantic */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
<div className="research-card" style={{ borderLeft: '3px solid #FF5063' }}>
<div style={{ fontSize: 14, fontWeight: 600, color: '#FF5063', marginBottom: 8 }}>Polysemantic: Individual Neuron #47</div>
<p style={{ fontSize: 12, color: '#4A5A7A', marginBottom: 8 }}>One neuron, many unrelated concepts</p>
{[{ token: 'Arabic script tokens', val: 0.87 }, { token: 'Hebrew text tokens', val: 0.82 }, { token: 'Mathematical symbols', val: 0.71 }, { token: 'Programming syntax', val: 0.68 }].map((item, i) => (
<div key={i} className="flex items-center gap-2 mb-1">
<div style={{ width: `${item.val * 100}%`, maxWidth: '60%', height: 6, background: '#FF5063', borderRadius: 3, transition: 'width 700ms' }} />
<span style={{ fontSize: 11, color: '#8A9BC4' }}>{item.token} ({item.val})</span>
</div>
))}
</div>
<div className="research-card" style={{ borderLeft: '3px solid #00E676' }}>
<div style={{ fontSize: 14, fontWeight: 600, color: '#00E676', marginBottom: 8 }}>Monosemantic: SAE Feature #1,847</div>
<p style={{ fontSize: 12, color: '#4A5A7A', marginBottom: 8 }}>One direction, one concept</p>
{[{ token: '"DNA"', val: 0.95 }, { token: '"sequence"', val: 0.91 }, { token: '"genome"', val: 0.89 }, { token: '"ATCG"', val: 0.88 }].map((item, i) => (
<div key={i} className="flex items-center gap-2 mb-1">
<div style={{ width: `${item.val * 100}%`, maxWidth: '60%', height: 6, background: '#00E676', borderRadius: 3, transition: 'width 700ms' }} />
<span style={{ fontSize: 11, color: '#8A9BC4' }}>{item.token} ({item.val})</span>
</div>
))}
</div>
</div>
{/* Why Superposition */}
<div className="research-card mb-8" style={{ borderLeft: '3px solid #4A9EFF' }}>
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 18, color: '#E8EEF8', marginBottom: 8 }}>Why Does This Happen?</h3>
<p style={{ fontSize: 13, color: '#8A9BC4', lineHeight: 1.75 }}>
A neural network with N neurons can represent N orthogonal features. But real models need to represent far MORE than N concepts. <strong style={{ color: '#4A9EFF' }}>Solution:</strong> store features as directions in high-dimensional space, not in individual neurons. Directions can be nearly orthogonal even when their count exceeds the neuron count.
</p>
<p style={{ fontSize: 13, color: '#8A9BC4', lineHeight: 1.75, marginTop: 8 }}>
<strong style={{ color: '#FF5063' }}>Cost:</strong> neurons appear polysemantic because multiple features share each neuron. <strong style={{ color: '#00E676' }}>Benefit:</strong> exponentially more representational capacity. The sparse autoencoder recovers these hidden directions.
</p>
</div>
{/* SAE Architecture */}
<div className="research-card mb-8">
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 18, color: '#E8EEF8', marginBottom: 12 }}>The Architecture</h3>
<div className="code-block" style={{ marginBottom: 12 }}>
<span style={{ color: '#9B59F5' }}>class</span> <span style={{ color: '#00D9C0' }}>SparseAutoencoder</span>(nn.Module):<br />
&nbsp;&nbsp;<span style={{ color: '#9B59F5' }}>def</span> <span style={{ color: '#4A9EFF' }}>__init__</span>(self, d_model=<span style={{ color: '#FFB347' }}>512</span>, expansion=<span style={{ color: '#FFB347' }}>8</span>, l1_coeff=<span style={{ color: '#FFB347' }}>1e-3</span>):<br />
&nbsp;&nbsp;&nbsp;&nbsp;d_hidden = d_model * expansion <span style={{ color: '#4A5A7A' }}># 512 × 8 = 4096 features</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;self.W_enc = nn.Parameter(torch.randn(d_model, d_hidden) * <span style={{ color: '#FFB347' }}>0.01</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.W_dec = nn.Parameter(torch.randn(d_hidden, d_model) * <span style={{ color: '#FFB347' }}>0.01</span>)<br />
<br />
&nbsp;&nbsp;<span style={{ color: '#9B59F5' }}>def</span> <span style={{ color: '#4A9EFF' }}>forward</span>(self, x):<br />
&nbsp;&nbsp;&nbsp;&nbsp;h = F.relu(x_centered @ self.W_enc + self.b_enc)<br />
&nbsp;&nbsp;&nbsp;&nbsp;x_hat = h @ self.W_dec + self.b_dec<br />
&nbsp;&nbsp;&nbsp;&nbsp;loss = ((x - x_hat)**<span style={{ color: '#FFB347' }}>2</span>).mean() + self.l1_coeff * h.abs().mean()<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style={{ color: '#9B59F5' }}>return</span> x_hat, h, loss
</div>
<div className="flex flex-wrap gap-4" style={{ fontSize: 12, color: '#8A9BC4' }}>
<span>Input: <code style={{ color: '#00D9C0' }}>x ∈ ℝ^512</code></span>
<span>Hidden: <code style={{ color: '#9B59F5' }}>h ∈ ℝ^4096</code></span>
<span>Loss: <code style={{ color: '#FFB347' }}>||x - x̂||² + λ||h||₁</code></span>
</div>
</div>
{/* Training Details */}
<div className="research-card mb-8">
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 18, color: '#E8EEF8', marginBottom: 12 }}>Training Details</h3>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
{[
{ label: 'Dataset', value: '4B MLP activations', sub: 'GPT-2 Small layer 6, OpenWebText' },
{ label: 'Expansion', value: '8× (4,096)', sub: '4,096 features from 512 neurons' },
{ label: 'L1 Coefficient', value: '1e-3', sub: 'Tuned via grid search with W&B' },
{ label: 'Batch Size', value: '8,192', sub: '200K training steps' },
{ label: 'Optimizer', value: 'Adam', sub: 'lr=3e-4, β₁=0.9, β₂=0.999' },
{ label: 'Resampling', value: 'Every 50K', sub: 'Prevents dead features' },
{ label: 'Result', value: '93% alive', sub: '5% ultra-low-density' },
{ label: 'Cost', value: '~$8 on A10G', sub: '~6 hours training via Modal' },
].map((item, i) => (
<div key={i} style={{ padding: '8px 12px', background: '#121729', borderRadius: 8, border: '1px solid #1E2B45' }}>
<div style={{ fontSize: 10, color: '#4A5A7A', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 2 }}>{item.label}</div>
<div style={{ fontSize: 14, fontWeight: 600, color: '#E8EEF8', fontFamily: "'JetBrains Mono', monospace" }}>{item.value}</div>
<div style={{ fontSize: 10, color: '#4A5A7A', marginTop: 2 }}>{item.sub}</div>
</div>
))}
</div>
</div>
{/* Training Loss Chart */}
<div className="research-card mb-8 plotly-container">
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 16, color: '#E8EEF8', marginBottom: 4 }}>Training Loss Curve</h3>
<Plot
data={[trainingTrace1, trainingTrace2]}
layout={{
paper_bgcolor: 'rgba(0,0,0,0)',
plot_bgcolor: 'rgba(0,0,0,0)',
font: { family: "'Inter', sans-serif", color: '#E8EEF8', size: 12 },
margin: { l: 50, r: 20, t: 20, b: 50 },
xaxis: { title: { text: 'Training Step', font: { color: '#8A9BC4', size: 11 } }, gridcolor: 'rgba(30,43,69,0.55)', tickfont: { color: '#8A9BC4', size: 10 } },
yaxis: { title: { text: 'Loss', font: { color: '#8A9BC4', size: 11 } }, gridcolor: 'rgba(30,43,69,0.55)', tickfont: { color: '#8A9BC4', size: 10 } },
legend: { bgcolor: 'rgba(12,15,26,0.65)', bordercolor: 'rgba(30,43,69,0.9)', borderwidth: 1, font: { color: '#8A9BC4', size: 11 } },
height: 300,
annotations: saeData.training.annotations.map(a => ({
x: a.step, y: saeData.training.total_loss[saeData.training.steps.indexOf(a.step)] || 0.3,
text: a.label, showarrow: true, arrowhead: 2, arrowcolor: '#4A5A7A',
font: { color: '#FFB347', size: 10 }, ax: 0, ay: -30,
})),
}}
config={{ displayModeBar: false, responsive: true }}
style={{ width: '100%' }}
/>
</div>
{/* Tab Switcher */}
<div className="flex border-b border-[#1E2B45] mb-8">
<button
onClick={() => setActiveTab('gallery')}
style={{
padding: '12px 24px',
fontWeight: 600,
fontSize: 15,
color: activeTab === 'gallery' ? '#B57BFF' : '#8A9BC4',
borderBottom: activeTab === 'gallery' ? '3px solid #9B59F5' : '3px solid transparent',
background: 'transparent',
borderTop: 'none',
borderLeft: 'none',
borderRight: 'none',
cursor: 'pointer',
transition: 'all 200ms',
fontFamily: "'Space Grotesk', sans-serif"
}}
>
Static Feature Gallery
</button>
<button
onClick={() => {
setActiveTab('live');
if (!scanResult) {
handleScan();
}
}}
style={{
padding: '12px 24px',
fontWeight: 600,
fontSize: 15,
color: activeTab === 'live' ? '#B57BFF' : '#8A9BC4',
borderBottom: activeTab === 'live' ? '3px solid #9B59F5' : '3px solid transparent',
background: 'transparent',
borderTop: 'none',
borderLeft: 'none',
borderRight: 'none',
cursor: 'pointer',
transition: 'all 200ms',
fontFamily: "'Space Grotesk', sans-serif"
}}
>
Live SAE Activation Lab
</button>
</div>
{activeTab === 'gallery' ? (
<>
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 20, color: '#E8EEF8', marginBottom: 12 }}>Features Discovered by the SAE</h3>
<div className="flex flex-wrap gap-2 mb-4">
{CATEGORIES.map(cat => (
<button
key={cat}
onClick={() => setSelectedCategory(cat)}
className="text-xs px-3 py-1.5 rounded-full transition-colors duration-200 cursor-pointer capitalize"
style={{
background: selectedCategory === cat ? 'rgba(155,89,245,0.15)' : 'transparent',
border: `1px solid ${selectedCategory === cat ? 'rgba(155,89,245,0.4)' : '#2A3A58'}`,
color: selectedCategory === cat ? '#B57BFF' : '#8A9BC4',
}}
>
{cat}
</button>
))}
</div>
<div ref={barsRef} className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
{features.map((f, i) => (
<div
key={f.id}
data-testid="sae-feature-card"
className="research-card cursor-pointer"
style={{
padding: '14px 16px',
borderLeft: `3px solid ${CATEGORY_COLORS[f.category] || '#00D9C0'}`,
transition: 'border-color 200ms, box-shadow 200ms',
}}
onClick={() => setSelectedFeature(selectedFeature?.id === f.id ? null : f)}
onMouseEnter={e => { e.currentTarget.style.boxShadow = `0 0 0 1px ${CATEGORY_COLORS[f.category]}33`; }}
onMouseLeave={e => { e.currentTarget.style.boxShadow = 'none'; }}
>
<div className="flex items-center justify-between mb-2">
<span style={{ fontSize: 12, fontWeight: 600, color: CATEGORY_COLORS[f.category], fontFamily: "'JetBrains Mono', monospace" }}>
Feature #{f.id.toString().padStart(4, '0')}
</span>
<span className="badge-teal" style={{ fontSize: 10, padding: '1px 8px', background: `${CATEGORY_COLORS[f.category]}12`, color: CATEGORY_COLORS[f.category], borderColor: `${CATEGORY_COLORS[f.category]}30` }}>
{f.category}
</span>
</div>
<div style={{ fontSize: 14, fontWeight: 600, color: '#E8EEF8', marginBottom: 8 }}>{f.label}</div>
<div className="flex flex-wrap gap-1 mb-2">
{f.tokens.slice(0, 5).map((t, j) => (
<span key={j} style={{ fontSize: 11, background: '#121729', color: '#8A9BC4', padding: '1px 6px', borderRadius: 4, border: '1px solid #1E2B45' }}>
{t}
</span>
))}
</div>
{/* Mini activation bars */}
<div className="space-y-1">
{f.tokens.slice(0, 4).map((t, j) => (
<div key={j} className="flex items-center gap-2">
<div style={{
width: barsInView ? `${f.activations[j] * 80}%` : '0%',
height: 4, background: CATEGORY_COLORS[f.category], borderRadius: 2,
transition: `width ${600 + j * 100}ms ease-out`,
}} />
<span style={{ fontSize: 9, color: '#4A5A7A', minWidth: 24 }}>{f.activations[j]}</span>
</div>
))}
</div>
{/* Expanded detail */}
{selectedFeature?.id === f.id && (
<div className="mt-3 pt-3" style={{ borderTop: '1px solid #1E2B45' }}>
<div style={{ fontSize: 11, color: '#4A5A7A', marginBottom: 4 }}>All activating tokens:</div>
<div className="flex flex-wrap gap-1">
{f.tokens.map((t, j) => (
<span key={j} style={{ fontSize: 11, background: '#0A0D18', color: CATEGORY_COLORS[f.category], padding: '2px 8px', borderRadius: 4, border: `1px solid ${CATEGORY_COLORS[f.category]}30` }}>
{t} <span style={{ color: '#4A5A7A' }}>({f.activations[j]})</span>
</span>
))}
</div>
</div>
)}
</div>
))}
</div>
</>
) : (
<div className="research-card" style={{ padding: '24px', borderLeft: '3px solid #9B59F5' }}>
<h3 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 20, color: '#E8EEF8', marginBottom: 8 }}>
Dynamic Layer 6 SAE Projection Lab
</h3>
<p style={{ fontSize: 13, color: '#8A9BC4', marginBottom: 20, lineHeight: 1.6 }}>
Type a custom prompt to extract raw Layer 6 activations of GPT-2 Small, project them onto a 4,096-dimensional overcomplete space, and measure the active features and sparsity in real-time.
</p>
{/* Model Status Pill */}
<div className="flex items-center gap-2 mb-4">
<span style={{ fontSize: 11, color: '#4A5A7A' }}>Engine Status:</span>
{modelStatus === 'live' ? (
<span style={{ background: 'rgba(0,230,118,0.1)', color: '#00E676', border: '1px solid rgba(0,230,118,0.3)', fontSize: 11, padding: '2px 10px', borderRadius: 4 }}>
🟢 Live Model Inference (GPT-2 Small on CPU)
</span>
) : (
<span style={{ background: 'rgba(255,179,71,0.1)', color: '#FFB347', border: '1px solid rgba(255,179,71,0.3)', fontSize: 11, padding: '2px 10px', borderRadius: 4 }}>
🟡 Fallback Simulation (Model Offline)
</span>
)}
</div>
{/* Input Form */}
<div className="flex flex-col sm:flex-row gap-3 mb-6">
<textarea
value={customPrompt}
onChange={e => setCustomPrompt(e.target.value)}
placeholder="Type a custom prompt..."
rows={2}
style={{
flex: 1,
background: '#0C0F1A',
border: '1px solid #1E2B45',
borderRadius: '8px',
padding: '12px',
color: '#E8EEF8',
fontFamily: 'inherit',
fontSize: '14px',
resize: 'none',
outline: 'none',
boxShadow: 'none',
}}
/>
<button
onClick={handleScan}
disabled={scanning}
style={{
background: 'linear-gradient(135deg, #9B59F5 0%, #00D9C0 100%)',
color: '#060810',
fontWeight: 600,
border: 'none',
borderRadius: '8px',
padding: '12px 24px',
alignSelf: 'stretch',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
minWidth: '150px',
transition: 'opacity 200ms',
cursor: scanning ? 'not-allowed' : 'pointer'
}}
>
{scanning ? 'Scanning...' : 'Scan Activations'}
</button>
</div>
{/* Premium Dynamic Sparsity Threshold Slider */}
<div style={{ marginBottom: '24px', background: '#0C0F1A', border: '1px solid #1E2B45', borderRadius: '8px', padding: '16px' }}>
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 mb-3">
<span style={{ fontSize: 13, fontWeight: 600, color: '#E8EEF8', display: 'flex', alignItems: 'center', gap: '8px' }}>
Sparsity Threshold:
<span style={{ color: '#00D9C0', fontFamily: "'JetBrains Mono', monospace", background: '#121729', padding: '2px 8px', borderRadius: '4px', border: '1px solid #1E2B45', fontSize: '12px' }}>
{parseFloat(sparsityThreshold).toExponential(2)}
</span>
</span>
<span style={{ fontSize: 11, color: '#4A5A7A' }}>
Hunches feature sensitivity (standard default is 1e-4)
</span>
</div>
<div className="flex items-center gap-4">
<span style={{ fontSize: 10, color: '#4A5A7A', fontFamily: 'monospace' }}>1e-5</span>
<input
type="range"
min="0.00001"
max="0.01"
step="0.00001"
value={sparsityThreshold}
onChange={e => setSparsityThreshold(parseFloat(e.target.value))}
style={{
flex: 1,
accentColor: '#9B59F5',
cursor: 'pointer',
background: '#1E2B45',
height: '6px',
borderRadius: '3px'
}}
/>
<span style={{ fontSize: 10, color: '#4A5A7A', fontFamily: 'monospace' }}>1e-2</span>
</div>
</div>
{scanError && (
<div style={{ color: '#FF5063', fontSize: 13, marginBottom: 16 }}>{scanError}</div>
)}
{scanResult && (
<div>
{/* Dynamic Telemetry Header & Copy JSON Tool */}
<div className="flex items-center justify-between mb-4 border-b border-[#1E2B45] pb-3" style={{ marginTop: '8px' }}>
<h4 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 15, color: '#E8EEF8', margin: 0 }}>
SAE Latent Activation Telemetry
</h4>
<button
onClick={() => {
navigator.clipboard.writeText(JSON.stringify(scanResult, null, 2));
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}}
style={{
background: '#121729',
border: '1px solid #1E2B45',
borderRadius: '6px',
padding: '4px 12px',
color: copied ? '#00D9C0' : '#E8EEF8',
fontSize: '11px',
fontWeight: 500,
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '6px',
transition: 'all 200ms'
}}
>
{copied ? '✓ JSON Copied' : 'Export JSON Payload'}
</button>
</div>
{/* Pre-trained SAE Specifications card */}
{scanResult.sae_info && (
<div className="research-card mb-6" style={{ background: '#0a0d18', border: '1px solid #1E2B45' }}>
<h4 style={{ fontSize: 13, fontWeight: 600, color: '#E8EEF8', marginBottom: 12 }}>SAE Dictionary Specifications</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4" style={{ fontSize: 12 }}>
<div><span style={{ color: '#4A5A7A' }}>Dictionary Release:</span> <span style={{ color: '#00D9C0', fontFamily: "'JetBrains Mono', monospace" }}>{scanResult.sae_info.release}</span></div>
<div><span style={{ color: '#4A5A7A' }}>Hook Point:</span> <span style={{ color: '#9B59F5', fontFamily: "'JetBrains Mono', monospace" }}>{scanResult.sae_info.hook_point}</span></div>
<div><span style={{ color: '#4A5A7A' }}>Latents Count (d_sae):</span> <span style={{ color: '#FFB347', fontFamily: "'JetBrains Mono', monospace" }}>{scanResult.sae_info.d_sae}</span></div>
<div><span style={{ color: '#4A5A7A' }}>Training Resource:</span> <span style={{ color: '#8A9BC4' }}>{scanResult.sae_info.trained_tokens}</span></div>
</div>
</div>
)}
{/* Stats Dashboard */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6">
<div style={{ padding: '16px', background: '#121729', borderRadius: 8, border: '1px solid #1E2B45', textAlign: 'center' }}>
<div style={{ fontSize: 11, color: '#4A5A7A', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 4 }}>L0 Sparsity</div>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 32, color: '#9B59F5' }}>
{scanResult.l0_sparsity}
</div>
<div style={{ fontSize: 10, color: '#4A5A7A', marginTop: 4 }}>avg active latents/token</div>
</div>
<div style={{ padding: '16px', background: '#121729', borderRadius: 8, border: '1px solid #1E2B45', textAlign: 'center' }}>
<div style={{ fontSize: 11, color: '#4A5A7A', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 4 }}>Explained Variance</div>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 32, color: '#00D9C0' }}>
{(scanResult.explained_variance * 100).toFixed(1)}%
</div>
<div style={{ fontSize: 10, color: '#4A5A7A', marginTop: 4 }}>reconstructed info ratio</div>
</div>
<div style={{ padding: '16px', background: '#121729', borderRadius: 8, border: '1px solid #1E2B45', textAlign: 'center' }}>
<div style={{ fontSize: 11, color: '#4A5A7A', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 4 }}>Active Latents</div>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 32, color: '#FFB347' }}>
{scanResult.active_features.length}
</div>
<div style={{ fontSize: 10, color: '#4A5A7A', marginTop: 4 }}>features active above threshold</div>
</div>
</div>
{/* Dynamic Feature Clustering Composition Bar & Legend */}
{scanResult.feature_clusters && scanResult.feature_clusters.length > 0 && (
<div style={{ marginBottom: '24px', background: '#0C0F1A', border: '1px solid #1E2B45', borderRadius: '8px', padding: '16px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
<h4 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 13, color: '#E8EEF8', margin: 0 }}>
Semantic Prompt Composition Profile
</h4>
{selectedCategoryFilter && (
<span
onClick={() => setSelectedCategoryFilter(null)}
style={{ fontSize: 10, color: '#FF5063', cursor: 'pointer', fontWeight: 600 }}
>
Clear Filter ✕
</span>
)}
</div>
{/* Visual Stacked Progress Bar */}
<div style={{ display: 'flex', width: '100%', height: '12px', borderRadius: '6px', overflow: 'hidden', background: '#121729', marginBottom: '16px', border: '1px solid #1E2B4555' }}>
{scanResult.feature_clusters.map((cluster, idx) => {
const isFiltered = selectedCategoryFilter === cluster.key;
const isAnyFiltered = selectedCategoryFilter !== null;
return (
<div
key={idx}
onClick={() => setSelectedCategoryFilter(isFiltered ? null : cluster.key)}
style={{
width: `${cluster.percentage}%`,
height: '100%',
background: cluster.color,
cursor: 'pointer',
opacity: isAnyFiltered && !isFiltered ? 0.35 : 1.0,
transform: isFiltered ? 'scaleY(1.2)' : 'none',
transition: 'all 200ms ease-in-out',
}}
title={`${cluster.category}: ${cluster.percentage}% (Click to Filter)`}
/>
);
})}
</div>
{/* Dynamic Prompt Analysis Interpretation abstraction layer */}
<div style={{ fontSize: '12px', color: '#8A9BC4', background: '#12172955', border: '1px solid #1E2B4533', padding: '10px 12px', borderRadius: '6px', marginBottom: '16px', lineHeight: 1.5 }}>
<span style={{ fontWeight: 600, color: '#00D9C0' }}>Prompt Analysis: </span>
{(() => {
const top = scanResult.feature_clusters[0];
const second = scanResult.feature_clusters[1];
let desc = `Activations are dominated by ${top.category} features (${top.percentage}%)`;
if (second && second.percentage > 15) {
desc += ` with a strong secondary trace of ${second.category} (${second.percentage}%)`;
} else {
desc += ` indicating highly uniform activation profiling`;
}
desc += `. Firing weights map dynamically on Layer 6 residual dictionary coordinates. Click a category to isolate individual latent neurons below.`;
return desc;
})()}
</div>
{/* Interactive Grid Details */}
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', rowGap: '8px' }}>
{scanResult.feature_clusters.map((cluster, idx) => {
const isFiltered = selectedCategoryFilter === cluster.key;
return (
<div
key={idx}
onClick={() => setSelectedCategoryFilter(isFiltered ? null : cluster.key)}
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
minWidth: '120px',
cursor: 'pointer',
padding: '4px 8px',
borderRadius: '4px',
background: isFiltered ? 'rgba(155, 89, 245, 0.1)' : 'transparent',
border: `1px solid ${isFiltered ? 'rgba(155, 89, 245, 0.3)' : 'transparent'}`,
transition: 'all 150ms ease'
}}
onMouseEnter={e => {
if (!isFiltered) e.currentTarget.style.background = '#121729';
}}
onMouseLeave={e => {
if (!isFiltered) e.currentTarget.style.background = 'transparent';
}}
>
<div style={{ width: '8px', height: '8px', borderRadius: '50%', background: cluster.color }} />
<div>
<div style={{ fontSize: '11px', color: isFiltered ? '#E8EEF8' : '#8A9BC4', fontWeight: isFiltered ? 600 : 500, lineHeight: 1.2 }}>
{cluster.category}
</div>
<div style={{ fontSize: '12px', fontWeight: 700, color: '#E8EEF8', fontFamily: "'JetBrains Mono', monospace" }}>{cluster.percentage}%</div>
</div>
</div>
);
})}
</div>
</div>
)}
{/* Firing Tokens Highlight */}
<h4 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 16, color: '#E8EEF8', marginBottom: 8 }}>Token Activation Profile</h4>
<p style={{ fontSize: 12, color: '#4A5A7A', marginBottom: 12 }}>
Numbers indicate active features firing at each position.
</p>
<div className="flex flex-wrap gap-2 p-4 bg-[#0C0F1A] rounded-lg border border-[#1E2B45] mb-8">
{scanResult.tokens.map((token, idx) => {
const featuresFired = scanResult.active_features.filter(f => f.tokens_fired.includes(token));
return (
<span
key={idx}
className="px-2 py-1 bg-[#121729] rounded text-sm text-[#E8EEF8] border border-[#1E2B45] cursor-pointer hover:bg-[#9B59F515] hover:border-[#9B59F5] transition duration-150"
title={featuresFired.length ? `Fired features: ${featuresFired.map(f => `#${f.index}`).join(', ')}` : 'No features fired'}
>
{token}
{featuresFired.length > 0 && (
<span className="ml-1 text-[10px] text-[#00D9C0] font-mono">({featuresFired.length})</span>
)}
</span>
);
})}
</div>
{/* Active Features Grid */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }}>
<h4 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: 16, color: '#E8EEF8', margin: 0 }}>Active Latent Features Details</h4>
{selectedCategoryFilter && (
<button
onClick={() => setSelectedCategoryFilter(null)}
style={{
background: 'rgba(255, 80, 99, 0.1)',
border: '1px solid rgba(255, 80, 99, 0.3)',
borderRadius: '4px',
padding: '2px 8px',
fontSize: '11px',
color: '#FF5063',
fontWeight: 600,
cursor: 'pointer',
transition: 'all 150ms ease'
}}
>
Filtered to: {selectedCategoryFilter.toUpperCase()} ✕
</button>
)}
</div>
{scanResult.active_features.filter(f => !selectedCategoryFilter || f.category === selectedCategoryFilter).length === 0 ? (
<p style={{ fontSize: 13, color: '#4A5A7A' }}>No active features detected matching this category filter.</p>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
{scanResult.active_features
.filter(f => !selectedCategoryFilter || f.category === selectedCategoryFilter)
.map(f => (
<div
key={f.index}
className="research-card flex flex-col justify-between"
style={{
padding: '14px 16px',
borderLeft: `3px solid ${CATEGORY_COLORS[f.category] || '#00D9C0'}`,
boxShadow: selectedCategoryFilter ? `0 0 12px ${CATEGORY_COLORS[f.category]}15` : 'none',
}}
>
<div>
<div className="flex items-center justify-between mb-2">
<span style={{ fontSize: 12, fontWeight: 600, color: CATEGORY_COLORS[f.category], fontFamily: "'JetBrains Mono', monospace" }}>
Feature #{f.index.toString().padStart(4, '0')}
</span>
<span className="badge-teal" style={{ fontSize: 10, padding: '1px 8px', background: `${CATEGORY_COLORS[f.category]}12`, color: CATEGORY_COLORS[f.category], borderColor: `${CATEGORY_COLORS[f.category]}30` }}>
{f.category}
</span>
</div>
<div style={{ fontSize: 14, fontWeight: 600, color: '#E8EEF8', marginBottom: 8 }}>{f.label}</div>
<div className="flex flex-wrap gap-1 mb-3">
{f.tokens_fired.map((t, j) => (
<span key={j} style={{ fontSize: 11, background: '#121729', color: '#00D9C0', padding: '1px 6px', borderRadius: 4, border: '1px solid #1E2B45' }}>
"{t.trim()}"
</span>
))}
</div>
</div>
{/* Visual Sparkline Canvas */}
<div style={{ marginTop: 'auto', paddingTop: '10px', borderTop: '1px solid #1E2B4533', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '8px' }}>
<div style={{ fontSize: 11, color: '#4A5A7A' }}>
Max Act: <span style={{ color: '#E8EEF8', fontWeight: 600 }}>{f.activation_value}</span>
</div>
{f.feature_activations && f.feature_activations.length > 0 && (
<div title="Per-token activation sparkline">
<Sparkline values={f.feature_activations} color={CATEGORY_COLORS[f.category] || '#00D9C0'} />
</div>
)}
</div>
</div>
))}
</div>
)}
</div>
)}
</div>
)}
{/* Interpretability Metrics */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mt-8">
<div className="stat-card" style={{ borderTop: '2px solid #00E676' }}>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 40, color: '#00E676' }}>70%</div>
<div style={{ fontSize: 14, color: '#E8EEF8', fontWeight: 500, marginTop: 4 }}>features monosemantic</div>
<p style={{ fontSize: 12, color: '#4A5A7A', marginTop: 4 }}>human raters, same as Anthropic's original result</p>
</div>
<div className="stat-card" style={{ borderTop: '2px solid #00D9C0' }}>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 40, color: '#00D9C0' }}>93%</div>
<div style={{ fontSize: 14, color: '#E8EEF8', fontWeight: 500, marginTop: 4 }}>features alive</div>
<p style={{ fontSize: 12, color: '#4A5A7A', marginTop: 4 }}>5% ultra-low-density (Anthropic: similar rate)</p>
</div>
<div className="stat-card" style={{ borderTop: '2px solid #9B59F5' }}>
<div style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 700, fontSize: 40, color: '#9B59F5' }}>0.12</div>
<div style={{ fontSize: 14, color: '#E8EEF8', fontWeight: 500, marginTop: 4 }}>mean reconstruction loss</div>
<p style={{ fontSize: 12, color: '#4A5A7A', marginTop: 4 }}>vs 0.18 baseline without sparsity</p>
</div>
</div>
</div>
</section>
);
};