ameythakur commited on
Commit
0d15004
Β·
verified Β·
1 Parent(s): bcc3640

Knowledge Lifecycle

Browse files
Files changed (3) hide show
  1. index.html +27 -16
  2. main.js +50 -31
  3. style.css +66 -0
index.html CHANGED
@@ -29,8 +29,8 @@
29
  <header>
30
  <h1>LLM Knowledge Lifecycle</h1>
31
  <p class="subtitle">
32
- A language model carries two memories: what it learned in training, and what you place in
33
- its prompt. When they disagree, which one wins? Companion demonstration for
34
  <em>The Knowledge Lifecycle of Large Language Models</em>.
35
  </p>
36
  <p class="badges">
@@ -41,8 +41,8 @@
41
  </p>
42
  <div class="alert a-important">
43
  <span class="alert-title">Important</span>
44
- The model runs entirely in your browser. Every measurement is deterministic and computed
45
- locally; nothing leaves your machine. First measurement downloads the model once (128 MB).
46
  </div>
47
  </header>
48
 
@@ -62,10 +62,8 @@
62
  <section id="probe" class="panel active">
63
 
64
  <p class="lede">
65
- Each preset is a real, documented fact change that happened after this model's training
66
- data was collected. The model's weights hold the old world; the corrective document in the
67
- prompt holds the new one. Pick a case, press Measure, and watch which memory controls the
68
- answer.
69
  </p>
70
 
71
  <div class="presets">
@@ -102,7 +100,7 @@
102
  <p id="load-status" class="dim"></p>
103
  </div>
104
 
105
- <div id="results" hidden>
106
 
107
  <div class="verdict-row">
108
  <span id="verdict-chip" class="chip"></span>
@@ -112,13 +110,13 @@
112
  <p id="narrative" class="narrative"></p>
113
 
114
  <h3>The two distributions, side by side</h3>
115
- <p class="dim small">Next-token probability without the document (grey) and with it (blue).
116
- The correct answer is outlined in green; if its bar is invisible, that is the finding.</p>
117
  <div id="bars"></div>
118
 
119
  <div class="gauge-block">
120
  <div class="gauge-label">
121
- <span>D<sub>sync</sub> &nbsp;<span class="dim">how lost the correct answer is</span></span>
122
  <strong id="r-dsync"></strong>
123
  </div>
124
  <div class="gauge">
@@ -130,7 +128,7 @@
130
 
131
  <div class="gauge-block">
132
  <div class="gauge-label">
133
- <span>I<sub>ctx</sub> &nbsp;<span class="dim">how much the document moved the model</span></span>
134
  <strong id="r-ictx"></strong>
135
  </div>
136
  <div class="gauge slim">
@@ -142,7 +140,7 @@
142
 
143
  <div class="temp-block">
144
  <div class="gauge-label">
145
- <span>Sampling temperature <span class="dim">(recomputed live from the measured logits)</span></span>
146
  <strong id="t-value">1.0</strong>
147
  </div>
148
  <input id="temp" type="range" min="0.2" max="2.0" step="0.1" value="1.0">
@@ -155,8 +153,8 @@
155
  <tr><td>P(answer | query alone)</td><td id="r-p0"></td></tr>
156
  <tr><td>P(answer | context + query)</td><td id="r-p1"></td></tr>
157
  <tr><td>Answer tokenization</td><td id="r-tok"></td></tr>
158
- <tr><td>D<sub>sync</sub> definition</td><td>&minus;ln P(answer | context + query), in nats</td></tr>
159
- <tr><td>I<sub>ctx</sub> definition</td><td>KL(with context &Vert; without), full vocabulary</td></tr>
160
  </table>
161
  </details>
162
  </div>
@@ -194,6 +192,19 @@
194
  <tr><td><span class="chip chip-influence">drift</span></td><td><strong>Twitter rename.</strong> Context lifts the right answer by orders of magnitude and still loses to " Twitter".</td></tr>
195
  </table>
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  <h2>Build your own probe</h2>
198
  <p>
