ucalyptus commited on
Commit
ce8e9f4
·
verified ·
1 Parent(s): 94a5ae8

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +444 -18
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Modernbert Viz
3
- emoji: 🐨
4
- colorFrom: pink
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: modernbert-viz
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,445 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
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.0">
6
+ <title>ModernBERT Features Visualization</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ /* Custom styles for better visualization */
10
+ body {
11
+ font-family: 'Inter', sans-serif; /* Using Inter font as standard */
12
+ }
13
+ canvas {
14
+ display: block;
15
+ background-color: #f3f4f6; /* Light gray background */
16
+ border-radius: 0.5rem; /* Rounded corners */
17
+ border: 1px solid #d1d5db; /* Gray border */
18
+ margin: 1rem auto; /* Center canvas with margin */
19
+ }
20
+ .token {
21
+ display: inline-block; /* Align tokens nicely */
22
+ padding: 0.3rem 0.6rem;
23
+ margin: 0.2rem;
24
+ border-radius: 0.375rem; /* Rounded corners for tokens */
25
+ font-size: 0.875rem; /* Smaller font size */
26
+ font-weight: 500;
27
+ min-width: 30px; /* Ensure minimum width */
28
+ text-align: center;
29
+ }
30
+ .token-real { background-color: #60a5fa; color: white; } /* Blue for real tokens */
31
+ .token-pad { background-color: #e5e7eb; color: #6b7280; } /* Gray for padding */
32
+ .token-attend { border: 2px solid #f87171; } /* Red border for attending token */
33
+ .token-attended { background-color: #fbbf24; color: white; } /* Amber for attended tokens */
34
+ .token-local { background-color: #a78bfa; color: white; } /* Violet for local attention window */
35
+
36
+ /* Ensure canvas is responsive */
37
+ #animationCanvas {
38
+ width: 100%;
39
+ max-width: 800px; /* Limit max width for larger screens */
40
+ height: auto; /* Adjust height automatically */
41
+ aspect-ratio: 16 / 9; /* Maintain aspect ratio, adjust as needed */
42
+ }
43
+
44
+ /* Style buttons */
45
+ button {
46
+ transition: all 0.2s ease-in-out; /* Smooth transitions */
47
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Subtle shadow */
48
+ }
49
+ button:hover {
50
+ transform: translateY(-1px); /* Slight lift on hover */
51
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); /* Enhanced shadow on hover */
52
+ }
53
+ button:active {
54
+ transform: translateY(0px); /* Press effect */
55
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
56
+ }
57
+ </style>
58
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
59
+ </head>
60
+ <body class="bg-gray-100 p-4 md:p-8">
61
+
62
+ <div class="max-w-4xl mx-auto bg-white p-6 rounded-lg shadow-md">
63
+ <h1 class="text-2xl md:text-3xl font-bold text-center text-gray-800 mb-6">Visualizing ModernBERT Efficiency Features</h1>
64
+
65
+ <canvas id="animationCanvas"></canvas>
66
+
67
+ <div class="flex flex-wrap justify-center gap-3 mt-6 mb-4">
68
+ <button id="btnPadding" class="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Padding</button>
69
+ <button id="btnUnpadding" class="bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Unpadding</button>
70
+ <button id="btnPacking" class="bg-purple-500 hover:bg-purple-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Sequence Packing</button>
71
+ <button id="btnLocalAttn" class="bg-indigo-500 hover:bg-indigo-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Local Attention</button>
72
+ <button id="btnGlobalAttn" class="bg-red-500 hover:bg-red-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Global Attention</button>
73
+ <button id="btnReset" class="bg-gray-500 hover:bg-gray-600 text-white font-semibold py-2 px-4 rounded-lg shadow">Reset</button>
74
+ </div>
75
+
76
+ <div id="explanation" class="mt-4 p-4 bg-gray-50 border border-gray-200 rounded-lg text-gray-700 min-h-[100px]">
77
+ Click a button above to see the animation and explanation.
78
+ </div>
79
+
80
+ <div class="mt-6 p-4 bg-gray-50 border border-gray-200 rounded-lg">
81
+ <h3 class="font-semibold mb-2 text-gray-800">Legend:</h3>
82
+ <div class="flex flex-wrap gap-2 items-center">
83
+ <span class="token token-real">Token</span>
84
+ <span class="token token-pad">Pad</span>
85
+ <span class="token token-attend">Attending</span>
86
+ <span class="token token-attended">Attended</span>
87
+ <span class="token token-local">Local Window</span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+
92
+ <script>
93
+ const canvas = document.getElementById('animationCanvas');
94
+ const ctx = canvas.getContext('2d');
95
+ const explanationDiv = document.getElementById('explanation');
96
+
97
+ // --- Configuration ---
98
+ const tokenWidth = 45;
99
+ const tokenHeight = 30;
100
+ const padding = 10; // Padding around tokens and between rows
101
+ const animationSpeed = 2; // Higher is faster
102
+
103
+ let sequences = [
104
+ ['T1', 'T2', 'T3', 'T4', 'T5'],
105
+ ['T1', 'T2', 'T3'],
106
+ ['T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
107
+ ['T1', 'T2']
108
+ ];
109
+ const maxSeqLen = 8; // Max length for padding example
110
+ const packMaxLen = 10; // Max length for packing example
111
+ const localWindowSize = 3; // e.g., attend to self +/- 1
112
+
113
+ let animationFrameId = null; // To control animation loop
114
+
115
+ // --- Drawing Functions ---
116
+ function drawToken(x, y, text, type = 'real', highlight = 'none') {
117
+ ctx.font = '12px Inter';
118
+ ctx.textAlign = 'center';
119
+ ctx.textBaseline = 'middle';
120
+
121
+ let bgColor = '#60a5fa'; // token-real (blue)
122
+ let textColor = 'white';
123
+ let borderColor = null;
124
+
125
+ if (type === 'pad') {
126
+ bgColor = '#e5e7eb'; // token-pad (gray)
127
+ textColor = '#6b7280';
128
+ } else if (type === 'attended') {
129
+ bgColor = '#fbbf24'; // token-attended (amber)
130
+ } else if (type === 'local') {
131
+ bgColor = '#a78bfa'; // token-local (violet)
132
+ }
133
+
134
+ if (highlight === 'attending') {
135
+ borderColor = '#f87171'; // token-attend (red)
136
+ }
137
+
138
+ // Draw background rectangle
139
+ ctx.fillStyle = bgColor;
140
+ ctx.beginPath();
141
+ ctx.roundRect(x, y, tokenWidth, tokenHeight, 5); // Use roundRect for rounded corners
142
+ ctx.fill();
143
+
144
+ // Draw border if needed
145
+ if (borderColor) {
146
+ ctx.strokeStyle = borderColor;
147
+ ctx.lineWidth = 2;
148
+ ctx.stroke();
149
+ }
150
+
151
+ // Draw text
152
+ ctx.fillStyle = textColor;
153
+ ctx.fillText(text, x + tokenWidth / 2, y + tokenHeight / 2);
154
+ }
155
+
156
+ function drawSequence(x, y, sequence, highlightMap = {}) {
157
+ sequence.forEach((token, index) => {
158
+ const tokenX = x + index * (tokenWidth + padding);
159
+ const tokenType = (typeof token === 'string' && token.startsWith('T')) ? 'real' : 'pad';
160
+ const highlight = highlightMap[index] || 'none';
161
+ drawToken(tokenX, y, token, tokenType, highlight);
162
+ });
163
+ }
164
+
165
+ function clearCanvas() {
166
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
167
+ }
168
+
169
+ // --- Animation Logic ---
170
+
171
+ // 1. Padding Animation
172
+ function animatePadding() {
173
+ cancelAnimationFrame(animationFrameId); // Stop previous animation
174
+ explanationDiv.innerHTML = `
175
+ <h3 class="font-semibold mb-1">Padding</h3>
176
+ Traditional processing requires all sequences in a batch to have the same length. Shorter sequences are "padded" with special (PAD) tokens to match the longest sequence. This wastes computation on meaningless tokens.
177
+ `;
178
+ let currentLengths = sequences.map(() => 0);
179
+ const targetMaxLength = Math.max(...sequences.map(s => s.length));
180
+ const paddedSequences = sequences.map(seq => {
181
+ const padsNeeded = targetMaxLength - seq.length;
182
+ return [...seq, ...Array(padsNeeded).fill('Pad')];
183
+ });
184
+
185
+ let progress = 0; // Represents how many tokens are shown
186
+ const totalSteps = targetMaxLength;
187
+
188
+ function step() {
189
+ clearCanvas();
190
+ const startY = padding * 3; // Start drawing lower
191
+
192
+ paddedSequences.forEach((seq, i) => {
193
+ const y = startY + i * (tokenHeight + padding * 2); // Increased vertical spacing
194
+ const displayLength = Math.min(seq.length, Math.ceil(progress));
195
+ drawSequence(padding * 2, y, seq.slice(0, displayLength));
196
+ });
197
+
198
+ if (progress < totalSteps) {
199
+ progress += animationSpeed / 10; // Adjust speed
200
+ animationFrameId = requestAnimationFrame(step);
201
+ }
202
+ }
203
+ step();
204
+ }
205
+
206
+ // 2. Unpadding Animation
207
+ function animateUnpadding() {
208
+ cancelAnimationFrame(animationFrameId);
209
+ explanationDiv.innerHTML = `
210
+ <h3 class="font-semibold mb-1">Unpadding</h3>
211
+ Unpadding removes the PAD tokens before processing. Sequences are treated individually (conceptually), avoiding wasted computation. ModernBERT concatenates these unpadded sequences.
212
+ `;
213
+ const targetMaxLength = Math.max(...sequences.map(s => s.length));
214
+ const paddedSequences = sequences.map(seq => {
215
+ const padsNeeded = targetMaxLength - seq.length;
216
+ return [...seq, ...Array(padsNeeded).fill('Pad')];
217
+ });
218
+
219
+ let fadeAmount = 1; // 1 = fully visible, 0 = invisible
220
+
221
+ function step() {
222
+ clearCanvas();
223
+ const startY = padding * 3;
224
+
225
+ ctx.globalAlpha = fadeAmount; // Apply fade effect
226
+
227
+ paddedSequences.forEach((seq, i) => {
228
+ const y = startY + i * (tokenHeight + padding * 2);
229
+ seq.forEach((token, index) => {
230
+ const tokenX = padding * 2 + index * (tokenWidth + padding);
231
+ const isPad = token === 'Pad';
232
+ // Only fade out padding tokens
233
+ ctx.globalAlpha = isPad ? fadeAmount : 1;
234
+ drawToken(tokenX, y, token, isPad ? 'pad' : 'real');
235
+ });
236
+ });
237
+
238
+ ctx.globalAlpha = 1; // Reset alpha
239
+
240
+ if (fadeAmount > 0) {
241
+ fadeAmount -= 0.02 * animationSpeed; // Fade out speed
242
+ animationFrameId = requestAnimationFrame(step);
243
+ } else {
244
+ // After fading, show only original tokens
245
+ clearCanvas();
246
+ sequences.forEach((seq, i) => {
247
+ const y = startY + i * (tokenHeight + padding * 2);
248
+ drawSequence(padding * 2, y, seq);
249
+ });
250
+ }
251
+ }
252
+ step();
253
+ }
254
+
255
+ // 3. Sequence Packing Animation
256
+ function animateSequencePacking() {
257
+ cancelAnimationFrame(animationFrameId);
258
+ explanationDiv.innerHTML = `
259
+ <h3 class="font-semibold mb-1">Sequence Packing</h3>
260
+ After unpadding, sequences are concatenated (packed) together into longer sequences, up to the model's maximum length (e.g., ${packMaxLen} here). This maximizes GPU utilization by processing more real tokens per batch. Careful masking ensures tokens only attend within their original sequence.
261
+ `;
262
+
263
+ let packedSequences = [];
264
+ let currentPack = [];
265
+ let currentLen = 0;
266
+
267
+ sequences.forEach(seq => {
268
+ if (currentLen + seq.length <= packMaxLen) {
269
+ currentPack.push(...seq);
270
+ currentLen += seq.length;
271
+ } else {
272
+ packedSequences.push([...currentPack]);
273
+ currentPack = [...seq];
274
+ currentLen = seq.length;
275
+ }
276
+ });
277
+ if (currentPack.length > 0) {
278
+ packedSequences.push(currentPack);
279
+ }
280
+
281
+ let progress = 0; // How many sequences are shown packed
282
+ const totalSequences = packedSequences.length;
283
+
284
+ function step() {
285
+ clearCanvas();
286
+ const startY = padding * 3;
287
+ let currentY = startY;
288
+
289
+ // Draw original sequences first (fading out)
290
+ const fade = 1 - (progress / totalSequences);
291
+ ctx.globalAlpha = Math.max(0, fade);
292
+ sequences.forEach((seq, i) => {
293
+ const y = startY + i * (tokenHeight + padding * 2);
294
+ drawSequence(padding * 2, y, seq);
295
+ });
296
+ ctx.globalAlpha = 1.0;
297
+
298
+
299
+ // Draw packed sequences (fading in)
300
+ const fadeIn = progress / totalSequences;
301
+ ctx.globalAlpha = Math.min(1, fadeIn * 2); // Faster fade in
302
+ packedSequences.slice(0, Math.ceil(progress)).forEach((pack, i) => {
303
+ const y = startY + i * (tokenHeight + padding * 2); // Draw packed below originals initially
304
+ drawSequence(padding * 2, y, pack);
305
+ currentY = y + tokenHeight + padding * 2;
306
+ });
307
+ ctx.globalAlpha = 1.0;
308
+
309
+
310
+ if (progress < totalSequences) {
311
+ progress += animationSpeed / 20; // Adjust speed
312
+ animationFrameId = requestAnimationFrame(step);
313
+ } else {
314
+ // Final state: only packed sequences
315
+ clearCanvas();
316
+ packedSequences.forEach((pack, i) => {
317
+ const y = startY + i * (tokenHeight + padding * 2);
318
+ drawSequence(padding * 2, y, pack);
319
+ });
320
+ }
321
+ }
322
+ step();
323
+ }
324
+
325
+ // 4. Attention Animations (Local/Global)
326
+ function animateAttention(isGlobal) {
327
+ cancelAnimationFrame(animationFrameId);
328
+ const seq = sequences[2]; // Use the longest sequence for demo
329
+ const midIndex = Math.floor(seq.length / 2); // Token that will 'attend'
330
+ explanationDiv.innerHTML = `
331
+ <h3 class="font-semibold mb-1">${isGlobal ? 'Global' : 'Local'} Attention</h3>
332
+ Attention allows tokens to "look" at other tokens to understand context.
333
+ <b>${isGlobal ? 'Global Attention:' : 'Local Attention:'}</b>
334
+ ${isGlobal
335
+ ? 'Every token attends to every other token in the sequence. Powerful but computationally expensive, especially for long sequences.'
336
+ : `Each token attends only to a fixed-size window of nearby tokens (e.g., +/- ${Math.floor(localWindowSize / 2)} here). Much faster for long sequences.`
337
+ } ModernBERT alternates between these layers.
338
+ `;
339
+
340
+ let highlightProgress = 0; // 0 to 1
341
+
342
+ function step() {
343
+ clearCanvas();
344
+ const startY = padding * 3;
345
+ const startX = padding * 2;
346
+
347
+ let highlightMap = {};
348
+ highlightMap[midIndex] = 'attending'; // The token doing the attending
349
+
350
+ const currentHighlight = Math.min(1, highlightProgress);
351
+
352
+ if (isGlobal) {
353
+ // Highlight all tokens based on progress
354
+ for (let i = 0; i < seq.length; i++) {
355
+ if (i !== midIndex) {
356
+ // Simple linear fade-in for attended tokens
357
+ if (Math.random() < currentHighlight) { // Randomly highlight based on progress for effect
358
+ highlightMap[i] = 'attended';
359
+ }
360
+ }
361
+ }
362
+ } else { // Local Attention
363
+ const windowStart = Math.max(0, midIndex - Math.floor(localWindowSize / 2));
364
+ const windowEnd = Math.min(seq.length - 1, midIndex + Math.floor(localWindowSize / 2));
365
+
366
+ for (let i = windowStart; i <= windowEnd; i++) {
367
+ // Highlight based on progress within the window
368
+ if (i !== midIndex) {
369
+ const dist = Math.abs(i - midIndex);
370
+ const requiredProgress = dist / (localWindowSize / 2); // Closer tokens highlight sooner
371
+ if (currentHighlight >= requiredProgress) {
372
+ highlightMap[i] = 'local'; // Use 'local' type for window visualization
373
+ }
374
+ }
375
+ }
376
+ }
377
+
378
+ drawSequence(startX, startY, seq, highlightMap);
379
+
380
+ if (highlightProgress < 1) {
381
+ highlightProgress += 0.01 * animationSpeed;
382
+ animationFrameId = requestAnimationFrame(step);
383
+ } else {
384
+ // Ensure final state is fully highlighted
385
+ clearCanvas();
386
+ highlightMap = {};
387
+ highlightMap[midIndex] = 'attending';
388
+ if (isGlobal) {
389
+ for (let i = 0; i < seq.length; i++) if (i !== midIndex) highlightMap[i] = 'attended';
390
+ } else {
391
+ const windowStart = Math.max(0, midIndex - Math.floor(localWindowSize / 2));
392
+ const windowEnd = Math.min(seq.length - 1, midIndex + Math.floor(localWindowSize / 2));
393
+ for (let i = windowStart; i <= windowEnd; i++) if (i !== midIndex) highlightMap[i] = 'local';
394
+ }
395
+ drawSequence(startX, startY, seq, highlightMap);
396
+ }
397
+ }
398
+ step();
399
+ }
400
+
401
+ // --- Reset Function ---
402
+ function resetVisualization() {
403
+ cancelAnimationFrame(animationFrameId);
404
+ clearCanvas();
405
+ explanationDiv.innerHTML = 'Click a button above to see the animation and explanation.';
406
+ // Optionally redraw initial state if needed
407
+ // drawInitialState(); // Implement if you want a default view
408
+ }
409
+
410
+ // --- Event Listeners ---
411
+ document.getElementById('btnPadding').addEventListener('click', animatePadding);
412
+ document.getElementById('btnUnpadding').addEventListener('click', animateUnpadding);
413
+ document.getElementById('btnPacking').addEventListener('click', animateSequencePacking);
414
+ document.getElementById('btnLocalAttn').addEventListener('click', () => animateAttention(false));
415
+ document.getElementById('btnGlobalAttn').addEventListener('click', () => animateAttention(true));
416
+ document.getElementById('btnReset').addEventListener('click', resetVisualization);
417
+
418
+
419
+ // --- Initial Setup & Resize ---
420
+ function resizeCanvas() {
421
+ // Make canvas resolution match its display size
422
+ const displayWidth = canvas.clientWidth;
423
+ const displayHeight = canvas.clientHeight; // Use clientHeight for aspect ratio consistency
424
+
425
+ if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
426
+ canvas.width = displayWidth;
427
+ canvas.height = displayHeight;
428
+ // Redraw current state if an animation was running? Or just reset?
429
+ // For simplicity, we'll reset on resize.
430
+ resetVisualization();
431
+ }
432
+ }
433
+
434
+ // Initial resize and setup listener
435
+ window.addEventListener('resize', resizeCanvas);
436
+ // Ensure initial sizing is correct after elements are laid out
437
+ window.addEventListener('load', () => {
438
+ resizeCanvas();
439
+ resetVisualization(); // Start clean
440
+ });
441
+
442
+ </script>
443
+
444
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ucalyptus/modernbert-viz" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
445
  </html>
prompts.txt ADDED
File without changes