new
Browse files- code.js +23 -13
- cat.png → imgs/cat.png +0 -0
- imgs/loading.svg +1 -0
- index.html +40 -35
code.js
CHANGED
@@ -28,7 +28,6 @@ class WorkerPool {
|
|
28 |
this._size = size;
|
29 |
}
|
30 |
init() {
|
31 |
-
console.log("init", this.size);
|
32 |
for (let i = 0; i < this.size; i++) {
|
33 |
this.workers.push({
|
34 |
worker: new Worker("./llama2c.worker.js", { type: "module" }),
|
@@ -92,7 +91,12 @@ async function generateSequence({
|
|
92 |
controller,
|
93 |
}) {
|
94 |
return new Promise((resolve, reject) => {
|
95 |
-
const seed = BigInt(
|
|
|
|
|
|
|
|
|
|
|
96 |
worker.postMessage({
|
97 |
weightsURL,
|
98 |
modelID,
|
@@ -106,13 +110,18 @@ async function generateSequence({
|
|
106 |
});
|
107 |
|
108 |
function handleAbort() {
|
109 |
-
console.log("abort");
|
110 |
worker.postMessage({ command: "abort" });
|
111 |
}
|
112 |
function updateStatus(data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
if (data.status === "generating") {
|
114 |
const { message, prompt, sentence, tokensSec, totalTime } = data;
|
115 |
-
contentEl.innerHTML = `<span
|
116 |
${sentence.replace(/\<s\>|\<\/s\>/g, "")}`;
|
117 |
}
|
118 |
}
|
@@ -140,11 +149,15 @@ async function initWorkers() {
|
|
140 |
workerPool.workers.map(async (_, i) => {
|
141 |
const contentEl = d3.select(document.createElement("div"));
|
142 |
|
143 |
-
contentEl.on("pointerover
|
144 |
-
|
|
|
|
|
|
|
145 |
});
|
|
|
146 |
contentEl.on("pointerout pointercancel pointerleave", (e) => {
|
147 |
-
|
148 |
});
|
149 |
|
150 |
const bgColor = colorPalette(i / workerPool.size);
|
@@ -216,17 +229,14 @@ async function run(containers, controller) {
|
|
216 |
}
|
217 |
|
218 |
initWorkers().then((containers) => {
|
219 |
-
const runBtn =
|
220 |
let runController = new AbortController();
|
221 |
let isRunning = false;
|
222 |
d3.select("#form").on("submit", async (e) => {
|
223 |
e.preventDefault();
|
224 |
-
|
225 |
if (isRunning) {
|
226 |
-
console.log("stop");
|
227 |
stopRunning();
|
228 |
} else {
|
229 |
-
console.log("start");
|
230 |
startRunning();
|
231 |
await run(containers, runController);
|
232 |
stopRunning();
|
@@ -235,10 +245,10 @@ initWorkers().then((containers) => {
|
|
235 |
|
236 |
function startRunning() {
|
237 |
isRunning = true;
|
238 |
-
runBtn.
|
239 |
}
|
240 |
function stopRunning() {
|
241 |
-
runBtn.
|
242 |
runController.abort();
|
243 |
runController = new AbortController();
|
244 |
isRunning = false;
|
|
|
28 |
this._size = size;
|
29 |
}
|
30 |
init() {
|
|
|
31 |
for (let i = 0; i < this.size; i++) {
|
32 |
this.workers.push({
|
33 |
worker: new Worker("./llama2c.worker.js", { type: "module" }),
|
|
|
91 |
controller,
|
92 |
}) {
|
93 |
return new Promise((resolve, reject) => {
|
94 |
+
const seed = BigInt(
|
95 |
+
`0x${
|
96 |
+
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16) +
|
97 |
+
Date.now().toString(16)
|
98 |
+
}`
|
99 |
+
);
|
100 |
worker.postMessage({
|
101 |
weightsURL,
|
102 |
modelID,
|
|
|
110 |
});
|
111 |
|
112 |
function handleAbort() {
|
|
|
113 |
worker.postMessage({ command: "abort" });
|
114 |
}
|
115 |
function updateStatus(data) {
|
116 |
+
if (data.status === "loading") {
|
117 |
+
contentEl.innerHTML = `<img src="imgs/loading.svg" />`;
|
118 |
+
}
|
119 |
+
if (data.status === "aborted") {
|
120 |
+
contentEl.innerHTML = ``;
|
121 |
+
}
|
122 |
if (data.status === "generating") {
|
123 |
const { message, prompt, sentence, tokensSec, totalTime } = data;
|
124 |
+
contentEl.innerHTML = `<span>${prompt}</span>
|
125 |
${sentence.replace(/\<s\>|\<\/s\>/g, "")}`;
|
126 |
}
|
127 |
}
|
|
|
149 |
workerPool.workers.map(async (_, i) => {
|
150 |
const contentEl = d3.select(document.createElement("div"));
|
151 |
|
152 |
+
contentEl.on("pointerover", (e) => {
|
153 |
+
e.currentTarget.classList.add("c-hover");
|
154 |
+
});
|
155 |
+
contentEl.on("pointerdown", (e) => {
|
156 |
+
e.currentTarget.classList.toggle("c-hover");
|
157 |
});
|
158 |
+
|
159 |
contentEl.on("pointerout pointercancel pointerleave", (e) => {
|
160 |
+
e.currentTarget.classList.remove("c-hover");
|
161 |
});
|
162 |
|
163 |
const bgColor = colorPalette(i / workerPool.size);
|
|
|
229 |
}
|
230 |
|
231 |
initWorkers().then((containers) => {
|
232 |
+
const runBtn = document.querySelector("#run");
|
233 |
let runController = new AbortController();
|
234 |
let isRunning = false;
|
235 |
d3.select("#form").on("submit", async (e) => {
|
236 |
e.preventDefault();
|
|
|
237 |
if (isRunning) {
|
|
|
238 |
stopRunning();
|
239 |
} else {
|
|
|
240 |
startRunning();
|
241 |
await run(containers, runController);
|
242 |
stopRunning();
|
|
|
245 |
|
246 |
function startRunning() {
|
247 |
isRunning = true;
|
248 |
+
runBtn.innerText = "Stop";
|
249 |
}
|
250 |
function stopRunning() {
|
251 |
+
runBtn.innerText = "Run";
|
252 |
runController.abort();
|
253 |
runController = new AbortController();
|
254 |
isRunning = false;
|
cat.png → imgs/cat.png
RENAMED
File without changes
|
imgs/loading.svg
ADDED
|
index.html
CHANGED
@@ -12,50 +12,58 @@
|
|
12 |
<meta charset="UTF-8" />
|
13 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
14 |
<style>
|
15 |
-
@import url("https://fonts.googleapis.com/css2?family=
|
16 |
html,
|
17 |
body {
|
18 |
font-family: "Source Sans 3", sans-serif;
|
19 |
}
|
20 |
-
|
21 |
-
|
22 |
-
select,
|
23 |
-
pre {
|
24 |
-
font-family: "Source Code Pro", monospace;
|
25 |
}
|
26 |
</style>
|
27 |
<script src="https://cdn.tailwindcss.com"></script>
|
28 |
<style type="text/tailwindcss">
|
29 |
.c-block {
|
30 |
grid-column: 1;
|
31 |
-
@apply bg-slate-100 text-gray-500 px-
|
32 |
-
|
|
|
|
|
|
|
33 |
}
|
34 |
.n-block {
|
35 |
@apply text-xs w-[50px] text-center font-light px-1 py-1 border border-white rounded-md;
|
36 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
</style>
|
38 |
<script type="module" src="./code.js"></script>
|
39 |
</head>
|
40 |
-
<body class="container mx-auto max-w-
|
41 |
-
<img src="./cat.png" class="fixed top-0 left-0 w-20 -z-10" />
|
42 |
-
<
|
43 |
-
|
44 |
-
<
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
|
|
59 |
<form
|
60 |
id="form"
|
61 |
class="flex text-normal px-1 py-2 border-2 border-white rounded-md items-center"
|
@@ -92,26 +100,24 @@
|
|
92 |
<input
|
93 |
type="range"
|
94 |
id="max-seq"
|
95 |
-
name="temperature"
|
96 |
min="1"
|
97 |
max="256"
|
98 |
step="1"
|
99 |
-
value="
|
100 |
oninput="this.nextElementSibling.value = Number(this.value)"
|
101 |
/>
|
102 |
-
<output class="n-block">
|
103 |
<label class="text-sm font-medium" for="temperature">Temperature</label>
|
104 |
<input
|
105 |
type="range"
|
106 |
id="temperature"
|
107 |
-
name="temperature"
|
108 |
min="0"
|
109 |
max="2"
|
110 |
step="0.01"
|
111 |
-
value="0.
|
112 |
oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)"
|
113 |
/>
|
114 |
-
<output class="n-block">
|
115 |
|
116 |
<label class="text-sm font-medium" for="repeat_penalty"
|
117 |
>Repeat Penalty</label
|
@@ -119,7 +125,6 @@
|
|
119 |
<input
|
120 |
type="range"
|
121 |
id="repeat-penalty"
|
122 |
-
name="repeat-penalty"
|
123 |
min="-2"
|
124 |
max="2"
|
125 |
step="0.01"
|
@@ -129,6 +134,6 @@
|
|
129 |
<output class="n-block">1.10</output>
|
130 |
</div>
|
131 |
</details>
|
132 |
-
<div class="text-base grid gap-
|
133 |
</body>
|
134 |
</html>
|
|
|
12 |
<meta charset="UTF-8" />
|
13 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
14 |
<style>
|
15 |
+
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@200;400;500;700&family=Source+Sans+3:wght@200;400;500;600;700;800;900&display=swap");
|
16 |
html,
|
17 |
body {
|
18 |
font-family: "Source Sans 3", sans-serif;
|
19 |
}
|
20 |
+
.mono {
|
21 |
+
font-family: "IBM Plex Mono", monospace;
|
|
|
|
|
|
|
22 |
}
|
23 |
</style>
|
24 |
<script src="https://cdn.tailwindcss.com"></script>
|
25 |
<style type="text/tailwindcss">
|
26 |
.c-block {
|
27 |
grid-column: 1;
|
28 |
+
@apply bg-slate-100 text-gray-500 px-5 py-6 rounded-2xl min-h-[30em] sm:min-h-[25em] leading-relaxed cursor-pointer overflow-hidden row-span-6;
|
29 |
+
font-family: "IBM Plex Mono", monospace;
|
30 |
+
}
|
31 |
+
.c-block span {
|
32 |
+
font-weight: 600;
|
33 |
}
|
34 |
.n-block {
|
35 |
@apply text-xs w-[50px] text-center font-light px-1 py-1 border border-white rounded-md;
|
36 |
}
|
37 |
+
.c-hover {
|
38 |
+
z-index: 100;
|
39 |
+
filter: drop-shadow(0 35px 35px rgba(0, 0, 0, 0.9));
|
40 |
+
transform: scale(1.05);
|
41 |
+
transition: transform 0.3s ease-in-out;
|
42 |
+
}
|
43 |
</style>
|
44 |
<script type="module" src="./code.js"></script>
|
45 |
</head>
|
46 |
+
<body class="container mx-auto max-w-2xl p-4 bg-[#020058]">
|
47 |
+
<img src="./imgs/cat.png" class="fixed top-0 left-0 w-20 -z-10" />
|
48 |
+
<header class="py-2 mb-6">
|
49 |
+
<h1 class="text-5xl font-bold text-white text-center">Tiny Stories</h1>
|
50 |
+
<h1 class="text-3xl text-white text-center mono">
|
51 |
+
<a
|
52 |
+
href="https://github.com/huggingface/candle"
|
53 |
+
target="_blank"
|
54 |
+
class="underline hover:no-underline"
|
55 |
+
>Candle
|
56 |
+
</a>
|
57 |
+
<a
|
58 |
+
href="https://github.com/karpathy/llama2.c"
|
59 |
+
target="_blank"
|
60 |
+
class="underline hover:no-underline"
|
61 |
+
>
|
62 |
+
Llama2.c
|
63 |
+
</a>
|
64 |
+
</h1>
|
65 |
+
<h2 class="text-2xl text-white text-center mono">Rust/WASM</h2>
|
66 |
+
</header>
|
67 |
<form
|
68 |
id="form"
|
69 |
class="flex text-normal px-1 py-2 border-2 border-white rounded-md items-center"
|
|
|
100 |
<input
|
101 |
type="range"
|
102 |
id="max-seq"
|
|
|
103 |
min="1"
|
104 |
max="256"
|
105 |
step="1"
|
106 |
+
value="150"
|
107 |
oninput="this.nextElementSibling.value = Number(this.value)"
|
108 |
/>
|
109 |
+
<output class="n-block"> 150</output>
|
110 |
<label class="text-sm font-medium" for="temperature">Temperature</label>
|
111 |
<input
|
112 |
type="range"
|
113 |
id="temperature"
|
|
|
114 |
min="0"
|
115 |
max="2"
|
116 |
step="0.01"
|
117 |
+
value="0.2"
|
118 |
oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)"
|
119 |
/>
|
120 |
+
<output class="n-block">0.2</output>
|
121 |
|
122 |
<label class="text-sm font-medium" for="repeat_penalty"
|
123 |
>Repeat Penalty</label
|
|
|
125 |
<input
|
126 |
type="range"
|
127 |
id="repeat-penalty"
|
|
|
128 |
min="-2"
|
129 |
max="2"
|
130 |
step="0.01"
|
|
|
134 |
<output class="n-block">1.10</output>
|
135 |
</div>
|
136 |
</details>
|
137 |
+
<div class="text-base grid gap-3 py-5" id="container"></div>
|
138 |
</body>
|
139 |
</html>
|