199
  Any fact change with a single-word answer works. Three rules make a clean probe: the query
 
29
  <header>
30
  <h1>LLM Knowledge Lifecycle</h1>
31
  <p class="subtitle">
32
+ A model holds two memories: what it learned in training, and what you put in its prompt.
33
+ When they disagree, which one wins? Companion demonstration for
34
  <em>The Knowledge Lifecycle of Large Language Models</em>.
35
  </p>
36
  <p class="badges">
 
41
  </p>
42
  <div class="alert a-important">
43
  <span class="alert-title">Important</span>
44
+ The model runs in your browser. Nothing leaves your machine, and identical inputs always
45
+ give identical numbers. The first measurement downloads the model once, 128 MB.
46
  </div>
47
  </header>
48
 
 
62
  <section id="probe" class="panel active">
63
 
64
  <p class="lede">
65
+ Each preset is a documented fact change from after this model was trained. Its weights hold
66
+ the old world, the document in the prompt holds the new one. Press Measure to see which wins.
 
 
67
  </p>
68
 
69
  <div class="presets">
 
100
  <p id="load-status" class="dim"></p>
101
  </div>
102
 
103
+ <div id="results" role="region" aria-live="polite" aria-label="Measurement results" hidden>
104
 
105
  <div class="verdict-row">
106
  <span id="verdict-chip" class="chip"></span>
 
110
  <p id="narrative" class="narrative"></p>
111
 
112
  <h3>The two distributions, side by side</h3>
113
+ <p class="dim small">Probability of each candidate without the document (grey) and with it (blue).
114
+ The correct answer is outlined in green. If its bar is invisible, that is the finding.</p>
115
  <div id="bars"></div>
116
 
117
  <div class="gauge-block">
118
  <div class="gauge-label">
119
+ <span>D<sub>sync</sub> &nbsp;<span class="dim">how lost the correct answer is, in nats</span></span>
120
  <strong id="r-dsync"></strong>
121
  </div>
122
  <div class="gauge">
 
128
 
129
  <div class="gauge-block">
130
  <div class="gauge-label">
131
+ <span>I<sub>ctx</sub> &nbsp;<span class="dim">how much the document moved the model, in nats</span></span>
132
  <strong id="r-ictx"></strong>
133
  </div>
134
  <div class="gauge slim">
 
140
 
141
  <div class="temp-block">
142
  <div class="gauge-label">
143
+ <span>Sampling temperature <span class="dim">(how randomly the model picks its answer)</span></span>
144
  <strong id="t-value">1.0</strong>
145
  </div>
146
  <input id="temp" type="range" min="0.2" max="2.0" step="0.1" value="1.0">
 
153
  <tr><td>P(answer | query alone)</td><td id="r-p0"></td></tr>
154
  <tr><td>P(answer | context + query)</td><td id="r-p1"></td></tr>
155
  <tr><td>Answer tokenization</td><td id="r-tok"></td></tr>
156
+ <tr><td>D<sub>sync</sub> definition</td><td>&minus;ln P(answer given context and query): the negative natural logarithm of the correct answer's probability</td></tr>
157
+ <tr><td>I<sub>ctx</sub> definition</td><td>Kullback-Leibler divergence between the with-document and without-document distributions, over all 50,257 tokens</td></tr>
158
  </table>
159
  </details>
160
  </div>
 
192
  <tr><td><span class="chip chip-influence">drift</span></td><td><strong>Twitter rename.</strong> Context lifts the right answer by orders of magnitude and still loses to " Twitter".</td></tr>
193
  </table>
194
 
