Huggingface IT commited on
Commit
181d9ef
·
1 Parent(s): 97802e3

add energy time estimate

Browse files
Dockerfile.dev ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-slim
2
+
3
+ USER root
4
+ RUN apt-get update && apt-get install -y \
5
+ python3 make g++ curl gnupg && apt-get clean
6
+
7
+ RUN mkdir -p /home/user/.cache && chown -R 1000:1000 /home/user/.cache
8
+
9
+ #USER user
10
+ WORKDIR /app
11
+
12
+ EXPOSE 5173
13
+
14
+ # start bash
15
+ CMD ["bash"]
compose.dev.yml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ services:
2
+ app:
3
+ build:
4
+ context: .
5
+ dockerfile: Dockerfile.dev
6
+ ports:
7
+ - "5173:5173" # adapt if using another dev server port
8
+ volumes:
9
+ - .:/app
10
+ - /app/node_modules # pour éviter les conflits entre host et conteneur
11
+ working_dir: /app
12
+ user: "1000:1000"
13
+ tty: true
14
+ mongo:
15
+ image: mongo:7
16
+ ports:
17
+ - "27017:27017"
18
+ volumes:
19
+ - mongo-data:/data/db
20
+
21
+ volumes:
22
+ mongo-data:
src/lib/components/chat/ChatMessage.svelte CHANGED
@@ -150,6 +150,7 @@
150
  class="mt-5 h-3 w-3 flex-none select-none rounded-full shadow-lg"
151
  />
152
  {/if}
 
153
  <div
154
  class="relative min-h-[calc(2rem+theme(spacing[3.5])*2)] min-w-[60px] break-words rounded-2xl border border-gray-100 bg-gradient-to-br from-gray-50 px-5 py-3.5 text-gray-600 prose-pre:my-2 dark:border-gray-800 dark:from-gray-800/40 dark:text-gray-300"
155
  >
@@ -197,6 +198,25 @@
197
  class="prose max-w-none dark:prose-invert max-sm:prose-sm prose-headings:font-semibold prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900"
198
  >
199
  <MarkdownRenderer content={message.content} sources={webSearchSources} />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  </div>
201
  </div>
202
 
 
150
  class="mt-5 h-3 w-3 flex-none select-none rounded-full shadow-lg"
151
  />
152
  {/if}
153
+
154
  <div
155
  class="relative min-h-[calc(2rem+theme(spacing[3.5])*2)] min-w-[60px] break-words rounded-2xl border border-gray-100 bg-gradient-to-br from-gray-50 px-5 py-3.5 text-gray-600 prose-pre:my-2 dark:border-gray-800 dark:from-gray-800/40 dark:text-gray-300"
156
  >
 
198
  class="prose max-w-none dark:prose-invert max-sm:prose-sm prose-headings:font-semibold prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900"
199
  >
200
  <MarkdownRenderer content={message.content} sources={webSearchSources} />
