Humuhumu33 commited on
Commit
7efaf4b
·
verified ·
1 Parent(s): dabcb0d

fast first turn: warmup boosts clock + primes system-prompt KV (12s TTFT to ~0.5s) + static grounded greeting

Browse files
Files changed (1) hide show
  1. index.html +20 -13
index.html CHANGED
@@ -108,18 +108,25 @@ async function generate(text, skipUser) {
108
  } catch (e) { a.classList.remove("think"); a.textContent = "⚠ " + e.message; }
109
  busy = false; input.disabled = send.disabled = false; input.focus();
110
  }
111
- async function proactiveGreeting() {
112
- busy = true; input.disabled = send.disabled = true;
113
- const a = bubble("a think", "…"); let first = true;
114
- const stat = document.createElement("div"); stat.className = "stat";
115
- const FALLBACK = "Hey I'm Q, running entirely in your browser, no server. My weights streamed from Hugging Face and are verified by re-derivation. What can I help you with?";
 
116
  try {
117
- const P = "This is the very first thing you say to the person who just opened you. You are Q — a private AI running entirely in their browser with no server, your weights streamed from Hugging Face and verified by re-derivation. Greet them warmly in one or two sentences and invite them to ask you anything.";
118
- let ids = engine.tokenize(engine.frameTurn(P, false));
119
- if (m.bos && engine.bosId != null) ids = [engine.bosId, ...ids];
120
- await engine.generate(ids, { maxNew: 64, onToken: ({ text: t, stats }) => { if (first && t) { a.classList.remove("think"); a.textContent = ""; first = false; } a.textContent = t; log.scrollTop = log.scrollHeight; if (stats && stats.tokps) stat.textContent = `${stats.tokps.toFixed(0)} tok/s`; } });
121
- if (first || a.textContent.trim().length < 4) { a.classList.remove("think"); a.textContent = FALLBACK; } else a.after(stat);
122
- } catch (e) { a.classList.remove("think"); a.textContent = FALLBACK; }
 
 
 
 
 
 
123
  busy = false; input.disabled = send.disabled = false; input.focus();
124
  }
125
  function onSend() {
@@ -339,7 +346,7 @@ try {
339
  else if (params.get("bench") === "perf") { await runPerfBench(); }
340
  else if (params.get("bench") === "trace") { await runTraceBench(); }
341
  else if (params.get("bench") === "discrete") { globalThis.__spec = false; await runDiscreteBench(); }
342
- else if (pending) { const w = [...log.querySelectorAll(".a")].reverse().find((x) => x.dataset.pending); if (w) w.remove(); const p = pending; pending = null; generate(p, true); }
343
- else await proactiveGreeting();
344
  } catch (e) { st.textContent = "⚠ " + e.message; bubble("a", "Could not start: " + e.message); }
345
  </script></body></html>
 
108
  } catch (e) { a.classList.remove("think"); a.textContent = "⚠ " + e.message; }
109
  busy = false; input.disabled = send.disabled = false; input.focus();
110
  }
111
+ // Warm the GPU to boost clock, then PRIME the system-prompt KV so the first real turn reuses it instead of
112
+ // re-prefilling ~140 tokens cold (that was the ~12s TTFT). sync() keeps the cache only if it's a clean prefix
113
+ // of the first turn — frameSystem() ends on the atomic <|eot_id|> token, so tokenize(system) is exactly that.
114
+ async function warmUp() {
115
+ const gpu = engine && engine._gpu;
116
+ if (!gpu || !gpu.sync || !gpu.generate || !gpu.reset) return;
117
  try {
118
+ gpu.reset(); await gpu.generate(engine.tokenize("Hello there."), 24, m.rep ?? 1.3); gpu.reset(); // boost clock (throwaway)
119
+ let primeIds = engine.tokenize(frameSystem());
120
+ if (m.bos && engine.bosId != null) primeIds = [engine.bosId, ...primeIds];
121
+ await gpu.sync(primeIds, true); // prefill the system prompt into KV; leaves cache == primeIds
122
+ } catch (e) { console.warn("warmUp", e); }
123
+ }
124
+ // STATIC grounded greeting — no model call (so it can't confabulate a generic "friendly AI assistant" line, and
125
+ // it doesn't disturb the primed system-prompt cache). Instant.
126
+ async function proactiveGreeting() {
127
+ const f = selfFacts({ model: m, engine });
128
+ const host = (f.weightsFrom && !/^local$/i.test(f.weightsFrom)) ? f.weightsFrom : "Hugging Face";
129
+ bubble("a", `Hey — I'm Q, running entirely in your browser${f.gpu ? " on your GPU" : ""}, no server. My weights streamed from ${host} and are verified by re-derivation, so nothing you type ever leaves your device. What can I help you with?`);
130
  busy = false; input.disabled = send.disabled = false; input.focus();
131
  }
132
  function onSend() {
 
346
  else if (params.get("bench") === "perf") { await runPerfBench(); }
347
  else if (params.get("bench") === "trace") { await runTraceBench(); }
348
  else if (params.get("bench") === "discrete") { globalThis.__spec = false; await runDiscreteBench(); }
349
+ else if (pending) { st.textContent = "warming up…"; await warmUp(); st.textContent = `${m.name} · ${m.size} · in your browser · ready`; const w = [...log.querySelectorAll(".a")].reverse().find((x) => x.dataset.pending); if (w) w.remove(); const p = pending; pending = null; generate(p, true); }
350
+ else { st.textContent = "warming up…"; await warmUp(); st.textContent = `${m.name} · ${m.size} · in your browser · ready`; await proactiveGreeting(); }
351
  } catch (e) { st.textContent = "⚠ " + e.message; bubble("a", "Could not start: " + e.message); }
352
  </script></body></html>