Spaces:
Running
Running
fast first turn: warmup boosts clock + primes system-prompt KV (12s TTFT to ~0.5s) + static grounded greeting
Browse files- 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 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
const
|
|
|
|
| 116 |
try {
|
| 117 |
-
|
| 118 |
-
let
|
| 119 |
-
if (m.bos && engine.bosId != null)
|
| 120 |
-
await
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>
|