lavanjv commited on
Commit
4c1db66
1 Parent(s): b3cc940

Upload 9 files

Browse files
static/autosize.min.js ADDED
@@ -0,0 +1 @@
 
 
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e||self).autosize=t()}(this,function(){var e,t,n="function"==typeof Map?new Map:(e=[],t=[],{has:function(t){return e.indexOf(t)>-1},get:function(n){return t[e.indexOf(n)]},set:function(n,o){-1===e.indexOf(n)&&(e.push(n),t.push(o))},delete:function(n){var o=e.indexOf(n);o>-1&&(e.splice(o,1),t.splice(o,1))}}),o=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){o=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}function r(e){var t=n.get(e);t&&t.destroy()}function i(e){var t=n.get(e);t&&t.update()}var l=null;return"undefined"==typeof window||"function"!=typeof window.getComputedStyle?((l=function(e){return e}).destroy=function(e){return e},l.update=function(e){return e}):((l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return function(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!n.has(e)){var t,r=null,i=null,l=null,a=function(){e.clientWidth!==i&&f()},d=function(t){window.removeEventListener("resize",a,!1),e.removeEventListener("input",f,!1),e.removeEventListener("keyup",f,!1),e.removeEventListener("autosize:destroy",d,!1),e.removeEventListener("autosize:update",f,!1),Object.keys(t).forEach(function(n){e.style[n]=t[n]}),n.delete(e)}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",d,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",f,!1),window.addEventListener("resize",a,!1),e.addEventListener("input",f,!1),e.addEventListener("autosize:update",f,!1),e.style.overflowX="hidden",e.style.wordWrap="break-word",n.set(e,{destroy:d,update:f}),"vertical"===(t=window.getComputedStyle(e,null)).resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),r="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(r)&&(r=0),f()}function s(t){var n=e.style.width;e.style.width="0px",e.style.width=n,e.style.overflowY=t}function u(){if(0!==e.scrollHeight){var t=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&(e.parentNode.style.scrollBehavior="auto",t.push([e.parentNode,e.parentNode.scrollTop])),e=e.parentNode;return function(){return t.forEach(function(e){var t=e[0];t.scrollTop=e[1],t.style.scrollBehavior=null})}}(e);e.style.height="",e.style.height=e.scrollHeight+r+"px",i=e.clientWidth,t()}}function f(){u();var t=Math.round(parseFloat(e.style.height)),n=window.getComputedStyle(e,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):e.offsetHeight;if(r<t?"hidden"===n.overflowY&&(s("scroll"),u(),r="content-box"===n.boxSizing?Math.round(parseFloat(window.getComputedStyle(e,null).height)):e.offsetHeight):"hidden"!==n.overflowY&&(s("hidden"),u(),r="content-box"===n.boxSizing?Math.round(parseFloat(window.getComputedStyle(e,null).height)):e.offsetHeight),l!==r){l=r;var i=o("autosize:resized");try{e.dispatchEvent(i)}catch(e){}}}}(e)}),e}).destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],r),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],i),e}),l});
static/bootstrap.min.css ADDED
The diff for this file is too large to render. See raw diff
 
static/bootstrap.min.css.map ADDED
The diff for this file is too large to render. See raw diff
 
static/bootstrap.rtl.min.css ADDED
The diff for this file is too large to render. See raw diff
 
static/bootstrap.rtl.min.css.map ADDED
The diff for this file is too large to render. See raw diff
 
static/chat.js ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const models = {
2
+ "meta-llama/Llama-2-70b-chat-hf": {
3
+ modelCard: "https://huggingface.co/meta-llama/Llama-2-70b-chat-hf",
4
+ license: "https://bit.ly/llama2-license",
5
+ maxSessionLength: 8192,
6
+ sepToken: "###",
7
+ stopToken: "###",
8
+ extraStopSequences: ["</s>"],
9
+ },
10
+ "meta-llama/Llama-2-70b-hf": {
11
+ modelCard: "https://huggingface.co/meta-llama/Llama-2-70b-hf",
12
+ license: "https://bit.ly/llama2-license",
13
+ maxSessionLength: 8192,
14
+ sepToken: "###",
15
+ stopToken: "###",
16
+ extraStopSequences: ["</s>"],
17
+ },
18
+ "timdettmers/guanaco-65b": {
19
+ modelCard: "https://huggingface.co/timdettmers/guanaco-65b",
20
+ license: "https://huggingface.co/timdettmers/guanaco-65b",
21
+ maxSessionLength: 2048,
22
+ sepToken: "###",
23
+ stopToken: "###",
24
+ extraStopSequences: ["</s>"],
25
+ },
26
+ "enoch/llama-65b-hf": {
27
+ modelCard: "https://github.com/facebookresearch/llama/blob/llama_v1/MODEL_CARD.md",
28
+ license: "https://bit.ly/llama-license",
29
+ maxSessionLength: 2048,
30
+ sepToken: "###",
31
+ stopToken: "###",
32
+ extraStopSequences: ["</s>"],
33
+ },
34
+ "bigscience/bloom": {
35
+ modelCard: "https://huggingface.co/bigscience/bloom",
36
+ license: "https://bit.ly/bloom-license",
37
+ maxSessionLength: 2048,
38
+ sepToken: "\n\n",
39
+ stopToken: "\n\n",
40
+ extraStopSequences: null,
41
+ },
42
+ "bigscience/bloomz": {
43
+ modelCard: "https://huggingface.co/bigscience/bloomz",
44
+ license: "https://bit.ly/bloom-license",
45
+ maxSessionLength: 2048,
46
+ sepToken: "\n\n",
47
+ stopToken: "</s>",
48
+ extraStopSequences: ["\n\nHuman"],
49
+ },
50
+ };
51
+ var curModel = "meta-llama/Llama-2-70b-chat-hf";
52
+
53
+ const generationParams = {
54
+ do_sample: 1,
55
+ temperature: 0.9,
56
+ top_p: 0.6,
57
+ };
58
+
59
+ var ws = null;
60
+ var position = 0;
61
+ const initialSessionLength = 512;
62
+ var sessionLength = initialSessionLength;
63
+ var connFailureBefore = false;
64
+
65
+ var totalElapsed, nRequests;
66
+
67
+ const Regime = {
68
+ CHATBOT: 1,
69
+ FEW_SHOT: 2,
70
+ };
71
+ let curRegime = Regime.CHATBOT;
72
+ let stop = false;
73
+
74
+ function openSession() {
75
+ let protocol = location.protocol == "https:" ? "wss:" : "ws:";
76
+ ws = new WebSocket(`${protocol}//${location.host}/api/v2/generate`);
77
+ ws.onopen = () => {
78
+ ws.send(JSON.stringify({type: "open_inference_session", model: curModel, max_length: sessionLength}));
79
+ ws.onmessage = event => {
80
+ const response = JSON.parse(event.data);
81
+ if (!response.ok) {
82
+ handleFailure(response.traceback);
83
+ return;
84
+ }
85
+
86
+ sendReplica();
87
+ };
88
+ };
89
+
90
+ ws.onerror = _event => handleFailure(`Connection failed`);
91
+ ws.onclose = _event => {
92
+ if ($(".error-box").is(":hidden")) {
93
+ handleFailure(`Connection was closed`, true);
94
+ }
95
+ };
96
+ }
97
+
98
+ function resetSession() {
99
+ if (ws !== null && ws.readyState <= 1) { // If readyState is "connecting" or "opened"
100
+ ws.close();
101
+ }
102
+ ws = null;
103
+ position = 0;
104
+ }
105
+
106
+ function isWaitingForInputs() {
107
+ return $('.human-replica textarea').length >= 1;
108
+ }
109
+
110
+ function sendReplica() {
111
+ if (isWaitingForInputs()) {
112
+ const aiPrompt = (curRegime === Regime.CHATBOT) ? 'Assistant:' : '';
113
+ $('.human-replica:last').text($('.human-replica:last textarea').val());
114
+ $('.dialogue').append($(
115
+ '<p class="ai-replica">' +
116
+ `<span class="text">${aiPrompt}</span>` +
117
+ '<span class="loading-animation"></span>' +
118
+ '<span class="speed" style="display: none;"></span>' +
119
+ '<span class="generation-controls"><a class="stop-generation" href=#>stop generation</a></span>' +
120
+ '<span class="suggest-join" style="display: none;">' +
121
+ '<b>Too slow?</b> ' +
122
+ '<a target="_blank" href="https://github.com/bigscience-workshop/petals#connect-your-gpu-and-increase-petals-capacity">Connect your GPU</a> ' +
123
+ 'and increase Petals capacity!' +
124
+ '</span>' +
125
+ '</p>'));
126
+ animateLoading();
127
+ $('.stop-generation').click(e => {
128
+ e.preventDefault();
129
+ console.log("Stop generation");
130
+ stop = true;
131
+ });
132
+ } else {
133
+ $('.loading-animation').show();
134
+ }
135
+
136
+ if (ws === null) {
137
+ openSession();
138
+ return;
139
+ }
140
+
141
+ const replicaDivs = $('.human-replica, .ai-replica .text');
142
+ var replicas = [];
143
+ for (var i = position; i < replicaDivs.length; i++) {
144
+ const el = $(replicaDivs[i]);
145
+ var phrase = el.text();
146
+ if (el.is(".human-replica")) {
147
+ phrase += models[curModel].sepToken;
148
+ } else
149
+ if (i < replicaDivs.length - 1) {
150
+ phrase += models[curModel].stopToken;
151
+ }
152
+ replicas.push(phrase);
153
+ }
154
+ const inputs = replicas.join("");
155
+ position = replicaDivs.length;
156
+
157
+ totalElapsed = 0;
158
+ nRequests = 0;
159
+ receiveReplica(inputs);
160
+ }
161
+
162
+ function receiveReplica(inputs) {
163
+ ws.send(JSON.stringify({
164
+ type: "generate",
165
+ inputs: inputs,
166
+ max_new_tokens: 1,
167
+ stop_sequence: models[curModel].stopToken,
168
+ extra_stop_sequences: models[curModel].extraStopSequences,
169
+ ...generationParams
170
+ }));
171
+
172
+ var lastMessageTime = null;
173
+ ws.onmessage = event => {
174
+ connFailureBefore = false; // We've managed to connect after a possible failure
175
+
176
+ const response = JSON.parse(event.data);
177
+ if (!response.ok) {
178
+ handleFailure(response.traceback);
179
+ return;
180
+ }
181
+
182
+ if (lastMessageTime != null) {
183
+ totalElapsed += performance.now() - lastMessageTime;
184
+ nRequests++;
185
+ }
186
+ lastMessageTime = performance.now();
187
+
188
+ const lastReplica = $('.ai-replica .text').last();
189
+ var newText = lastReplica.text() + response.outputs;
190
+ newText = newText.replace(models[curModel].stopToken, "");
191
+ if (models[curModel].extraStopSequences !== null) {
192
+ for (const seq of models[curModel].extraStopSequences) {
193
+ newText = newText.replace(seq, "");
194
+ }
195
+ }
196
+ lastReplica.text(newText);
197
+
198
+ if (!response.stop && !stop) {
199
+ if (nRequests >= 1) {
200
+ const speed = nRequests / (totalElapsed / 1000);
201
+ $('.speed')
202
+ .text(`Speed: ${speed.toFixed(1)} tokens/sec`)
203
+ .show();
204
+ if (speed < 0.5) {
205
+ $('.suggest-join').show();
206
+ }
207
+ }
208
+ } else {
209
+ $('.loading-animation, .speed, .suggest-join, .generation-controls').remove();
210
+ resetSession();
211
+ appendTextArea();
212
+ stop = false;
213
+ }
214
+ };
215
+ }
216
+
217
+ function handleFailure(message, autoRetry = false) {
218
+ resetSession();
219
+ if (!isWaitingForInputs()) {
220
+ // Show the error and the retry button only if a user is waiting for the generation results
221
+
222
+ if (message === "Connection failed" && !connFailureBefore) {
223
+ autoRetry = true;
224
+ connFailureBefore = true;
225
+ }
226
+ if (/Session .+ expired/.test(message)) {
227
+ autoRetry = true;
228
+ }
229
+ if (/Maximum length exceeded/.test(message) && sessionLength < models[curModel].maxSessionLength) {
230
+ // We gradually increase sessionLength to save server resources. Default: 512 -> 2048 -> 8192 (if supported)
231
+ sessionLength = Math.min(sessionLength * 4, models[curModel].maxSessionLength);
232
+ autoRetry = true;
233
+ }
234
+
235
+ if (autoRetry) {
236
+ retry();
237
+ } else {
238
+ $('.loading-animation').hide();
239
+ if (/attention cache is full/.test(message)) {
240
+ $('.error-message').hide();
241
+ $('.out-of-capacity').show();
242
+ } else {
243
+ $('.out-of-capacity').hide();
244
+ $('.error-message').text(message).show();
245
+ }
246
+ $('.error-box').show();
247
+ }
248
+ }
249
+ }
250
+
251
+ function retry() {
252
+ $('.error-box').hide();
253
+ sendReplica();
254
+ }
255
+
256
+ function appendTextArea() {
257
+ const humanPrompt = (curRegime === Regime.CHATBOT) ? "Human: " : "";
258
+ $('.dialogue').append($(
259
+ `<p class="human-replica"><textarea class="form-control" id="exampleTextarea" rows="2">${humanPrompt}</textarea></p>`
260
+ ));
261
+ upgradeTextArea();
262
+ }
263
+
264
+ function upgradeTextArea() {
265
+ const textarea = $('.human-replica textarea');
266
+ autosize(textarea);
267
+ textarea[0].selectionStart = textarea[0].value.length;
268
+ textarea.focus();
269
+
270
+ textarea.on('keypress', e => {
271
+ if (e.which == 13 && !e.shiftKey) {
272
+ e.preventDefault();
273
+ sendReplica();
274
+ }
275
+ });
276
+ }
277
+
278
+ const animFrames = ["⌛", "🧠"];
279
+ var curFrame = 0;
280
+
281
+ function animateLoading() {
282
+ $('.loading-animation').html(' &nbsp;' + animFrames[curFrame]);
283
+ curFrame = (curFrame + 1) % animFrames.length;
284
+ }
285
+
286
+ $(() => {
287
+ upgradeTextArea();
288
+
289
+ $('.family-selector label').click(function (e) {
290
+ if (!isWaitingForInputs()) {
291
+ alert("Can't switch the model while the AI is writing a response. Please refresh the page");
292
+ e.preventDefault();
293
+ return;
294
+ }
295
+
296
+ const radio = $(`#${$(this).attr("for")}`);
297
+ if (radio.is(":checked")) {
298
+ setTimeout(() => $('.human-replica textarea').focus(), 10);
299
+ return;
300
+ }
301
+
302
+ const curFamily = radio.attr("value");
303
+ $('.model-selector').hide();
304
+ const firstLabel = $(`.model-selector[data-family=${curFamily}]`).show().children('label:first');
305
+ firstLabel.click();
306
+ firstLabel.trigger('click');
307
+ });
308
+ $('.model-selector label').click(function (e) {
309
+ if (!isWaitingForInputs()) {
310
+ alert("Can't switch the model while the AI is writing a response. Please refresh the page");
311
+ e.preventDefault();
312
+ return;
313
+ }
314
+
315
+ curModel = $(`#${$(this).attr("for")}`).attr("value");
316
+ if (curRegime === Regime.CHATBOT) {
317
+ $('.dialogue p').slice(2).remove();
318
+ } else {
319
+ $('.dialogue').empty();
320
+ }
321
+
322
+ sessionLength = initialSessionLength;
323
+ resetSession();
324
+ appendTextArea();
325
+
326
+ $('.model-name')
327
+ .text($(this).text())
328
+ .attr('href', models[curModel].modelCard);
329
+ $('.license-link').attr('href', models[curModel].license);
330
+ setTimeout(() => $('.human-replica textarea').focus(), 10);
331
+ });
332
+ $('.retry-link').click(e => {
333
+ e.preventDefault();
334
+ retry();
335
+ });
336
+
337
+ setInterval(animateLoading, 2000);
338
+ });
static/index.html ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <!-- Google tag (gtag.js) -->
5
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-LENBCEYH86"></script>
6
+ <script>
7
+ window.dataLayer = window.dataLayer || [];
8
+ function gtag(){dataLayer.push(arguments);}
9
+ gtag('js', new Date());
10
+
11
+ gtag('config', 'G-LENBCEYH86');
12
+ </script>
13
+
14
+ <meta charset="utf-8">
15
+ <meta name="viewport" content="width=device-width, initial-scale=1">
16
+ <link rel="icon" class="js-site-favicon" type="image/png" href="./static/logo.svg">
17
+ <title>Petals &ndash; Decentralized platform for running large language models</title>
18
+ <link href="./static/bootstrap.min.css" rel="stylesheet">
19
+ <link href="./static/style.css" rel="stylesheet">
20
+ </head>
21
+ <body>
22
+
23
+ <main>
24
+ <div class="position-relative overflow-hidden px-5 pt-1 m-md-4 text-center">
25
+ <div class="col-lg-6 col-md-8 p-md-3 mx-auto my-3" style="max-width: 700px;">
26
+ <div class="mb-4">
27
+ <div class="d-md-inline-block pe-md-4">
28
+ <a target="_blank" href="https://petals.dev"><img src="./static/logo.svg" height="100" class="rot-image"></a>
29
+ </div>
30
+ <h1 class="display-4 fw-bold d-md-inline-block justify-content-center" style="font-size: 40pt; vertical-align: middle;">
31
+ Petals
32
+ <span style="font-size: 25pt; color: #aaa;">Chat</span>
33
+ </h1>
34
+ </div>
35
+ <div class="welcome mb-4">
36
+ <div>
37
+ <b>Welcome!</b> This is a demo app running
38
+ <a target="_blank" class="model-name" href="https://huggingface.co/meta-llama/Llama-2-70b-chat-hf">LLaMA 2 (70B-chat)</a>
39
+ over the <a target="_blank" href="https://petals.dev">Petals</a> network.
40
+ Please follow the model's
41
+ <a target="_blank" class="license-link" href="https://bit.ly/llama2-license">terms of use</a>
42
+ and do not enter sensitive data.
43
+ The chat history is recorded.
44
+ </div>
45
+ <form id="settings">
46
+ <div class="mt-2">
47
+ <label class="group-label">Family:</label>
48
+ <div class="btn-group family-selector" role="group">
49
+ <input type="radio" class="btn-check" name="family" value="llama-2" id="family-llama-2" checked>
50
+ <label class="btn btn-outline-primary" for="family-llama-2">LLaMA 2</label>
51
+ <input type="radio" class="btn-check" name="family" value="llama" id="family-llama">
52
+ <label class="btn btn-outline-primary" for="family-llama">LLaMA</label>
53
+ <input type="radio" class="btn-check" name="family" value="bloom" id="family-bloom">
54
+ <label class="btn btn-outline-primary" for="family-bloom">BLOOM</label>
55
+ </div>
56
+ </div>
57
+ <div class="mt-2">
58
+ <label class="group-label">Model:</label>
59
+ <div class="model-selector btn-group" role="group" data-family="llama-2">
60
+ <input type="radio" class="btn-check" name="model" value="meta-llama/Llama-2-70b-chat-hf" id="meta-llama-2-70b-chat-hf" checked>
61
+ <label class="btn btn-outline-primary" for="meta-llama-2-70b-chat-hf">LLaMA 2 (70B-chat)</label>
62
+ <input type="radio" class="btn-check" name="model" value="meta-llama/Llama-2-70b-hf" id="meta-llama-2-70b-hf">
63
+ <label class="btn btn-outline-primary" for="meta-llama-2-70b-hf">LLaMA 2 (70B)</label>
64
+ </div>
65
+ <div class="model-selector btn-group" role="group" data-family="llama" style="display: none;">
66
+ <input type="radio" class="btn-check" name="model" value="timdettmers/guanaco-65b" id="model-guanaco-65b">
67
+ <label class="btn btn-outline-primary" for="model-guanaco-65b">Guanaco-65B</label>
68
+ <input type="radio" class="btn-check" name="model" value="enoch/llama-65b-hf" id="model-llama-65b-hf">
69
+ <label class="btn btn-outline-primary" for="model-llama-65b-hf">LLaMA-65B</label>
70
+ </div>
71
+ <div class="model-selector btn-group" role="group" data-family="bloom" style="display: none;">
72
+ <!-- <input type="radio" class="btn-check" name="model" value="bigscience/bloom" id="model-bloom">
73
+ <label class="btn btn-outline-primary" for="model-bloomz">BLOOM-176B</label> -->
74
+ <input type="radio" class="btn-check" name="model" value="bigscience/bloomz" id="model-bloomz">
75
+ <label class="btn btn-outline-primary" for="model-bloomz">BLOOMZ-176B</label>
76
+ </div>
77
+ </div>
78
+ </form>
79
+ </div>
80
+ <div class="dialogue">
81
+ <p class="human-replica">A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.</p>
82
+ <p class="ai-replica"><span class="text">Assistant: Hi! How can I help you?</span></p>
83
+ <p class="human-replica"><textarea class="form-control" id="exampleTextarea" rows="2">Human: </textarea></p>
84
+ </div>
85
+ <p class="error-box" style="display: none;">
86
+ Request failed. <a class="retry-link" href="#">Retry</a><br>
87
+ <span class="error-message"></span>
88
+ <span class="out-of-capacity"><br>
89
+ <b>We're out of capacity</b> &mdash; attention caches of existing servers are full.
90
+ Please come back later, or
91
+ <a target="_blank" href="https://github.com/bigscience-workshop/petals#connect-your-gpu-and-increase-petals-capacity">connect your GPU</a>
92
+ to increase Petals capacity now!
93
+ </span>
94
+ </p>
95
+
96
+ <p class="acknowledgements mt-5 pt-3">
97
+ <!-- <a class="show-few-shot" href="#">Few-shot mode</a><br> -->
98
+ <b>Shift+Enter</b> inserts newlines.<br>
99
+ See source code and API docs on <a target="_blank" href="https://github.com/petals-infra/chat.petals.dev">GitHub</a>.
100
+ </p>
101
+ </div>
102
+ </div>
103
+ </main>
104
+ <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
105
+ <script src="./static/autosize.min.js"></script>
106
+ <script src="./static/chat.js"></script>
107
+ </body>
108
+ </html>
static/logo.svg ADDED
static/style.css ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .container {
2
+ max-width: 960px;
3
+ }
4
+
5
+ /*
6
+ * Custom translucent site header
7
+ */
8
+
9
+ .site-header {
10
+ background-color: rgba(0, 0, 0, .85);
11
+ -webkit-backdrop-filter: saturate(180%) blur(20px);
12
+ backdrop-filter: saturate(180%) blur(20px);
13
+ }
14
+ .site-header a {
15
+ color: #8e8e8e;
16
+ transition: color .15s ease-in-out;
17
+ }
18
+ .site-header a:hover {
19
+ color: #fff;
20
+ text-decoration: none;
21
+ }
22
+
23
+ /*
24
+ * Dummy devices (replace them with your own or something else entirely!)
25
+ */
26
+
27
+ .product-device {
28
+ position: absolute;
29
+ right: 10%;
30
+ bottom: -30%;
31
+ width: 300px;
32
+ height: 540px;
33
+ background-color: #333;
34
+ border-radius: 21px;
35
+ transform: rotate(30deg);
36
+ }
37
+
38
+ .product-device::before {
39
+ position: absolute;
40
+ top: 10%;
41
+ right: 10px;
42
+ bottom: 10%;
43
+ left: 10px;
44
+ content: "";
45
+ background-color: rgba(255, 255, 255, .1);
46
+ border-radius: 5px;
47
+ }
48
+
49
+ .product-device-2 {
50
+ top: -25%;
51
+ right: auto;
52
+ bottom: 0;
53
+ left: 5%;
54
+ background-color: #e5e5e5;
55
+ }
56
+
57
+
58
+ /*
59
+ * Extra utilities
60
+ */
61
+
62
+ .flex-equal > * {
63
+ flex: 1;
64
+ }
65
+ @media (min-width: 768px) {
66
+ .flex-md-equal > * {
67
+ flex: 1;
68
+ }
69
+ }
70
+
71
+
72
+ .form-control:focus {
73
+ /* From Bootswatch Flatly theme */
74
+ border-color: #969fa8;
75
+ box-shadow: 0 0 0 0.25rem rgb(44 62 80 / 25%);
76
+ }
77
+
78
+
79
+ .rot-image {
80
+ -webkit-animation:spin 4s linear infinite;
81
+ -moz-animation:spin 4s linear infinite;
82
+ animation:spin 60s linear infinite;
83
+ }
84
+ @-moz-keyframes spin {
85
+ 100% { -moz-transform: rotate(360deg); }
86
+ }
87
+ @-webkit-keyframes spin {
88
+ 100% { -webkit-transform: rotate(360deg); }
89
+ }
90
+ @keyframes spin {
91
+ 100% {
92
+ -webkit-transform: rotate(360deg);
93
+ transform:rotate(360deg);
94
+ }
95
+ }
96
+
97
+ .lead {
98
+ font-size: 13pt;
99
+ }
100
+
101
+ main p {
102
+ font-size: 10pt;
103
+ }
104
+
105
+ .acknowledgements {
106
+ font-size: 9pt;
107
+ }
108
+
109
+ .feature-list {
110
+ padding-left: 0;
111
+ }
112
+
113
+ .feature-list li {
114
+ position: relative;
115
+ font-size: 10.5pt;
116
+ margin: 0;
117
+ padding-left: 50px;
118
+ list-style: none;
119
+ text-align: left;
120
+ }
121
+
122
+ .feature-list li:before {
123
+ content: " ";
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ width: 35px;
128
+ height: 100%;
129
+ box-sizing: border-box;
130
+ background-image: url("leaf.svg");
131
+ background-repeat: no-repeat;
132
+ background-position: left center;
133
+ background-size: 35px;
134
+ }
135
+
136
+ .human-replica, .ai-replica, .welcome, .error-box {
137
+ border: 1px solid #777;
138
+ border-radius: 10px;
139
+ padding: 10px 15px;
140
+ width: 90%;
141
+ max-width: 360px;
142
+ text-align: left;
143
+ word-wrap: break-word;
144
+ }
145
+
146
+ .human-replica, .ai-replica, .error-message {
147
+ white-space: pre-wrap;
148
+ }
149
+
150
+ .human-replica {
151
+ background-color: #f7f7ff;
152
+ margin-left: auto;
153
+ margin-right: 0;
154
+ }
155
+
156
+ .human-replica:focus-within {
157
+ border: 2px solid black;
158
+ padding: 9px 14px;
159
+ }
160
+
161
+ .human-replica textarea {
162
+ background-color: #f7f7ff !important;
163
+ border: none;
164
+ resize: none;
165
+ padding: 0;
166
+ font-size: 10pt;
167
+ }
168
+
169
+ .human-replica textarea.form-control:focus {
170
+ border: none;
171
+ box-shadow: none;
172
+ }
173
+
174
+ .ai-replica {
175
+ background-color: #fff7f7;
176
+ }
177
+
178
+ .speed, .generation-controls, .suggest-join {
179
+ display: block;
180
+ color: #999;
181
+ font-size: 9pt;
182
+ line-height: 1.25;
183
+ margin-top: 7px;
184
+ }
185
+
186
+ .generation-controls a {
187
+ color: #999;
188
+ }
189
+
190
+ .welcome {
191
+ background-color: #fff7f7;
192
+ margin-left: auto;
193
+ margin-right: 0;
194
+ max-width: 400px;
195
+ }
196
+
197
+ @media (max-width: 767px) {
198
+ .welcome {
199
+ width: 100%;
200
+ }
201
+ }
202
+
203
+ .welcome div, .welcome label, .welcome .dropdown button {
204
+ font-size: 9pt;
205
+ }
206
+
207
+ .welcome .group-label {
208
+ padding-left: 0;
209
+ padding-right: 5px;
210
+ }
211
+
212
+ .welcome label {
213
+ padding: 1px 7px;
214
+ }
215
+
216
+ .welcome label, .welcome input {
217
+ box-shadow: none !important;
218
+ }
219
+
220
+ .welcome .btn-outline-primary, .welcome .btn-outline-primary:hover {
221
+ color: #333;
222
+ border-color: black;
223
+ }
224
+
225
+ .welcome .btn-check:active+.btn-outline-primary, .welcome .btn-check:checked+.btn-outline-primary {
226
+ color: #fff;
227
+ background-color: #333;
228
+ border-color: black;
229
+ }
230
+
231
+ .welcome .btn-outline-primary:hover {
232
+ color: black;
233
+ background-color: #ccc;
234
+ border-color: black;
235
+ }
236
+
237
+ .error-box {
238
+ font-size: 10pt;
239
+ background-color: #fcc;
240
+ margin-left: auto;
241
+ margin-right: 0;
242
+ max-width: 100%;
243
+ word-wrap: break-word;
244
+ }
245
+
246
+ .error-message {
247
+ font-family: monospace;
248
+ font-size: 8pt;
249
+ }
250
+
251
+ .out-of-capacity {
252
+ font-size: 9pt;
253
+ }
254
+
255
+ .reset-btn {
256
+ font-size: 9pt;
257
+ }