JoFrost commited on
Commit
6e8146a
1 Parent(s): 0015338

feat: loading bar for phi

Browse files
package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
  {
2
  "name": "chat-ui",
3
- "version": "0.0.1",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
  "name": "chat-ui",
9
- "version": "0.0.1",
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.2.0",
@@ -29,6 +29,7 @@
29
  "svelte-device-info": "^1.0.0",
30
  "tailwind-scrollbar": "^3.0.0",
31
  "tailwindcss": "^3.3.1",
 
32
  "uuid": "^9.0.1",
33
  "zod": "^3.21.4"
34
  },
@@ -41,6 +42,7 @@
41
  "@types/jsdom": "^21.1.1",
42
  "@types/marked": "^4.0.8",
43
  "@types/parquetjs": "^0.10.3",
 
44
  "@typescript-eslint/eslint-plugin": "^5.45.0",
45
  "@typescript-eslint/parser": "^5.45.0",
46
  "eslint": "^8.28.0",
@@ -1071,6 +1073,12 @@
1071
  "integrity": "sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==",
1072
  "dev": true
1073
  },
 
 
 
 
 
 
1074
  "node_modules/@typescript-eslint/eslint-plugin": {
1075
  "version": "5.62.0",
1076
  "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
@@ -2776,9 +2784,9 @@
2776
  "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
2777
  },
2778
  "node_modules/get-func-name": {
2779
- "version": "2.0.0",
2780
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
2781
- "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
2782
  "dev": true,
2783
  "engines": {
2784
  "node": "*"
@@ -5864,6 +5872,11 @@
5864
  "punycode": "^2.1.0"
5865
  }
5866
  },
 
 
 
 
 
5867
  "node_modules/url-parse": {
5868
  "version": "1.5.10",
5869
  "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
 
1
  {
2
  "name": "chat-ui",
3
+ "version": "0.0.8",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
  "name": "chat-ui",
9
+ "version": "0.0.8",
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.2.0",
 
29
  "svelte-device-info": "^1.0.0",
30
  "tailwind-scrollbar": "^3.0.0",
31
  "tailwindcss": "^3.3.1",
32
+ "urijs": "^1.19.11",
33
  "uuid": "^9.0.1",
34
  "zod": "^3.21.4"
35
  },
 
42
  "@types/jsdom": "^21.1.1",
43
  "@types/marked": "^4.0.8",
44
  "@types/parquetjs": "^0.10.3",
45
+ "@types/urijs": "^1.19.20",
46
  "@typescript-eslint/eslint-plugin": "^5.45.0",
47
  "@typescript-eslint/parser": "^5.45.0",
48
  "eslint": "^8.28.0",
 
1073
  "integrity": "sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==",
1074
  "dev": true
1075
  },
1076
+ "node_modules/@types/urijs": {
1077
+ "version": "1.19.20",
1078
+ "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.20.tgz",
1079
+ "integrity": "sha512-77Mq/2BeHU894J364dUv9tSwxxyCLtcX228Pc8TwZpP5bvOoMns+gZoftp3LYl3FBH8vChpWbuagKGiMki2c1A==",
1080
+ "dev": true
1081
+ },
1082
  "node_modules/@typescript-eslint/eslint-plugin": {
1083
  "version": "5.62.0",
1084
  "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
 
2784
  "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
2785
  },
2786
  "node_modules/get-func-name": {
2787
+ "version": "2.0.2",
2788
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
2789
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
2790
  "dev": true,
2791
  "engines": {
2792
  "node": "*"
 
5872
  "punycode": "^2.1.0"
5873
  }
5874
  },
