Adrien Denat commited on
Commit
958c233
2 Parent(s): 663005a 793c54c

Merge pull request #1 from huggingface/julien-openassistant-demo

Browse files
.env.example ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ PUBLIC_HF_TOKEN=
2
+ PUBLIC_ENDPOINT=https://api-inference.huggingface.co/models/OpenAssistant/oasst-sft-1-pythia-12b
3
+ PUBLIC_MODEL_NAME=OpenAssistant/oasst-sft-1-pythia-12b
4
+ PUBLIC_MODEL_TAGLINE=This is the first iteration English supervised-fine-tuning (SFT) model of the <a class="underline" href="https://github.com/LAION-AI/Open-Assistant">Open-Assistant</a> project. It is based on a Pythia 12B that was fine-tuned on ~22k human demonstrations of assistant conversations collected through the <a class="underline" href="https://open-assistant.io/">https://open-assistant.io/</a> human feedback web app before March 7, 2023.
5
+ PUBLIC_DISABLE_INTRO_TILES=true
6
+ PUBLIC_USER_MESSAGE_TOKEN=<|prompter|>
7
+ PUBLIC_ASSISTANT_MESSAGE_TOKEN=<|assistant|>
8
+ PUBLIC_SEP_TOKEN=<|endoftext|>
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: chat-ui
3
  emoji: 🔥
4
  colorFrom: purple
5
  colorTo: purple
 
1
  ---
2
+ title: oasst-sft-1-pythia-12b
3
  emoji: 🔥
4
  colorFrom: purple
5
  colorTo: purple
src/lib/Types.ts ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export type Message =
2
+ | {
3
+ from: 'user';
4
+ content: string;
5
+ }
6
+ | {
7
+ from: 'bot';
8
+ content: string;
9
+ };
10
+
11
+
12
+ export interface Token {
13
+ id: number;
14
+ text: string;
15
+ logprob: number;
16
+ special: boolean;
17
+ }
18
+
19
+
20
+ export interface StreamResponse {
21
+ /**
22
+ * Generated token
23
+ */
24
+ token: Token;
25
+ /**
26
+ * Complete generated text
27
+ * Only available when the generation is finished
28
+ */
29
+ generated_text?: string;
30
+ }
src/lib/chat/ChatBox.svelte CHANGED
@@ -1,5 +1,7 @@
1
  <script lang="ts">
2
- export let message;
 
 
3
  </script>
4
 
