tasq/node_modules/agentdb/examples/browser/attention-demo.html

500 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AgentDB - WASM Attention Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
header {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
margin-bottom: 30px;
}
h1 {
color: #667eea;
margin-bottom: 10px;
}
.subtitle {
color: #666;
font-size: 16px;
}
.demo-section {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
h2 {
color: #333;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #667eea;
}
.status {
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
font-weight: 500;
}
.status.loading {
background: #fff3cd;
color: #856404;
}
.status.success {
background: #d4edda;
color: #155724;
}
.status.error {
background: #f8d7da;
color: #721c24;
}
button {
background: #667eea;
color: white;
border: none;
padding: 12px 24px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
margin-bottom: 10px;
transition: background 0.3s;
}
button:hover {
background: #5568d3;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
.results {
background: #f8f9fa;
padding: 20px;
border-radius: 5px;
margin-top: 20px;
font-family: 'Courier New', monospace;
font-size: 14px;
max-height: 400px;
overflow-y: auto;
}
.metric {
display: inline-block;
background: #667eea;
color: white;
padding: 5px 15px;
border-radius: 20px;
margin: 5px;
font-size: 14px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-top: 20px;
}
.card {
background: #f8f9fa;
padding: 20px;
border-radius: 5px;
border-left: 4px solid #667eea;
}
.card h3 {
color: #667eea;
margin-bottom: 10px;
font-size: 18px;
}
.card p {
color: #666;
line-height: 1.6;
}
code {
background: #f1f3f5;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
footer {
text-align: center;
color: white;
margin-top: 30px;
opacity: 0.9;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>AgentDB WASM Attention Demo</h1>
<p class="subtitle">High-performance attention mechanisms in the browser</p>
<div style="margin-top: 15px;">
<span class="metric">Flash Attention</span>
<span class="metric">Hyperbolic Attention</span>
<span class="metric">Memory Consolidation</span>
</div>
</header>
<!-- Status Section -->
<div class="demo-section">
<h2>System Status</h2>
<div id="status" class="status loading">Initializing WASM module...</div>
<div id="features"></div>
</div>
<!-- Flash Attention Demo -->
<div class="demo-section">
<h2>Flash Attention</h2>
<p style="margin-bottom: 20px;">
O(N) memory complexity attention mechanism for efficient sequence processing.
Perfect for long sequences and memory-constrained environments.
</p>
<button id="runFlashAttention">Run Flash Attention</button>
<button id="benchmarkFlashAttention">Benchmark Performance</button>
<div id="flashResults" class="results" style="display: none;"></div>
</div>
<!-- Hyperbolic Attention Demo -->
<div class="demo-section">
<h2>Hyperbolic Attention</h2>
<p style="margin-bottom: 20px;">
Attention in hyperbolic space for hierarchical relationships.
Better representation of tree-like structures and taxonomies.
</p>
<button id="runHyperbolicAttention">Run Hyperbolic Attention</button>
<button id="visualizeHierarchy">Visualize Hierarchy</button>
<div id="hyperbolicResults" class="results" style="display: none;"></div>
</div>
<!-- Memory Consolidation Demo -->
<div class="demo-section">
<h2>Memory Consolidation</h2>
<p style="margin-bottom: 20px;">
Cluster and consolidate similar memories for efficient storage.
Reduces memory footprint while preserving important information.
</p>
<button id="runConsolidation">Run Consolidation</button>
<button id="compareMemory">Compare Memory Usage</button>
<div id="consolidationResults" class="results" style="display: none;"></div>
</div>
<!-- Feature Comparison -->
<div class="demo-section">
<h2>Feature Comparison</h2>
<div class="grid">
<div class="card">
<h3>Flash Attention</h3>
<p><strong>Memory:</strong> O(N) vs O(N²)</p>
<p><strong>Speed:</strong> 2-4x faster</p>
<p><strong>Use Case:</strong> Long sequences</p>
</div>
<div class="card">
<h3>Hyperbolic Attention</h3>
<p><strong>Space:</strong> Poincaré ball</p>
<p><strong>Benefit:</strong> Better hierarchies</p>
<p><strong>Use Case:</strong> Tree structures</p>
</div>
<div class="card">
<h3>Memory Consolidation</h3>
<p><strong>Compression:</strong> 5-10x</p>
<p><strong>Quality:</strong> Minimal loss</p>
<p><strong>Use Case:</strong> Large memory sets</p>
</div>
</div>
</div>
<footer>
<p>AgentDB v2.0 | Powered by WASM & RuVector</p>
</footer>
</div>
<script type="module">
import {
AttentionBrowser,
createAttention,
createFastAttention,
createAccurateAttention
} from '../../dist/agentdb.browser.js';
let attention = null;
// Initialize
async function initialize() {
const statusEl = document.getElementById('status');
const featuresEl = document.getElementById('features');
try {
// Create attention instance
attention = createAttention({
dimension: 384,
numHeads: 4,
blockSize: 64,
useWASM: true
});
// Initialize (lazy load WASM)
await attention.initialize();
const state = attention.getLoadingState();
const error = attention.getError();
if (state === 'loaded') {
statusEl.className = 'status success';
statusEl.textContent = '✓ WASM module loaded successfully!';
} else if (state === 'error') {
statusEl.className = 'status error';
statusEl.textContent = `⚠ WASM loading failed (using fallback): ${error?.message || 'Unknown error'}`;
}
// Display browser features
featuresEl.innerHTML = `
<div style="margin-top: 20px;">
<h3 style="margin-bottom: 10px;">Browser Capabilities:</h3>
<div class="grid">
<div class="card">
<h3>WebAssembly</h3>
<p>${typeof WebAssembly !== 'undefined' ? '✓ Supported' : '✗ Not supported'}</p>
</div>
<div class="card">
<h3>WASM SIMD</h3>
<p id="simdStatus">Detecting...</p>
</div>
<div class="card">
<h3>SharedArrayBuffer</h3>
<p>${typeof SharedArrayBuffer !== 'undefined' ? '✓ Supported' : '✗ Not supported'}</p>
</div>
</div>
</div>
`;
// Detect SIMD
detectSIMD();
} catch (error) {
statusEl.className = 'status error';
statusEl.textContent = `✗ Initialization failed: ${error.message}`;
console.error(error);
}
}
async function detectSIMD() {
try {
const simdTest = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,
0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,
0xfd, 0x0c, 0xfd, 0x0c, 0xfd, 0x54, 0x0b
]);
const module = await WebAssembly.instantiate(simdTest);
document.getElementById('simdStatus').textContent = '✓ Supported';
} catch {
document.getElementById('simdStatus').textContent = '✗ Not supported';
}
}
// Flash Attention Demo
document.getElementById('runFlashAttention').addEventListener('click', async () => {
const resultsEl = document.getElementById('flashResults');
resultsEl.style.display = 'block';
resultsEl.textContent = 'Running flash attention...';
try {
const dim = 384;
const seqLen = 10;
// Create sample data
const query = new Float32Array(dim);
const keys = new Float32Array(seqLen * dim);
const values = new Float32Array(seqLen * dim);
for (let i = 0; i < dim; i++) query[i] = Math.random() - 0.5;
for (let i = 0; i < seqLen * dim; i++) {
keys[i] = Math.random() - 0.5;
values[i] = Math.random() - 0.5;
}
const start = performance.now();
const output = await attention.flashAttention(query, keys, values);
const duration = performance.now() - start;
resultsEl.innerHTML = `
<strong>Flash Attention Results:</strong><br><br>
Sequence Length: ${seqLen}<br>
Dimension: ${dim}<br>
Time: ${duration.toFixed(2)}ms<br>
Output size: ${output.length} elements<br>
First 5 values: [${Array.from(output.slice(0, 5)).map(v => v.toFixed(4)).join(', ')}]<br><br>
<em>Memory complexity: O(N) instead of O(N²)</em>
`;
} catch (error) {
resultsEl.textContent = `Error: ${error.message}`;
}
});
// Benchmark Flash Attention
document.getElementById('benchmarkFlashAttention').addEventListener('click', async () => {
const resultsEl = document.getElementById('flashResults');
resultsEl.style.display = 'block';
resultsEl.textContent = 'Running benchmark...';
try {
const iterations = 100;
const dim = 384;
const seqLen = 10;
const times = [];
const query = new Float32Array(dim).map(() => Math.random() - 0.5);
const keys = new Float32Array(seqLen * dim).map(() => Math.random() - 0.5);
const values = new Float32Array(seqLen * dim).map(() => Math.random() - 0.5);
for (let i = 0; i < iterations; i++) {
const start = performance.now();
await attention.flashAttention(query, keys, values);
times.push(performance.now() - start);
}
times.sort((a, b) => a - b);
const avg = times.reduce((a, b) => a + b) / times.length;
const p50 = times[Math.floor(times.length * 0.5)];
const p95 = times[Math.floor(times.length * 0.95)];
resultsEl.innerHTML = `
<strong>Benchmark Results (${iterations} iterations):</strong><br><br>
Average: ${avg.toFixed(2)}ms<br>
Median (p50): ${p50.toFixed(2)}ms<br>
p95: ${p95.toFixed(2)}ms<br>
Min: ${times[0].toFixed(2)}ms<br>
Max: ${times[times.length - 1].toFixed(2)}ms<br><br>
<em>Throughput: ${(1000 / avg).toFixed(0)} operations/second</em>
`;
} catch (error) {
resultsEl.textContent = `Error: ${error.message}`;
}
});
// Hyperbolic Attention Demo
document.getElementById('runHyperbolicAttention').addEventListener('click', async () => {
const resultsEl = document.getElementById('hyperbolicResults');
resultsEl.style.display = 'block';
resultsEl.textContent = 'Running hyperbolic attention...';
try {
const dim = 384;
const numKeys = 5;
const query = new Float32Array(dim).map(() => Math.random() * 0.5);
const keys = new Float32Array(numKeys * dim).map(() => Math.random() * 0.5);
const start = performance.now();
const similarities = await attention.hyperbolicAttention(query, keys);
const duration = performance.now() - start;
resultsEl.innerHTML = `
<strong>Hyperbolic Attention Results:</strong><br><br>
Number of keys: ${numKeys}<br>
Dimension: ${dim}<br>
Time: ${duration.toFixed(2)}ms<br><br>
<strong>Similarities (Poincaré distance):</strong><br>
${Array.from(similarities).map((s, i) =>
`Key ${i}: ${s.toFixed(4)}`
).join('<br>')}<br><br>
<em>Using Poincaré ball model for hyperbolic space</em>
`;
} catch (error) {
resultsEl.textContent = `Error: ${error.message}`;
}
});
// Memory Consolidation Demo
document.getElementById('runConsolidation').addEventListener('click', async () => {
const resultsEl = document.getElementById('consolidationResults');
resultsEl.style.display = 'block';
resultsEl.textContent = 'Running memory consolidation...';
try {
const dim = 384;
const numMemories = 20;
// Create clustered memories
const memories = [];
for (let cluster = 0; cluster < 3; cluster++) {
const base = new Float32Array(dim).map(() => Math.random() - 0.5);
for (let i = 0; i < 6; i++) {
const memory = new Float32Array(dim);
for (let d = 0; d < dim; d++) {
memory[d] = base[d] + (Math.random() - 0.5) * 0.1;
}
memories.push(memory);
}
}
const start = performance.now();
const consolidated = await attention.consolidateMemories(memories, {
threshold: 0.85,
maxClusters: 5
});
const duration = performance.now() - start;
const totalMembers = consolidated.reduce((sum, c) => sum + c.count, 0);
resultsEl.innerHTML = `
<strong>Memory Consolidation Results:</strong><br><br>
Original memories: ${memories.length}<br>
Consolidated clusters: ${consolidated.length}<br>
Compression ratio: ${(memories.length / consolidated.length).toFixed(2)}x<br>
Time: ${duration.toFixed(2)}ms<br><br>
<strong>Clusters:</strong><br>
${consolidated.map((c, i) =>
`Cluster ${i}: ${c.count} members`
).join('<br>')}<br><br>
<em>Reduced from ${memories.length} to ${consolidated.length} memories</em>
`;
} catch (error) {
resultsEl.textContent = `Error: ${error.message}`;
}
});
// Initialize on load
initialize();
</script>
</body>
</html>