195
+
196
+ <h2>Terms used on this page</h2>
197
+ <table class="glossary">
198
+ <tr><td><strong>Token</strong></td><td>The unit a model reads and writes. Roughly a word or word fragment; " withdrawn" is one token, and the leading space is part of it.</td></tr>
199
+ <tr><td><strong>Parametric memory</strong></td><td>What the model absorbed into its weights during training. Fixed after training, and the model cannot tell you when it learned any of it.</td></tr>
200
+ <tr><td><strong>Context</strong></td><td>What you put in the prompt right now, including any document retrieved for the model to read.</td></tr>
201
+ <tr><td><strong>Nat</strong></td><td>A unit of information, measured with natural logarithms. Here it converts directly to probability: a value of <em>n</em> nats means the correct answer holds probability e<sup>&minus;n</sup>. One nat is roughly 37%, nine nats is roughly one in ten thousand.</td></tr>
202
+ <tr><td><strong>Surprisal</strong></td><td>How surprised the model is by an answer, written as &minus;ln P. Low when the model expected it, high when it did not. D<sub>sync</sub> is the surprisal of the correct answer.</td></tr>
203
+ <tr><td><strong>KL divergence</strong></td><td>A measure of how far one probability distribution sits from another. I<sub>ctx</sub> uses it to ask whether the document changed the model's mind about anything at all.</td></tr>
204
+ <tr><td><strong>Temperature</strong></td><td>How randomly a model picks among candidate answers. Low values make it repeat its favorite; high values spread the choice out.</td></tr>
205
+ <tr><td><strong>Quantized</strong></td><td>Weights stored at reduced precision so the model downloads and runs faster. This page uses 8-bit weights, which shift individual probabilities slightly without changing any conclusion.</td></tr>
206
+ </table>
207
+
208
  <h2>Build your own probe</h2>
209
  <p>
210
  Any fact change with a single-word answer works. Three rules make a clean probe: the query
main.js CHANGED
@@ -1,9 +1,11 @@
1
  // =============================================================================
2
  // File : main.js
3
  // Project : The Knowledge Lifecycle of Large Language Models
4
- // Purpose : Browser-side D_sync measurement engine: loads GPT-2, runs both prompt
5
- // conditions, and renders the narrative, bars, gauges, and diagnostics.
6
- // Tech Stack : JavaScript (ES modules), transformers.js 3.4.0, ONNX Runtime Web (WASM)
 
 
7
  // Authors : Amey Thakur (https://github.com/Amey-Thakur)
8
  // Sarvesh Talele (https://github.com/sarveshtalele)
9
  // Repository : https://github.com/Amey-Thakur/LLM-KNOWLEDGE-LIFECYCLE
@@ -23,19 +25,19 @@ const PRESETS = {
23
  query: "Question: Is Vioxx safe to prescribe? Answer: Vioxx is considered",
24
  context: "Context: In September 2004, Merck voluntarily withdrew Vioxx after trials revealed increased cardiovascular risks.",
25
  answer: " withdrawn",
26
- reading: "The paper's headline case. The withdrawal notice sits in the prompt, and the model still answers β€œsafe”. Expect D_sync deep past the 9.2-nat failure threshold; the paper's fp32 run measures 12.05 nats with I_ctx = 0.033.",
27
  },
28
  monarch: {
29
  query: "Question: Who is the current British monarch? Answer: The current British monarch is",
30
  context: "Context: Queen Elizabeth II died in September 2022. Charles III acceded to the throne and is the reigning King of the United Kingdom.",
31
  answer: " Charles",
32
- reading: "A subtler failure. The context raises P(Charles), but its strongest effect is boosting β€œ Queen”: merely mentioning the late monarch reinforces the stale association. Correct information can strengthen the wrong answer.",
33
  },
34
  twitter: {
35
  query: "Question: What is the social network Twitter called today? Answer: Twitter is now called",
36
  context: "Context: In July 2023, Twitter was rebranded as X under Elon Musk's ownership.",
37
  answer: " X",
38
- reading: "The context moves the distribution hard (the paper's fp32 run: I_ctx = 0.9 nats) and lifts the correct answer by orders of magnitude. The model still answers β€œTwitter”. Influence without resolution.",
39
  },
40
  };
41
 
@@ -115,18 +117,24 @@ function softmax(row, temperature = 1.0) {
115
  return probs;
116
  }