5
  {#if message.from === 'bot'}
 
1
  <script lang="ts">
2
+ import type { Message } from '$lib/Types';
3
+
4
+ export let message: Message;
5
  </script>
6
 
7
  {#if message.from === 'bot'}
src/lib/chat/ChatIntroduction.svelte CHANGED
@@ -1,28 +1,38 @@
1
  <script lang="ts">
2
- export let title: string = '';
 
 
3
  </script>
4
 
5
  <div class="grid grid-cols-3 gap-3 my-auto">
6
  <div class="col-span-3 text-center mb-10">
7
- <h1 class="text-3xl font-bold mb-1.5">{title}</h1>
8
- <p class="text-lg text-gray-500">Lorem ipsum dolor sit.</p>
9
- </div>
10
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
11
- Create
12
- </div>
13
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
14
- Discover
15
- </div>
16
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
17
- Overcome
18
- </div>
19
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
20
- Create
21
- </div>
22
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
23
- Discover
24
- </div>
25
- <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
26
- Overcome
27
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  </div>
 
1
  <script lang="ts">
2
+ import { PUBLIC_DISABLE_INTRO_TILES, PUBLIC_MODEL_NAME, PUBLIC_MODEL_TAGLINE } from '$env/static/public';
3
+
4
+ export let title: string = 'Joi 20B Instruct';
5
  </script>
6
 
7
  <div class="grid grid-cols-3 gap-3 my-auto">
8
  <div class="col-span-3 text-center mb-10">
9
+ <h1 class="text-3xl font-bold mb-1.5">{PUBLIC_MODEL_NAME || title}</h1>
10
+ <p class="text-lg text-gray-500">
11
+ {#if PUBLIC_MODEL_TAGLINE}
12
+ {@html PUBLIC_MODEL_TAGLINE}
13
+ {:else}
14
+ Lorem ipsum dolor sit.
15
+ {/if}
16
+ </p>
 
 
 
 
 
 
 
 
 
 
 
 
17
  </div>
18
+ {#if PUBLIC_DISABLE_INTRO_TILES !== "true"}
19
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
20
+ Create
21
+ </div>
22
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
23
+ Discover
24
+ </div>
25
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
26
+ Overcome
27
+ </div>
28
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
29
+ Create
30
+ </div>
31
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
32
+ Discover
33
+ </div>
34
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-xl text-gray-500 dark:text-gray-400 p-4">
35
+ Overcome
36
+ </div>
37
+ {/if}
38
  </div>
src/routes/+page.svelte CHANGED
@@ -1,61 +1,83 @@
1
  <script lang="ts">
 
2
  import { fetchEventSource } from '@microsoft/fetch-event-source';
3
  import ChatBox from '$lib/chat/ChatBox.svelte';
4
  import ChatIntroduction from '$lib/chat/ChatIntroduction.svelte';
5
- const ENDPOINT = 'https://joi-20b.ngrok.io/generate_stream';
 
 
 
 
 
 
 
6
 
7
- type Message =
8
- | {
9
- from: 'user';
10
- content: string;
11
- }
12
- | {
13
- from: 'bot';
14
- content: string;
15
- };
16
 
17
  let messages: Message[] = [];
18
  let message = '';
19
 
 
 
 
 
 
 
20
  function onWrite() {
21
  messages = [...messages, { from: 'user', content: message }];
22
  message = '';
23
- let incoming = '';
24
  const inputs =
25
  messages
26
- .map((m) => (m.from === 'user' ? `User: ${m.content}\n` : `Joi:${m.content}\n`))
27
- .join('\n') + '\nJoi:';
 
 
 
 
28
 
29
- fetchEventSource(ENDPOINT, {
 
30
  method: 'POST',
31
  headers: {
32
  Accept: 'text/event-stream',
33
- 'Content-Type': 'application/json'
 
 
 
 
 
 
34
  },
35
  body: JSON.stringify({
36
  inputs: inputs,
 
37
  parameters: {
38
- temperature: 0.5,
39
- top_p: 0.95,
40
- do_sample: true,
41
- max_new_tokens: 512,
42
- top_k: 4,
43
- repetition_penalty: 1.03,
44
- stop: ['User:']
 
45
  }
46
  }),
47
  async onopen(response) {
48
  if (response.ok && response.headers.get('content-type') === 'text/event-stream') {
49
- messages = [...messages, { from: 'bot', content: incoming }];
50
  } else {
51
  console.error('error opening the SSE endpoint');
52
  }
53
  },
54
  onmessage(msg) {
55
- const data = JSON.parse(msg.data);
56
  // console.log(data);
57
- messages.at(-1)!.content += data.token.text;
58
- messages = messages;
 
 
59
  }
60
  });
61
  }
@@ -69,6 +91,7 @@
69
  >
70
  <div class="flex-none sticky top-0 relative p-3 flex flex-col">
71
  <button
 
72
  class="border px-12 py-2.5 rounded-lg border shadow bg-white dark:bg-gray-700 dark:border-gray-600"
73
  >New Chat</button
74
  >
@@ -99,12 +122,12 @@
99
  </div>
100
  </nav>
101
  <div class="relative h-screen">
102
- <div class="overflow-y-auto h-full">
103
  <div class="max-w-3xl xl:max-w-4xl mx-auto px-5 pt-6 flex flex-col gap-8 h-full">
104
  {#each messages as message}
105
  <ChatBox {message} />
106
  {:else}
107
- <ChatIntroduction title="Joi 20B Instruct" />
108
  {/each}
109
  <div class="h-32 flex-none" />
110
  </div>
 
1
  <script lang="ts">
2
+ import { afterUpdate } from 'svelte';
3
  import { fetchEventSource } from '@microsoft/fetch-event-source';
4
  import ChatBox from '$lib/chat/ChatBox.svelte';
5
  import ChatIntroduction from '$lib/chat/ChatIntroduction.svelte';
6
+ import type { Message, StreamResponse } from '$lib/Types';
7
+ import {
8
+ PUBLIC_ASSISTANT_MESSAGE_TOKEN,
9
+ PUBLIC_ENDPOINT,
10
+ PUBLIC_HF_TOKEN,
11
+ PUBLIC_SEP_TOKEN,
12
+ PUBLIC_USER_MESSAGE_TOKEN
13
+ } from '$env/static/public';
14
 
15
+ const userToken = PUBLIC_USER_MESSAGE_TOKEN || '<|prompter|>';
16
+ const assistantToken = PUBLIC_ASSISTANT_MESSAGE_TOKEN || '<|assistant|>';
17
+ const sepToken = PUBLIC_SEP_TOKEN || '<|endoftext|>';
 
 
 
 
 
 
18
 
19
  let messages: Message[] = [];
20
  let message = '';
21
 
22
+ let messagesContainer: HTMLElement;
23
+
24
+ afterUpdate(() => {
25
+ messagesContainer.scrollTo(0, messagesContainer.scrollHeight);
26
+ });
27
+
28
  function onWrite() {
29
  messages = [...messages, { from: 'user', content: message }];
30
  message = '';
 
31
  const inputs =
32
  messages
33
+ .map(
34
+ (m) =>
35
+ (m.from === 'user' ? userToken + m.content : assistantToken + m.content) +
36
+ (m.content.endsWith(sepToken) ? '' : sepToken)
37
+ )
38
+ .join('') + assistantToken;
39
 
40
+ console.log(inputs);
41
+ fetchEventSource(PUBLIC_ENDPOINT, {
42
  method: 'POST',
43
  headers: {
44
  Accept: 'text/event-stream',
45
+ 'Content-Type': 'application/json',
46
+ 'user-agent': 'chat-ui/0.0.1',
47
+ ...(PUBLIC_HF_TOKEN
48
+ ? {
49
+ authorization: `Bearer ${PUBLIC_HF_TOKEN}`
50
+ }
51
+ : {})
52
  },
53
  body: JSON.stringify({
54
  inputs: inputs,
55
+ stream: true,
56
  parameters: {
57
+ do_sample: false,
58
+ max_new_tokens: 500,
59
+ return_full_text: false,
60
+ stop: [],
61
+ truncate: 1000,
62
+ typical_p: 0.2,
63
+ watermark: false,
64
+ details: true
65
  }
66
  }),
67
  async onopen(response) {
68
  if (response.ok && response.headers.get('content-type') === 'text/event-stream') {
69
+ messages = [...messages, { from: 'bot', content: '' }];
70
  } else {
71
  console.error('error opening the SSE endpoint');
72
  }
73
  },
74
  onmessage(msg) {
75
+ const data = JSON.parse(msg.data) as StreamResponse;
76
  // console.log(data);
77
+ if (!data.token.special) {
78
+ messages.at(-1)!.content += data.token.text;
79
+ messages = messages;
80
+ }
81
  }
82
  });
83
  }
 
91
  >
92
  <div class="flex-none sticky top-0 relative p-3 flex flex-col">
93
  <button
94
+ on:click={() => location.reload()}
95
  class="border px-12 py-2.5 rounded-lg border shadow bg-white dark:bg-gray-700 dark:border-gray-600"
96
  >New Chat</button
97
  >
 
122
  </div>
123
  </nav>
124
  <div class="relative h-screen">
125
+ <div class="overflow-y-auto h-full" bind:this={messagesContainer}>
126
  <div class="max-w-3xl xl:max-w-4xl mx-auto px-5 pt-6 flex flex-col gap-8 h-full">
127
  {#each messages as message}
128
  <ChatBox {message} />
129
  {:else}
130
+ <ChatIntroduction />
131
  {/each}
132
  <div class="h-32 flex-none" />
133
  </div>