firobeid commited on
Commit
eb18fb8
Β·
verified Β·
1 Parent(s): efb2859

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +226 -19
index.html CHANGED
@@ -1,19 +1,226 @@
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
+
2
+ <style>
3
+ .pe-wrap { font-family: var(--font-sans); padding: 1rem 0; }
4
+ .pe-title { font-size: 15px; font-weight: 500; color: var(--color-text-primary); margin-bottom: 4px; }
5
+ .pe-sub { font-size: 12px; color: var(--color-text-secondary); margin-bottom: 16px; }
6
+ .pe-canvas-wrap { position: relative; width: 100%; }
7
+ .pe-axis-label { font-size: 12px; color: var(--color-text-secondary); text-align: center; }
8
+ .pe-y-label { writing-mode: vertical-rl; transform: rotate(180deg); font-size: 12px; color: var(--color-text-secondary); display: flex; align-items: center; justify-content: center; min-width: 20px; }
9
+ .pe-row { display: flex; align-items: stretch; gap: 8px; }
10
+ .pe-legend { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 11px; color: var(--color-text-secondary); }
11
+ .pe-legend-bar { flex: 1; height: 12px; border-radius: 3px; }
12
+ .annotation-box { background: var(--color-background-secondary); border: 0.5px solid var(--color-border-tertiary); border-radius: 8px; padding: 10px 14px; margin-top: 14px; font-size: 12px; color: var(--color-text-secondary); line-height: 1.6; }
13
+ .ann-row { display: flex; gap: 16px; }
14
+ .ann-col { flex: 1; }
15
+ .ann-head { font-weight: 500; font-size: 12px; color: var(--color-text-primary); margin-bottom: 3px; }
16
+ .highlight-col { border: 2px solid #EF9F27; border-radius: 3px; position: absolute; pointer-events: none; }
17
+ .highlight-row { border: 2px solid #1D9E75; border-radius: 3px; position: absolute; pointer-events: none; }
18
+ .pe-controls { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; align-items: center; }
19
+ .pe-btn { background: var(--color-background-secondary); border: 0.5px solid var(--color-border-secondary); border-radius: 6px; padding: 4px 12px; font-size: 12px; cursor: pointer; color: var(--color-text-primary); }
20
+ .pe-btn.active { background: var(--color-background-info); color: var(--color-text-info); border-color: var(--color-border-info); }
21
+ .tooltip { position: absolute; background: var(--color-background-primary); border: 0.5px solid var(--color-border-secondary); border-radius: 6px; padding: 6px 10px; font-size: 11px; color: var(--color-text-primary); pointer-events: none; opacity: 0; transition: opacity 0.15s; white-space: nowrap; z-index: 10; }
22
+ </style>
23
+ <div class="pe-wrap">
24
+ <div class="pe-title">Positional Encoding Matrix</div>
25
+ <div class="pe-sub">Each cell = PE(pos, i). Hover to inspect. Click a column (dimension) or row (position) to highlight it.</div>
26
+
27
+ <div class="pe-controls">
28
+ <span style="font-size:12px;color:var(--color-text-secondary)">Hover mode:</span>
29
+ <button class="pe-btn active" id="btn-cell" onclick="setMode('cell')">Cell value</button>
30
+ <button class="pe-btn" id="btn-col" onclick="setMode('col')">Column (dimension)</button>
31
+ <button class="pe-btn" id="btn-row" onclick="setMode('row')">Row (position)</button>
32
+ </div>
33
+
34
+ <div class="pe-row">
35
+ <div class="pe-y-label" id="ylabel">Sequence position <em>(pos ↓)</em></div>
36
+ <div style="flex:1;position:relative;">
37
+ <canvas id="pe-canvas" style="width:100%;display:block;cursor:crosshair;"></canvas>
38
+ <div class="tooltip" id="tt"></div>
39
+ </div>
40
+ </div>
41
+ <div style="margin-left:28px">
42
+ <div class="pe-axis-label">Embedding dimension <em>(i β†’)</em></div>
43
+ <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--color-text-secondary);margin-top:2px;margin-left:2px;margin-right:2px">
44
+ <span>i=0 (fast)</span><span>i=128</span><span>i=256 (slow)</span>
45
+ </div>
46
+ </div>
47
+
48
+ <div class="pe-legend" style="margin-left:28px">
49
+ <span>βˆ’1</span>
50
+ <canvas id="legend-bar" width="300" height="12" style="flex:1;border-radius:3px;"></canvas>
51
+ <span>+1</span>
52
+ </div>
53
+
54
+ <div class="annotation-box" id="ann-box">
55
+ <div class="ann-row">
56
+ <div class="ann-col">
57
+ <div class="ann-head">⚑ Fast dimensions (small <em>i</em>, left)</div>
58
+ The sine wave completes many full cycles across just a few positions. Adjacent words look very different here β€” the model uses this to detect <strong>neighbors</strong>.
59
+ </div>
60
+ <div class="ann-col">
61
+ <div class="ann-head">🐒 Slow dimensions (large <em>i</em>, right)</div>
62
+ The wavelength is enormous (up to 10,000Β·2Ο€). Values barely change between consecutive words, but differ noticeably over hundreds of positions β€” telling the model about <strong>long-range structure</strong>.
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+
68
+ <script>
69
+ const ROWS = 50;
70
+ const COLS = 256;
71
+ const D_MODEL = 512;
72
+
73
+ function pe(pos, i) {
74
+ const denom = Math.pow(10000, (2 * Math.floor(i / 2)) / D_MODEL);
75
+ return (i % 2 === 0) ? Math.sin(pos / denom) : Math.cos(pos / denom);
76
+ }
77
+
78
+ const matrix = [];
79
+ for (let r = 0; r < ROWS; r++) {
80
+ matrix[r] = [];
81
+ for (let c = 0; c < COLS; c++) {
82
+ matrix[r][c] = pe(r, c);
83
+ }
84
+ }
85
+
86
+ function valToColor(v, alpha) {
87
+ const t = (v + 1) / 2;
88
+ const isDark = matchMedia('(prefers-color-scheme: dark)').matches;
89
+ if (isDark) {
90
+ if (t > 0.5) {
91
+ const s = (t - 0.5) * 2;
92
+ const r = Math.round(30 + s * 200), g = Math.round(40 + s * 100), b = Math.round(80 + s * 80);
93
+ return `rgba(${r},${g},${b},${alpha})`;
94
+ } else {
95
+ const s = (0.5 - t) * 2;
96
+ const r = Math.round(30 + s * 180), g = Math.round(40 + s * 40), b = Math.round(80 + s * 120);
97
+ return `rgba(${r},${g},${b},${alpha})`;
98
+ }
99
+ } else {
100
+ if (t > 0.5) {
101
+ const s = (t - 0.5) * 2;
102
+ const r = Math.round(248 - s * 130), g = Math.round(248 - s * 30), b = Math.round(248 - s * 200);
103
+ return `rgba(${r},${g},${b},${alpha})`;
104
+ } else {
105
+ const s = (0.5 - t) * 2;
106
+ const r = Math.round(248 - s * 50), g = Math.round(248 - s * 140), b = Math.round(248 - s * 20);
107
+ return `rgba(${r},${g},${b},${alpha})`;
108
+ }
109
+ }
110
+ }
111
+
112
+ const canvas = document.getElementById('pe-canvas');
113
+ const ctx = canvas.getContext('2d');
114
+ let cellW, cellH, dpr;
115
+
116
+ function drawMatrix(highlightCol = -1, highlightRow = -1) {
117
+ const w = canvas.offsetWidth;
118
+ const h = Math.round(w * (ROWS / COLS) * 1.4);
119
+ dpr = window.devicePixelRatio || 1;
120
+ canvas.width = w * dpr;
121
+ canvas.height = h * dpr;
122
+ canvas.style.height = h + 'px';
123
+ ctx.scale(dpr, dpr);
124
+ cellW = w / COLS;
125
+ cellH = h / ROWS;
126
+
127
+ for (let r = 0; r < ROWS; r++) {
128
+ for (let c = 0; c < COLS; c++) {
129
+ const v = matrix[r][c];
130
+ const isHL = (highlightCol >= 0 && c === highlightCol) || (highlightRow >= 0 && r === highlightRow);
131
+ ctx.fillStyle = valToColor(v, isHL ? 1 : (highlightCol >= 0 || highlightRow >= 0 ? 0.35 : 1));
132
+ ctx.fillRect(c * cellW, r * cellH, cellW + 0.5, cellH + 0.5);
133
+ }
134
+ }
135
+
136
+ if (highlightCol >= 0) {
137
+ ctx.strokeStyle = '#EF9F27';
138
+ ctx.lineWidth = 2;
139
+ ctx.strokeRect(highlightCol * cellW + 1, 1, cellW - 1, ROWS * cellH - 2);
140
+ }
141
+ if (highlightRow >= 0) {
142
+ ctx.strokeStyle = '#1D9E75';
143
+ ctx.lineWidth = 2;
144
+ ctx.strokeRect(1, highlightRow * cellH + 1, COLS * cellW - 2, cellH - 1);
145
+ }
146
+ }
147
+
148
+ function drawLegend() {
149
+ const lb = document.getElementById('legend-bar');
150
+ const lctx = lb.getContext('2d');
151
+ const w = lb.offsetWidth || 300;
152
+ lb.width = w * (window.devicePixelRatio || 1);
153
+ lb.style.width = '100%';
154
+ for (let x = 0; x < w; x++) {
155
+ const v = (x / w) * 2 - 1;
156
+ lctx.fillStyle = valToColor(v, 1);
157
+ lctx.fillRect(x * (window.devicePixelRatio || 1), 0, (window.devicePixelRatio || 1), 12);
158
+ }
159
+ }
160
+
161
+ let mode = 'cell';
162
+ function setMode(m) {
163
+ mode = m;
164
+ ['cell','col','row'].forEach(k => document.getElementById('btn-'+k).classList.toggle('active', k === m));
165
+ drawMatrix();
166
+ }
167
+
168
+ canvas.addEventListener('mousemove', function(e) {
169
+ const rect = canvas.getBoundingClientRect();
170
+ const x = e.clientX - rect.left;
171
+ const y = e.clientY - rect.top;
172
+ const col = Math.floor(x / (rect.width / COLS));
173
+ const row = Math.floor(y / (rect.height / ROWS));
174
+ if (col < 0 || col >= COLS || row < 0 || row >= ROWS) return;
175
+
176
+ const tt = document.getElementById('tt');
177
+ const v = matrix[row][col].toFixed(4);
178
+
179
+ if (mode === 'cell') {
180
+ drawMatrix();
181
+ tt.innerHTML = `<b>pos=${row}, i=${col}</b><br>value = ${v}<br>${col % 2 === 0 ? 'sin' : 'cos'} wave`;
182
+ } else if (mode === 'col') {
183
+ drawMatrix(-1, -1);
184
+ drawMatrix(col, -1);
185
+ const speed = col < 20 ? '⚑ fast' : col < 100 ? '⚑ moderate' : '🐒 slow';
186
+ tt.innerHTML = `<b>Dimension i=${col}</b> (${speed})<br>wavelength β‰ˆ ${(2 * Math.PI * Math.pow(10000, col / D_MODEL)).toFixed(0)}`;
187
+ } else {
188
+ drawMatrix(-1, row);
189
+ tt.innerHTML = `<b>Position pos=${row}</b><br>Word at index ${row} in the sequence`;
190
+ }
191
+
192
+ tt.style.left = Math.min(x + 10, rect.width - 180) + 'px';
193
+ tt.style.top = Math.max(y - 36, 0) + 'px';
194
+ tt.style.opacity = '1';
195
+ });
196
+
197
+ canvas.addEventListener('mouseleave', function() {
198
+ document.getElementById('tt').style.opacity = '0';
199
+ drawMatrix();
200
+ });
201
+
202
+ canvas.addEventListener('click', function(e) {
203
+ const rect = canvas.getBoundingClientRect();
204
+ const x = e.clientX - rect.left;
205
+ const y = e.clientY - rect.top;
206
+ const col = Math.floor(x / (rect.width / COLS));
207
+ const row = Math.floor(y / (rect.height / ROWS));
208
+ if (mode === 'col') {
209
+ const speed = col < 20 ? 'fast (high frequency)' : col < 100 ? 'moderate frequency' : 'slow (low frequency)';
210
+ const ann = document.getElementById('ann-box');
211
+ ann.innerHTML = `<div class="ann-row"><div class="ann-col"><div class="ann-head" style="color:#BA7517">Dimension i=${col} β€” ${speed}</div>
212
+ Looking down this column (vertical), the value at each row changes ${col < 30 ? '<strong>rapidly</strong> β€” adjacent words look very different. The model can distinguish neighbors.' : col > 150 ? '<strong>barely at all</strong> between neighbors β€” but significantly over hundreds of positions. Good for long-range context.' : 'at a moderate rate.'}<br><br>Wavelength β‰ˆ ${(2 * Math.PI * Math.pow(10000, col / D_MODEL)).toFixed(0)} radians.</div></div>`;
213
+ } else if (mode === 'row') {
214
+ const ann = document.getElementById('ann-box');
215
+ ann.innerHTML = `<div class="ann-row"><div class="ann-col"><div class="ann-head" style="color:#0F6E56">Position pos=${row} β€” the lookup table row for word ${row}</div>
216
+ Reading across this row (horizontal), you see how the 512-dimensional encoding vector for <em>any word at position ${row}</em> looks: left side oscillates fast, right side is nearly flat. When the Transformer sees a word here, it adds this entire row to the word's embedding.</div></div>`;
217
+ }
218
+ });
219
+
220
+ setTimeout(() => {
221
+ drawMatrix();
222
+ drawLegend();
223
+ }, 50);
224
+
225
+ window.addEventListener('resize', () => { drawMatrix(); drawLegend(); });
226
+ </script>