117
 
 
 
 
 
 
 
 
118
  function topK(probs, k) {
119
- const taken = new Set();
120
- const idx = [];
121
- for (let n = 0; n < k; n++) {
122
- let best = -1, bp = -1;
123
- for (let i = 0; i < probs.length; i++) {
124
- if (!taken.has(i) && probs[i] > bp) { bp = probs[i]; best = i; }
125
- }
126
- taken.add(best);
127
- idx.push(best);
128
  }
129
- return idx;
130
  }
131
 
132
  // ---------- rendering ----------
@@ -158,24 +166,35 @@ function renderBars(pPlain, pCtx, target) {
158
  + rows.join("");
159
  }
160
 
 
 
 
 
 
 
 
 
161
  function narrative(m) {
162
- const s = [];
163
- const topCtxTok = fmtTok(m.topCtx);
164
- const ansTok = fmtTok(m.answerPiece).trim();
165
- s.push(`With the corrective document in its prompt, the model's most likely continuation is β€œ${topCtxTok}” at ${fmtPct(m.pTopCtx)}.`);
166
  const odds = Math.round(1 / m.pt1);
167
- s.push(`The correct answer β€œ${ansTok}” receives ${fmtPct(m.pt1)}: about one chance in ${odds.toLocaleString()}.`);
168
- if (m.topCtx === m.topPlain && m.ictx < 0.05) {
169
- s.push(`The document changed almost nothing. The model's whole distribution moved by ${m.ictx.toFixed(3)} nats, and its preferred answer is the same one it gives with no document at all.`);
170
- } else if (m.pt1 > m.pt0 * 1.5 && m.topCtx !== fmtTok(m.answerPiece)) {
171
- const factor = (m.pt1 / m.pt0).toFixed(1);
172
- s.push(`The document helped: it multiplied the correct answer's probability by ${factor}. It still loses.`);
173
- } else if (m.pTopCtx > m.pTopPlainSameTok) {
174
- s.push(`Counterintuitively, the document made the leading wrong answer stronger, raising it from ${fmtPct(m.pTopPlainSameTok)} to ${fmtPct(m.pTopCtx)}. Mentioning a fact, even to correct it, reinforces the association.`);
175
  }
176
- if (m.topCtx === fmtTok(m.answerPiece)) {
177
- s.push("Here the document won: the model's top answer is the correct one. This is what synchronization looks like.");
178
  }
 
 
 
 
 
 
 
179
  return s.join(" ");
180
  }
181
 
@@ -286,7 +305,7 @@ $("run").addEventListener("click", async () => {
286
 
287
  const m = {
288
  pt0, pt1, dsync, ictx,
289
- answerPiece: pieces[0],
290
  topPlain: fmtTok(tokenizer.decode([topPlainId])),
291
  topCtx: fmtTok(tokenizer.decode([topCtxId])),
292
  pTopCtx: pCtx[topCtxId],
 
1
  // =============================================================================
2
  // File : main.js
3
  // Project : The Knowledge Lifecycle of Large Language Models
4
+ // Purpose : Browser-side measurement engine. Loads GPT-2, runs the two
5
+ // prompt conditions, and renders the narrative, the paired
6
+ // distributions, the gauges, and the stage diagnosis.
7
+ // Tech Stack : JavaScript (ES modules), transformers.js 3.4.0,
8
+ // ONNX Runtime Web (WASM)
9
  // Authors : Amey Thakur (https://github.com/Amey-Thakur)
10
  // Sarvesh Talele (https://github.com/sarveshtalele)
11
  // Repository : https://github.com/Amey-Thakur/LLM-KNOWLEDGE-LIFECYCLE
 
25
  query: "Question: Is Vioxx safe to prescribe? Answer: Vioxx is considered",
26
  context: "Context: In September 2004, Merck voluntarily withdrew Vioxx after trials revealed increased cardiovascular risks.",
27
  answer: " withdrawn",
28
+ reading: "The headline case. The withdrawal notice is in the prompt and the model still answers β€œsafe”. At full precision the paper measures 12.05 nats, far past the 9.2 failure threshold.",
29
  },
30
  monarch: {
31
  query: "Question: Who is the current British monarch? Answer: The current British monarch is",
32
  context: "Context: Queen Elizabeth II died in September 2022. Charles III acceded to the throne and is the reigning King of the United Kingdom.",
33
  answer: " Charles",
34
+ reading: "A subtler failure. The document does raise the correct answer, but its strongest effect is boosting β€œ Queen”. Naming a fact, even to correct it, reinforces the old association.",
35
  },
36
  twitter: {
37
  query: "Question: What is the social network Twitter called today? Answer: Twitter is now called",
38
  context: "Context: In July 2023, Twitter was rebranded as X under Elon Musk's ownership.",
39
  answer: " X",
40
+ reading: "Here the document moves the model hard and lifts the correct answer by orders of magnitude. It still answers β€œTwitter”. Influence without resolution.",
41
  },
42
  };
43
 
 
117
  return probs;
118
  }