5875
+ "node_modules/urijs": {
5876
+ "version": "1.19.11",
5877
+ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
5878
+ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
5879
+ },
5880
  "node_modules/url-parse": {
5881
  "version": "1.5.10",
5882
  "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "chat-ui",
3
- "version": "0.0.4",
4
  "private": true,
5
  "packageManager": "npm@9.5.0",
6
  "scripts": {
@@ -22,6 +22,7 @@
22
  "@types/jsdom": "^21.1.1",
23
  "@types/marked": "^4.0.8",
24
  "@types/parquetjs": "^0.10.3",
 
25
  "@typescript-eslint/eslint-plugin": "^5.45.0",
26
  "@typescript-eslint/parser": "^5.45.0",
27
  "eslint": "^8.28.0",
@@ -61,6 +62,7 @@
61
  "svelte-device-info": "^1.0.0",
62
  "tailwind-scrollbar": "^3.0.0",
63
  "tailwindcss": "^3.3.1",
 
64
  "uuid": "^9.0.1",
65
  "zod": "^3.21.4"
66
  }
 
1
  {
2
  "name": "chat-ui",
3
+ "version": "0.0.8",
4
  "private": true,
5
  "packageManager": "npm@9.5.0",
6
  "scripts": {
 
22
  "@types/jsdom": "^21.1.1",
23
  "@types/marked": "^4.0.8",
24
  "@types/parquetjs": "^0.10.3",
25
+ "@types/urijs": "^1.19.20",
26
  "@typescript-eslint/eslint-plugin": "^5.45.0",
27
  "@typescript-eslint/parser": "^5.45.0",
28
  "eslint": "^8.28.0",
 
62
  "svelte-device-info": "^1.0.0",
63
  "tailwind-scrollbar": "^3.0.0",
64
  "tailwindcss": "^3.3.1",
65
+ "urijs": "^1.19.11",
66
  "uuid": "^9.0.1",
67
  "zod": "^3.21.4"
68
  }
src/lib/components/LoadingModal.svelte CHANGED
@@ -25,8 +25,9 @@
25
  is_phi_loading = false;
26
  loadingMap.set(model, Math.floor(Number(percent)));
27
  }
28
- else if (model != undefined && model.startsWith("phi")) {
29
- is_phi_loading = true;
 
30
  }
31
  if (loadingMap.size > 0)
32
  {
 
25
  is_phi_loading = false;
26
  loadingMap.set(model, Math.floor(Number(percent)));
27
  }
28
+ else if (model != undefined && model.endsWith("gguf")) {
29
+ is_phi_loading = false;
30
+ loadingMap.set(model, Math.floor(Number(percent)));
31
  }
32
  if (loadingMap.size > 0)
33
  {
src/routes/conversation/[id]/+page.svelte CHANGED
@@ -26,7 +26,6 @@
26
  let curr_model_id = 0;
27
  curr_model_writable.subscribe((val) => {
28
  curr_model_id = val;
29
- console.log(val);
30
  });
31
 
32
  let pipelineWorker;
@@ -52,12 +51,16 @@
52
  let pending = false;
53
  let loginRequired = false;
54
 
 
 
 
55
  // Create a callback function for messages from the worker thread.
56
  const onMessageReceived = (e) => {
57
- console.log(e)
58
  let lastMessage: any = undefined;
59
  switch (e.data.status) {
60
  case "initiate":
 
 
61
  break;
62
 
63
  case "progress":
@@ -71,13 +74,13 @@
71
  break;
72
 
73
  case "init_model":
74
- phi_writable.set(true);
75
  break;
76
 
77
  case "done":
78
  break;
79
 
80
  case "ready":
 
81
  isloading_writable.set(false);
82
  is_init_writable.set(false);
83
  phi_writable.set(false);
@@ -99,6 +102,7 @@
99
  case "aborted":
100
  case "complete":
101
  if (e.data.id_now == id_now) {
 
102
  lastMessage = messages[messages.length - 1];
103
  lastMessage.webSearchId = e.data.searchID;
104
  lastMessage.updatedAt = new Date();
@@ -152,6 +156,8 @@
152
  isCode: false,
153
  };
154
 
 
 
155
  addMessageToChat(conversationId, msg, curr_model);
156
 
157
  let lastMessage = messages[messages.length - 1];
 
26
  let curr_model_id = 0;
27
  curr_model_writable.subscribe((val) => {
28
  curr_model_id = val;
 
29
  });
30
 
31
  let pipelineWorker;
 
51
  let pending = false;
52
  let loginRequired = false;
53
 
54
+ //The code consider that the datalayer variable does not exist
55
+ //but it is instantiated by Google Tag Manager during runtime
56
+
57
  // Create a callback function for messages from the worker thread.
58
  const onMessageReceived = (e) => {
 
59
  let lastMessage: any = undefined;
60
  switch (e.data.status) {
61
  case "initiate":
62
+ if (e.data.file == "tokenizer.json") // Avoid to send the tag multiple times
63
+ dataLayer.push({'event': 'debut_chargement_chat', 'nom_modele':[e.data.name]});
64
  break;
65
 
66
  case "progress":
 
74
  break;
75
 
76
  case "init_model":
 
77
  break;
78
 
79
  case "done":
80
  break;
81
 
82
  case "ready":
83
+ dataLayer.push({'event': 'fin_chargement_chat', 'nom_modele':[e.data.name]});
84
  isloading_writable.set(false);
85
  is_init_writable.set(false);
86
  phi_writable.set(false);
 
102
  case "aborted":
103
  case "complete":
104
  if (e.data.id_now == id_now) {
105
+ dataLayer.push({'event': 'reponse_message'});
106
  lastMessage = messages[messages.length - 1];
107
  lastMessage.webSearchId = e.data.searchID;
108
  lastMessage.updatedAt = new Date();
 
156
  isCode: false,
157
  };
158
 
159
+ dataLayer.push({'event': 'envoi_message'});
160
+
161
  addMessageToChat(conversationId, msg, curr_model);
162
 
163
  let lastMessage = messages[messages.length - 1];
src/routes/conversation/[id]/worker.js CHANGED
@@ -1,17 +1,71 @@
1
  import { pipeline, env } from "@xenova/transformers";
2
  import init, { Model } from "./phi/m.js";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  async function fetchArrayBuffer(url) {
5
- const cacheName = "phi-mixformer-candle-cache";
6
- const cache = await caches.open(cacheName);
7
- const cachedResponse = await cache.match(url);
8
- if (cachedResponse) {
9
- const data = await cachedResponse.arrayBuffer();
10
- return new Uint8Array(data);
 
 
 
 
11
  }
12
- const res = await fetch(url, { cache: "force-cache" });
13
- cache.put(url, res.clone());
14
- return new Uint8Array(await res.arrayBuffer());
 
 
 
 
 
 
 
15
  }
16
 
17
  class Phi {
@@ -23,8 +77,6 @@ class Phi {
23
  await init();
24
 
25
  self.postMessage({ status: "loading", message: "Loading Model" });
26
- self.postMessage({ status: "progress", file: "model-q4k.gguf", no_progress_bar: true, message: "Starting Phi" });
27
-
28
 
29
  const [weightsArrayU8, tokenizerArrayU8] = await Promise.all([
30
  fetchArrayBuffer(weightsURL),
@@ -63,6 +115,7 @@ export class FlanPipeline {
63
  }
64
 
65
  let controller = null;
 
66
 
67
  // Listen for messages from the main thread
68
  self.addEventListener("message", async (event) => {
@@ -120,6 +173,9 @@ async function generate_phi(data) {
120
  let top_p = 1;
121
  let repeatPenalty = 1.1;
122
  let seed = 299792458;
 
 
 
123
  try {
124
  const model = await Phi.getInstance(
125
  weightsURL,
 
1
  import { pipeline, env } from "@xenova/transformers";
2
  import init, { Model } from "./phi/m.js";
3
+ import URI from "urijs"
4
+
5
+ // Shamelessly stolen from Transformers.js
6
+
7
+ export async function tryCache(cache, ...names) {
8
+ for (let name of names) {
9
+ try {
10
+ console.log(name)
11
+ let result = await cache.match(name);
12
+ if (result) return result;
13
+ } catch (e) {
14
+ continue;
15
+ }
16
+ }
17
+ return undefined;
18
+ }
19
+
20
+ async function read_stream(url, response) {
21
+ const reader = response.body.getReader();
22
+ const contentLength = +response.headers.get('Content-Length');
23
+ let receivedLength = 0;
24
+ let chunks = [];
25
+ let uri = new URI(url)
26
+
27
+ while(true) {
28
+ const {done, value} = await reader.read();
29
+ if (done) {
30
+ break;
31
+ }
32
+ chunks.push(value);
33
+ receivedLength += value.length;
34
+ let percent = (receivedLength / contentLength) * 100
35
+ self.postMessage({ status: "progress", file: uri.filename(), progress: percent });
36
+ }
37
+
38
+ let chunksAll = new Uint8Array(receivedLength);
39
+ let position = 0;
40
+ for(let chunk of chunks) {
41
+ chunksAll.set(chunk, position);
42
+ position += chunk.length;
43
+ }
44
+ return chunksAll
45
+ }
46
 
47
  async function fetchArrayBuffer(url) {
48
+ let cache = await caches.open('transformers-cache');
49
+
50
+ const response = await tryCache(cache, url);
51
+ if (response != undefined) {
52
+ console.log(url)
53
+ let res = await read_stream(url, response)
54
+ cache.put(url, new Response(res, {
55
+ headers: response.headers
56
+ }));
57
+ return new Uint8Array(res);
58
  }
59
+ else {
60
+ const response = await fetch(url);
61
+ let res = await read_stream(url, response)
62
+ cache.put(url, new Response(res, {
63
+ headers: response.headers,
64
+ }));
65
+ return new Uint8Array(res);
66
+ }
67
+
68
+
69
  }
70
 
71
  class Phi {
 
77
  await init();
78
 
79
  self.postMessage({ status: "loading", message: "Loading Model" });
 
 
80
 
81
  const [weightsArrayU8, tokenizerArrayU8] = await Promise.all([
82
  fetchArrayBuffer(weightsURL),
 
115
  }
116
 
117
  let controller = null;
118
+ let phi_model = null;
119
 
120
  // Listen for messages from the main thread
121
  self.addEventListener("message", async (event) => {
 
173
  let top_p = 1;
174
  let repeatPenalty = 1.1;
175
  let seed = 299792458;
176
+
177
+ self.postMessage({ status: "initiate", file: "tokenizer.json", name: "phi-1_5" }); // Fake init
178
+
179
  try {
180
  const model = await Phi.getInstance(
181
  weightsURL,