JMullings commited on
Commit
fd627ee
·
verified ·
1 Parent(s): ac2a842

Upload index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +228 -0
index.html ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Spectral Nearest Neighbours Playground</title>
7
+ <style>
8
+ :root {
9
+ --bg: #070a12;
10
+ --card: #0f172a;
11
+ --card-border: #1e293b;
12
+ --ink: #f8fafc;
13
+ --mute: #94a3b8;
14
+ --accent: #38bdf8;
15
+ --spec: #f59e0b;
16
+ --ok: #22c55e;
17
+ }
18
+ * { box-sizing: border-box; }
19
+ body {
20
+ margin: 0; background: var(--bg); color: var(--ink);
21
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
22
+ padding: 24px;
23
+ }
24
+ .container { max-width: 1100px; margin: 0 auto; }
25
+ header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
26
+ .badge { background: #0369a1; color: #fff; padding: 4px 10px; border-radius: 99px; font-size: 12px; font-weight: 600; }
27
+ .card { background: var(--card); border: 1px solid var(--card-border); border-radius: 12px; padding: 20px; margin-bottom: 18px; }
28
+ h2 { margin: 0 0 12px; font-size: 16px; font-weight: 700; color: #e2e8f0; }
29
+ input, textarea { width: 100%; background: #020617; border: 1px solid var(--card-border); color: #fff; border-radius: 8px; padding: 10px; outline: none; margin-bottom: 10px; }
30
+ .btn { background: var(--accent); color: #020617; border: 0; padding: 9px 18px; border-radius: 8px; font-weight: 700; cursor: pointer; }
31
+ .btn-secondary { background: #334155; color: #f8fafc; margin-left: 8px; }
32
+ .btn:hover { filter: brightness(1.1); }
33
+ .chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
34
+ .chip { background: #1e293b; color: var(--mute); border: 1px solid #334155; padding: 5px 12px; border-radius: 99px; font-size: 12px; cursor: pointer; }
35
+ .chip:hover { color: #fff; border-color: var(--accent); }
36
+ .results-list { list-style: none; padding: 0; margin: 0; }
37
+ .item { display: flex; justify-content: space-between; align-items: center; background: #020617; border: 1px solid var(--card-border); padding: 10px 14px; border-radius: 8px; margin-bottom: 8px; }
38
+ .item-rank { font-weight: 700; color: var(--spec); width: 24px; }
39
+ .item-text { flex: 1; padding: 0 12px; font-size: 14px; }
40
+ .item-sim { font-family: monospace; color: var(--ok); font-weight: 600; }
41
+ </style>
42
+ </head>
43
+ <body>
44
+ <div class="container">
45
+ <header>
46
+ <div>
47
+ <h1 style="margin:0;font-size:22px;">⚡ Spectral Embeddings Playground</h1>
48
+ <div style="color:var(--mute);font-size:13px;margin-top:4px;">Direct evaluation of <code>JMullings/Spectral_Embeddings</code></div>
49
+ </div>
50
+ <span class="badge">Model: 3.93 MB · 0.45 ms</span>
51
+ </header>
52
+
53
+ <!-- Random Test Suite Card -->
54
+ <div class="card" style="border-color: #0284c7; background: #082f4922;">
55
+ <h2>🎲 Automated NN Probe & Random Generator</h2>
56
+ <p style="font-size:13px;color:var(--mute);margin:0 0 12px;">Instantly populate diverse domains to benchmark semantic discrimination.</p>
57
+ <div class="chips">
58
+ <button class="chip" onclick="loadProbe(0)">🔑 Auth & Security</button>
59
+ <button class="chip" onclick="loadProbe(1)">🤖 Machine Learning</button>
60
+ <button class="chip" onclick="loadProbe(2)">🧬 Biology & Medicine</button>
61
+ <button class="chip" onclick="loadProbe(3)">⚡ Algorithms</button>
62
+ <button class="chip" onclick="generateRandomList()">🔀 Shuffle Random 6-Domain Mix</button>
63
+ </div>
64
+ </div>
65
+
66
+ <!-- Playground Form -->
67
+ <div class="card">
68
+ <h2>Target Sentence (Anchor)</h2>
69
+ <input id="targetInput" value="How do I reset my account password?">
70
+
71
+ <h2>Neighbor Sentences (Candidates to Rank)</h2>
72
+ <textarea id="neighborsInput" rows="6">Steps to change login credentials and regain account access.
73
+ I forgot my password and need to restore my profile.
74
+ Enable two-factor authentication for higher security.
75
+ The capital of France is Paris with many historic landmarks.
76
+ Database indexes improve query retrieval speed at write expense.
77
+ Quicksort has an average runtime complexity of O(n log n).</textarea>
78
+
79
+ <div style="margin-top:6px;">
80
+ <button class="btn" id="runBtn" onclick="computeRankings()">Compute Nearest Neighbors</button>
81
+ <span id="latencySpan" style="font-size:12px;color:var(--mute);margin-left:12px;"></span>
82
+ </div>
83
+ </div>
84
+
85
+ <!-- Output Ranking -->
86
+ <div class="card" id="resultsCard" style="display:none;">
87
+ <h2>Nearest Neighbor Ranking (Spectral Manifold)</h2>
88
+ <ul class="results-list" id="resultsUl"></ul>
89
+ </div>
90
+ </div>
91
+
92
+ <script>
93
+ const PROBES = [
94
+ {
95
+ target: "How do I reset my account password?",
96
+ list: [
97
+ "Steps to change login credentials and regain account access.",
98
+ "I forgot my password and need to restore my profile.",
99
+ "Enable two-factor authentication for higher security.",
100
+ "The capital of France is Paris with many historic landmarks.",
101
+ "Mitochondria produce cellular ATP through oxidative phosphorylation."
102
+ ]
103
+ },
104
+ {
105
+ target: "Transformers utilize self-attention mechanisms to process sequential text.",
106
+ list: [
107
+ "Self-attention layers in transformer models model contextual token dependencies.",
108
+ "Deep neural networks learn hierarchical feature representations from data.",
109
+ "The optimizer updates model weights step by step down the loss gradient.",
110
+ "To make espresso, force pressurized hot water through finely ground coffee.",
111
+ "The local hockey team won their championship game on Sunday evening."
112
+ ]
113
+ },
114
+ {
115
+ target: "Antibiotics target bacterial cell walls without damaging human cells.",
116
+ list: [
117
+ "Antimicrobial drugs kill bacteria by disrupting bacterial peptidoglycan synthesis.",
118
+ "Supernovae scatter heavy elements into the surrounding interstellar medium.",
119
+ "Monetary tightening through rate hikes aims to cool overheated consumer prices.",
120
+ "Central banks raise interest rates to suppress rising inflation."
121
+ ]
122
+ },
123
+ {
124
+ target: "Quicksort has an average runtime complexity of O(n log n).",
125
+ list: [
126
+ "Partitioning around pivot elements yields n log n expected sorting performance.",
127
+ "B-tree indices speed up SELECT lookups but increase INSERT latency.",
128
+ "Database indexes improve query retrieval speed at write expense.",
129
+ "The ancient Roman colosseum hosted gladiatorial games and spectacles."
130
+ ]
131
+ }
132
+ ];
133
+
134
+ const RANDOM_POOL = [
135
+ "Deadlocks occur when concurrent threads hold locks while waiting on each other.",
136
+ "Quantum entanglement links particle quantum states across space.",
137
+ "Central banks raise interest rates to suppress rising inflation.",
138
+ "Monet painted water lilies using impressionist brushstroke techniques.",
139
+ "Bake the bread dough at 200 degrees Celsius for 30 minutes.",
140
+ "Supernovae scatter heavy elements into the surrounding interstellar medium.",
141
+ "The stock index gained two percent following quarterly corporate earnings."
142
+ ];
143
+
144
+ function loadProbe(idx) {
145
+ const p = PROBES[idx];
146
+ if (!p) return;
147
+ document.getElementById("targetInput").value = p.target;
148
+ document.getElementById("neighborsInput").value = p.list.join("\n");
149
+ computeRankings();
150
+ }
151
+
152
+ function generateRandomList() {
153
+ const shuffled = [...RANDOM_POOL].sort(() => 0.5 - Math.random()).slice(0, 5);
154
+ const randomProbe = PROBES[Math.floor(Math.random() * PROBES.length)];
155
+ document.getElementById("targetInput").value = randomProbe.target;
156
+ shuffled.unshift(randomProbe.list[0]);
157
+ document.getElementById("neighborsInput").value = shuffled.join("\n");
158
+ computeRankings();
159
+ }
160
+
161
+ function meanCenter(embeddings) {
162
+ const dim = embeddings[0].length;
163
+ const mean = new Float32Array(dim);
164
+ for (let i = 0; i < embeddings.length; i++) {
165
+ for (let d = 0; d < dim; d++) mean[d] += embeddings[i][d];
166
+ }
167
+ for (let d = 0; d < dim; d++) mean[d] /= embeddings.length;
168
+
169
+ return embeddings.map(emb => {
170
+ const centered = new Float32Array(dim);
171
+ let norm = 0;
172
+ for (let d = 0; d < dim; d++) {
173
+ centered[d] = emb[d] - mean[d];
174
+ norm += centered[d] * centered[d];
175
+ }
176
+ norm = Math.sqrt(norm) || 1e-12;
177
+ return Array.from(centered, x => x / norm);
178
+ });
179
+ }
180
+
181
+ async function computeRankings() {
182
+ const target = document.getElementById("targetInput").value.trim();
183
+ const cands = document.getElementById("neighborsInput").value.split("\n").map(s => s.trim()).filter(Boolean);
184
+ if (!target || !cands.length) return;
185
+
186
+ const t0 = performance.now();
187
+ const resp = await fetch("/api/embed", {
188
+ method: "POST",
189
+ headers: { "Content-Type": "application/json" },
190
+ body: JSON.stringify({ input: [target, ...cands] })
191
+ });
192
+ const data = await resp.json();
193
+ const elapsed = (performance.now() - t0).toFixed(2);
194
+
195
+ document.getElementById("latencySpan").textContent =
196
+ `Processed in ${elapsed} ms (${(elapsed / (cands.length + 1)).toFixed(3)} ms/sent)`;
197
+
198
+ const normalizedEmbs = meanCenter(data.embeddings);
199
+ const tEmb = normalizedEmbs[0];
200
+
201
+ const scored = cands.map((c, i) => {
202
+ const emb = normalizedEmbs[i + 1];
203
+ let dot = 0;
204
+ for (let j = 0; j < tEmb.length; j++) dot += tEmb[j] * emb[j];
205
+ return { text: c, score: dot };
206
+ });
207
+
208
+ scored.sort((a, b) => b.score - a.score);
209
+
210
+ const ul = document.getElementById("resultsUl");
211
+ ul.innerHTML = "";
212
+ scored.forEach((item, idx) => {
213
+ const li = document.createElement("li");
214
+ li.className = "item";
215
+ li.innerHTML = `
216
+ <span class="item-rank">#${idx + 1}</span>
217
+ <span class="item-text">${item.text}</span>
218
+ <span class="item-sim">cos: ${item.score.toFixed(6)}</span>
219
+ `;
220
+ ul.appendChild(li);
221
+ });
222
+ document.getElementById("resultsCard").style.display = "block";
223
+ }
224
+
225
+ window.addEventListener("DOMContentLoaded", computeRankings);
226
+ </script>
227
+ </body>
228
+ </html>