201
+ {#if message.metadata?.energy_wh || message.metadata?.duration_seconds}
202
+ <div class="mt-2 flex gap-2">
203
+ {#if message.metadata?.energy_wh}
204
+ <div
205
+ class="text-xs text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded w-fit"
206
+ >
207
+ ◊ {message.metadata.energy_wh} Wh
208
+ </div>
209
+ {/if}
210
+ {#if message.metadata?.duration_seconds}
211
+ <div
212
+ class="text-xs text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded w-fit"
213
+ >
214
+ {message.metadata.duration_seconds} sec
215
+ </div>
216
+ {/if}
217
+ </div>
218
+ {/if}
219
+
220
  </div>
221
  </div>
222
 
src/lib/server/textGeneration/generate.ts CHANGED
@@ -127,6 +127,25 @@ Do not use prefixes such as Response: or Answer: when answering to the user.`,
127
  interrupted,
128
  webSources: output.webSources,
129
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  continue;
131
  }
132
 
 
127
  interrupted,
128
  webSources: output.webSources,
129
  };
130
+
131
+ // simulation of metadata
132
+ const durationInSeconds = (new Date().getTime() - startTime.getTime()) / 1000;
133
+ const energyUsedwh = +(50 * (durationInSeconds / 3600)).toFixed(6); // 50W is a guess
134
+
135
+ yield {
136
+ type: MessageUpdateType.Metadata,
137
+ key: "energy_wh",
138
+ value: energyUsedwh,
139
+ };
140
+ yield {
141
+ type: MessageUpdateType.Metadata,
142
+ key: "duration_seconds",
143
+ value: durationInSeconds,
144
+ };
145
+
146
+ console.log('model', model);
147
+ console.log('output', output);
148
+
149
  continue;
150
  }
151
 
src/lib/types/Message.ts CHANGED
@@ -25,6 +25,9 @@ export type Message = Partial<Timestamps> & {
25
 
26
  // goes one level deep
27
  children?: Message["id"][];
 
 
 
28
  };
29
 
30
  export type MessageFile = {
 
25
 
26
  // goes one level deep
27
  children?: Message["id"][];
28
+
29
+ // metadata
30
+ metadata?: Record<string, string | number>;
31
  };
32
 
33
  export type MessageFile = {
src/lib/types/MessageUpdate.ts CHANGED
@@ -9,7 +9,8 @@ export type MessageUpdate =
9
  | MessageStreamUpdate
10
  | MessageFileUpdate
11
  | MessageFinalAnswerUpdate
12
- | MessageReasoningUpdate;
 
13
 
14
  export enum MessageUpdateType {
15
  Status = "status",
@@ -20,6 +21,7 @@ export enum MessageUpdateType {
20
  File = "file",
21
  FinalAnswer = "finalAnswer",
22
  Reasoning = "reasoning",
 
23
  }
24
 
25
  // Status
@@ -147,3 +149,9 @@ export interface MessageFinalAnswerUpdate {
147
  interrupted: boolean;
148
  webSources?: { uri: string; title: string }[];
149
  }
 
 
 
 
 
 
 
9
  | MessageStreamUpdate
10
  | MessageFileUpdate
11
  | MessageFinalAnswerUpdate
12
+ | MessageReasoningUpdate
13
+ | MessageMetadataUpdate;
14
 
15
  export enum MessageUpdateType {
16
  Status = "status",
 
21
  File = "file",
22
  FinalAnswer = "finalAnswer",
23
  Reasoning = "reasoning",
24
+ Metadata = "metadata",
25
  }
26
 
27
  // Status
 
149
  interrupted: boolean;
150
  webSources?: { uri: string; title: string }[];
151
  }
152
+
153
+ export interface MessageMetadataUpdate {
154
+ type: MessageUpdateType.Metadata;
155
+ key: string;
156
+ value: string | number;
157
+ }
src/routes/conversation/[id]/+server.ts CHANGED
@@ -402,6 +402,12 @@ export async function POST({ request, locals, params, getClientAddress }) {
402
  ];
403
  }
404
 
 
 
 
 
 
 
405
  // Append to the persistent message updates if it's not a stream update
406
  if (
407
  event.type !== MessageUpdateType.Stream &&
@@ -417,6 +423,8 @@ export async function POST({ request, locals, params, getClientAddress }) {
417
  messageToWriteTo?.updates?.push(event);
418
  }
419
 
 
 
420
  // Avoid remote keylogging attack executed by watching packet lengths
421
  // by padding the text with null chars to a fixed length
422
  // https://cdn.arstechnica.net/wp-content/uploads/2024/03/LLM-Side-Channel.pdf
 
402
  ];
403
  }
404
 
405
+ // Add metadata
406
+ else if (event.type === MessageUpdateType.Metadata) {
407
+ messageToWriteTo.metadata ??= {};
408
+ messageToWriteTo.metadata[event.key] = event.value;
409
+ }
410
+
411
  // Append to the persistent message updates if it's not a stream update
412
  if (
413
  event.type !== MessageUpdateType.Stream &&
 
423
  messageToWriteTo?.updates?.push(event);
424
  }
425
 
426
+
427
+
428
  // Avoid remote keylogging attack executed by watching packet lengths
429
  // by padding the text with null chars to a fixed length
430
  // https://cdn.arstechnica.net/wp-content/uploads/2024/03/LLM-Side-Channel.pdf