119
 
120
+ /**
121
+ * Indices of the k largest probabilities, highest first.
122
+ *
123
+ * One pass over the vocabulary, maintaining a short sorted list. The obvious
124
+ * alternative, k full scans with a "already taken" set, costs k passes over
125
+ * 50,257 entries at every call site; this costs one.
126
+ */
127
  function topK(probs, k) {
128
+ const best = []; // indices, kept sorted by descending probability
129
+ for (let i = 0; i < probs.length; i++) {
130
+ const p = probs[i];
131
+ if (best.length === k && p <= probs[best[k - 1]]) continue;
132
+ let at = best.length;
133
+ while (at > 0 && probs[best[at - 1]] < p) at--;
134
+ best.splice(at, 0, i);
135
+ if (best.length > k) best.pop();
 
136
  }
137
+ return best;
138
  }
139
 
140
  // ---------- rendering ----------
 
166
  + rows.join("");
167
  }
168
 
169
+ /**
170
+ * Plain-language account of one measurement, written from the numbers.
171
+ *
172
+ * The observations are additive rather than exclusive: a single run can be
173
+ * both "the document helped" and "the document also strengthened the wrong
174
+ * answer", and an if/else chain would report only the first and hide the
175
+ * second, which is the more interesting half.
176
+ */
177
  function narrative(m) {
178
+ const answerWon = m.topCtx === m.answerPiece;
 
 
 
179
  const odds = Math.round(1 / m.pt1);
180
+ const s = [
181
+ `With the corrective document in its prompt, the model's most likely continuation is β€œ${m.topCtx}” at ${fmtPct(m.pTopCtx)}.`,
182
+ `The correct answer β€œ${m.answerPiece.trim()}” receives ${fmtPct(m.pt1)}: about one chance in ${odds.toLocaleString()}.`,
183
+ ];
184
+
185
+ if (m.ictx < 0.05) {
186
+ s.push(`The document barely registered: it moved the model's whole distribution by ${m.ictx.toFixed(3)} nats.`);
 
187
  }
188
+ if (m.pt1 > m.pt0 * 1.5) {
189
+ s.push(`It did help the correct answer, multiplying its probability by ${(m.pt1 / m.pt0).toFixed(1)}.`);
190
  }
191
+ if (!answerWon && m.pTopCtx > m.pTopPlainSameTok) {
192
+ s.push(`It also strengthened the leading wrong answer, raising β€œ${m.topCtx}” from ${fmtPct(m.pTopPlainSameTok)} to ${fmtPct(m.pTopCtx)}: mentioning a fact, even to correct it, reinforces the association.`);
193
+ }
194
+
195
+ s.push(answerWon
196
+ ? "The document won here: the model's top answer is the correct one. This is what synchronization looks like."
197
+ : "The parametric memory still controls the answer.");
198
  return s.join(" ");
199
  }
200
 
 
305
 
306
  const m = {
307
  pt0, pt1, dsync, ictx,
308
+ answerPiece: fmtTok(pieces[0]),
309
  topPlain: fmtTok(tokenizer.decode([topPlainId])),
310
  topCtx: fmtTok(tokenizer.decode([topCtxId])),
311
  pTopCtx: pCtx[topCtxId],
style.css CHANGED
@@ -276,3 +276,69 @@ textarea:focus, input:focus, select:focus, #run:focus-visible, .preset:focus-vis
276
  outline: 2px solid var(--accent); outline-offset: 1px;
277
  }
278
  .stagebar { border-radius: 6px; overflow: hidden; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  outline: 2px solid var(--accent); outline-offset: 1px;
277
  }
278
  .stagebar { border-radius: 6px; overflow: hidden; }
279
+
280
+ /* narrow screens: stack the paired bars rather than crushing four columns */
281
+ @media (max-width: 620px) {
282
+ body { padding: 2rem 1rem 3rem; }
283
+ .bar-tok { flex: 0 0 5rem; font-size: .78rem; }
284
+ .bar-pair { grid-template-columns: 1fr 4rem; row-gap: .2rem; }
285
+ .row { flex-wrap: wrap; }
286
+ #run { width: 100%; }
287
+ .authors { gap: 1.5rem; }
288
+ .stagebar { font-size: .62rem; }
289
+ .gauge-ticks span { font-size: .66rem; }
290
+ }
291
+
292
+ /* ---------------------------------------------------------------------------
293
+ Typographic measure and rhythm.
294
+
295
+ Prose is capped near 68 characters. Beyond that the eye loses the line
296
+ start on the return sweep, which is what made the earlier full-width
297
+ paragraphs tiring to read. Tables, bars, and gauges stay full width: they
298
+ are scanned, not read.
299
+ --------------------------------------------------------------------------- */
300
+
301
+ body { line-height: 1.65; }
302
+
303
+ .subtitle { max-width: 38rem; font-size: 1.02rem; }
304
+ .lede,
305
+ .reading,
306
+ #guide p,
307
+ .narrative,
308
+ .note { max-width: 46rem; }
309
+ .alert { max-width: 46rem; line-height: 1.6; }
310
+ .subtitle { max-width: 44rem; }
311
+
312
+ .lede { margin-bottom: 1.6rem; font-size: 1rem; }
313
+ .reading { margin: 1rem 0 1.8rem; }
314
+
315
+ header { margin-bottom: 2.2rem; }
316
+ header h1 { font-size: 1.9rem; margin-bottom: .6rem; }
317
+ .badges { margin-bottom: 1.2rem; }
318
+
319
+ .panel { padding-top: 2.2rem; }
320
+ .inputs { margin-top: 1.8rem; }
321
+ .inputs label { margin-bottom: 1.1rem; }
322
+ #results { margin-top: 2.8rem; }
323
+ .verdict-row { margin-bottom: 1.4rem; }
324
+ .narrative { padding: 1rem 1.2rem; margin-bottom: 2rem; line-height: 1.7; }
325
+ #bars { padding: 1rem 1.2rem; margin-bottom: 2.2rem; }
326
+ .gauge-block { margin-bottom: 2rem; }
327
+ .temp-block { padding: 1rem 1.2rem; margin-bottom: 1.8rem; }
328
+
329
+ #guide h2 { margin: 2.4rem 0 .8rem; }
330
+ #guide h2:first-child { margin-top: .4rem; }
331
+ #guide p { margin-bottom: 1.2rem; }
332
+ #guide table { margin-bottom: 1.8rem; }
333
+ th, td { padding: .55rem .7rem; }
334
+
335
+ h3 { margin: 1.8rem 0 .3rem; }
336
+ .cols h3 { margin-top: 0; }
337
+
338
+ footer { margin-top: 4rem; padding-top: 2rem; }
339
+ .authors { margin-bottom: 1.6rem; }
340
+
341
+ /* glossary: term column narrow and steady so definitions align */
342
+ .glossary td:first-child { width: 11rem; color: var(--ink); }
343
+ .glossary td:last-child { color: var(--muted); }
344
+ .glossary { max-width: 46rem; }