chansung commited on
Commit
f407c35
·
1 Parent(s): 5f0f907

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +353 -11
app.py CHANGED
@@ -1,11 +1,18 @@
1
  from typing import Text, Any, Dict, Optional
2
 
3
- import gradio as gr
 
 
4
  import tensorflow as tf
5
  import tensorflow_text
6
  from tensorflow.python.saved_model import tag_constants
7
  from huggingface_hub import Repository
8
 
 
 
 
 
 
9
  local_path = "hf_model"
10
 
11
  model_version = "v1687590401"
@@ -23,24 +30,359 @@ _ = _clone_and_checkout(model_repo_url, local_path, model_version)
23
  model = tf.saved_model.load(local_path, tags=[tag_constants.SERVING])
24
  gpt_lm_predict_fn = model.signatures["serving_default"]
25
 
26
- def gen_text(prompt, max_length=256):
27
- prompt = tf.constant(f"### Instruction:\n{prompt}\n\n### Response:\n")
28
- max_length = tf.constant(max_length, dtype="int64")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  result = gpt_lm_predict_fn(
31
  prompt=prompt,
32
  max_length=max_length,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  )
34
 
35
- return result['result'].numpy().decode('UTF-8').split("### Response:")[-1].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- with gr.Blocks() as demo:
38
- instruction = gr.Textbox("Instruction")
39
- output = gr.Textbox("Output", lines=5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- instruction.submit(
42
- lambda prompt: gen_text(prompt),
43
- instruction, output
 
 
 
 
44
  )
 
 
 
 
 
 
 
45
 
46
  demo.launch()
 
1
  from typing import Text, Any, Dict, Optional
2
 
3
+ import json
4
+ import copy
5
+
6
  import tensorflow as tf
7
  import tensorflow_text
8
  from tensorflow.python.saved_model import tag_constants
9
  from huggingface_hub import Repository
10
 
11
+ import gradio as gr
12
+ from pingpong import PingPong
13
+ from pingpong.gradio import GradioAlpacaChatPPManager
14
+ from pingpong.context import CtxLastWindowStrategy
15
+
16
  local_path = "hf_model"
17
 
18
  model_version = "v1687590401"
 
30
  model = tf.saved_model.load(local_path, tags=[tag_constants.SERVING])
31
  gpt_lm_predict_fn = model.signatures["serving_default"]
32
 
33
+ STYLE = """
34
+ .custom-btn {
35
+ border: none !important;
36
+ background: none !important;
37
+ box-shadow: none !important;
38
+ display: block !important;
39
+ text-align: left !important;
40
+ }
41
+ .custom-btn:hover {
42
+ background: rgb(243 244 246) !important;
43
+ }
44
+ .custom-btn-highlight {
45
+ border: none !important;
46
+ background: rgb(243 244 246) !important;
47
+ box-shadow: none !important;
48
+ display: block !important;
49
+ text-align: left !important;
50
+ }
51
+ #prompt-txt > label > span {
52
+ display: none !important;
53
+ }
54
+ #prompt-txt > label > textarea {
55
+ border: transparent;
56
+ box-shadow: none;
57
+ }
58
+ #chatbot {
59
+ height: 800px;
60
+ overflow: auto;
61
+ box-shadow: none !important;
62
+ border: none !important;
63
+ }
64
+ #chatbot > .wrap {
65
+ max-height: 780px;
66
+ }
67
+ #chatbot + div {
68
+ border-radius: 35px !important;
69
+ width: 80% !important;
70
+ margin: auto !important;
71
+ }
72
+ #left-pane {
73
+ background-color: #f9fafb;
74
+ border-radius: 15px;
75
+ padding: 10px;
76
+ }
77
+ #left-top {
78
+ padding-left: 10px;
79
+ padding-right: 10px;
80
+ text-align: center;
81
+ font-weight: bold;
82
+ font-size: large;
83
+ }
84
+ #chat-history-accordion {
85
+ background: transparent;
86
+ border: 0.8px !important;
87
+ }
88
+ #right-pane {
89
+ margin-left: 20px;
90
+ margin-right: 70px;
91
+ }
92
+ #initial-popup {
93
+ z-index: 100;
94
+ position: absolute;
95
+ width: 50%;
96
+ top: 50%;
97
+ height: 50%;
98
+ left: 50%;
99
+ transform: translate(-50%, -50%);
100
+ border-radius: 35px;
101
+ padding: 15px;
102
+ }
103
+ #initial-popup-title {
104
+ text-align: center;
105
+ font-size: 18px;
106
+ font-weight: bold;
107
+ }
108
+ #initial-popup-left-pane {
109
+ min-width: 150px !important;
110
+ }
111
+ #initial-popup-right-pane {
112
+ text-align: right;
113
+ }
114
+ .example-btn {
115
+ padding-top: 20px !important;
116
+ padding-bottom: 20px !important;
117
+ padding-left: 5px !important;
118
+ padding-right: 5px !important;
119
+ background: linear-gradient(to bottom right, #f7faff, #ffffff) !important;
120
+ box-shadow: none !important;
121
+ border-radius: 20px !important;
122
+ }
123
+ .example-btn:hover {
124
+ box-shadow: 0.3px 0.3px 0.3px gray !important;
125
+ }
126
+ #example-title {
127
+ margin-bottom: 15px;
128
+ }
129
+ #aux-btns-popup {
130
+ z-index: 200;
131
+ position: absolute !important;
132
+ bottom: 75px !important;
133
+ right: 15px !important;
134
+ }
135
+ #aux-btns-popup > div {
136
+ flex-wrap: nowrap;
137
+ width: auto;
138
+ margin: auto;
139
+ }
140
+ .aux-btn {
141
+ height: 30px !important;
142
+ flex-wrap: initial !important;
143
+ flex: none !important;
144
+ min-width: min(100px,100%) !important;
145
+ font-weight: unset !important;
146
+ font-size: 10pt !important;
147
+ background: linear-gradient(to bottom right, #f7faff, #ffffff) !important;
148
+ box-shadow: none !important;
149
+ border-radius: 20px !important;
150
+ }
151
+ .aux-btn:hover {
152
+ box-shadow: 0.3px 0.3px 0.3px gray !important;
153
+ }
154
+ """
155
+
156
+ get_local_storage = """
157
+ function() {
158
+ globalThis.setStorage = (key, value)=>{
159
+ localStorage.setItem(key, JSON.stringify(value));
160
+ }
161
+ globalThis.getStorage = (key, value)=>{
162
+ return JSON.parse(localStorage.getItem(key));
163
+ }
164
+ var local_data = getStorage('local_data');
165
+ var history = [];
166
+ if(local_data) {
167
+ local_data[0].pingpongs.forEach(element =>{
168
+ history.push([element.ping, element.pong]);
169
+ });
170
+ }
171
+ else {
172
+ local_data = [];
173
+ for (let step = 0; step < 10; step++) {
174
+ local_data.push({'ctx': '', 'pingpongs':[]});
175
+ }
176
+ setStorage('local_data', local_data);
177
+ }
178
+ if(history.length == 0) {
179
+ document.querySelector("#initial-popup").classList.remove('hide');
180
+ }
181
+
182
+ return [history, local_data];
183
+ }
184
+ """
185
+
186
+ update_left_btns_state = """
187
+ (v)=>{
188
+ document.querySelector('.custom-btn-highlight').classList.add('custom-btn');
189
+ document.querySelector('.custom-btn-highlight').classList.remove('custom-btn-highlight');
190
+ const elements = document.querySelectorAll(".custom-btn");
191
+ for(var i=0; i < elements.length; i++) {
192
+ const element = elements[i];
193
+ if(element.textContent == v) {
194
+ console.log(v);
195
+ element.classList.add('custom-btn-highlight');
196
+ element.classList.remove('custom-btn');
197
+ break;
198
+ }
199
+ }
200
+ }"""
201
+
202
+ channels = [
203
+ "1st Channel",
204
+ "2nd Channel",
205
+ "3rd Channel",
206
+ "4th Channel",
207
+ "5th Channel",
208
+ "6th Channel",
209
+ "7th Channel",
210
+ "8th Channel",
211
+ "9th Channel",
212
+ "10th Channel"
213
+ ]
214
+ channel_btns = []
215
+
216
+ examples = [
217
+ "hello world",
218
+ "what's up?",
219
+ "this is GradioChat"
220
+ ]
221
+ ex_btns = []
222
+
223
+ def reset_chat(idx, ld):
224
+ res = [GradioAlpacaChatPPManager.from_json(json.dumps(ppm)) for ppm in ld]
225
+ res[idx].pingpongs = []
226
+
227
+ return (
228
+ "",
229
+ [],
230
+ str(res),
231
+ gr.update(visible=True),
232
+ gr.update(interactive=False),
233
+ )
234
+
235
+ def build_prompts(ppmanager):
236
+ dummy_ppm = copy.deepcopy(ppmanager)
237
+
238
+ dummy_ppm.ctx = """Below are a series of dialogues between human and an AI assistant.
239
+ The AI tries to answer the given instruction as in response.
240
+ The AI MUST not generate any text containing `### Response` or `### Instruction`.
241
+ The AI MUST be helpful, polite, honest, sophisticated, emotionally aware, and humble-but-knowledgeable.
242
+ The assistant MUST be happy to help with almost anything, and will do its best to understand exactly what is needed.
243
+ It also MUST avoid giving false or misleading information, and it caveats when it isn’t entirely sure about the right answer.
244
+ That said, the assistant is practical and really does its best, and doesn’t let caution get too much in the way of being useful.
245
+ """
246
+ return CtxLastWindowStrategy(3)(dummy_ppm)
247
+
248
+ def add_pingpong(idx, ld, ping):
249
+ res = [GradioAlpacaChatPPManager.from_json(json.dumps(ppm)) for ppm in ld]
250
+ ppm = res[idx]
251
+
252
+ ppm.add_pingpong(
253
+ PingPong(ping, "")
254
+ )
255
+
256
+ prompt = tf.constant(build_prompts(ppm))
257
+ max_length = tf.constant(512, dtype="int64")
258
+ print(f"Prompt:\n{prompt}")
259
 
260
  result = gpt_lm_predict_fn(
261
  prompt=prompt,
262
  max_length=max_length,
263
+ )['result'].numpy().decode('UTF-8')
264
+ result = result.split("### Response:")[-1].strip()
265
+
266
+ ppm.add_pong(result)
267
+ print(f"res:\n{str(res)}")
268
+ return "", ppm.build_uis(), str(res)
269
+
270
+ def channel_num(btn_title):
271
+ choice = 0
272
+
273
+ for idx, channel in enumerate(channels):
274
+ if channel == btn_title:
275
+ choice = idx
276
+
277
+ return choice
278
+
279
+ def set_chatbot(btn, ld):
280
+ choice = channel_num(btn)
281
+
282
+ res = [
283
+ GradioAlpacaChatPPManager.from_json(json.dumps(ppm_str))
284
+ for ppm_str in ld
285
+ ]
286
+ empty = len(res[choice].pingpongs) == 0
287
+ return (
288
+ res[choice].build_uis(),
289
+ choice,
290
+ gr.update(visible=empty)
291
  )
292
 
293
+ def set_example(btn):
294
+ return btn, gr.update(visible=False)
295
+
296
+ def set_popup_visibility(ld, example_block):
297
+ return example_block
298
+
299
+ with gr.Blocks(css=STYLE, elem_id='container-col') as demo:
300
+ idx = gr.State(0)
301
+ local_data = gr.JSON({},visible=False)
302
+
303
+ with gr.Row():
304
+ with gr.Column(scale=1, min_width=180):
305
+ gr.Markdown("GradioChat", elem_id="left-top")
306
+
307
+ with gr.Column(elem_id="left-pane"):
308
+ with gr.Accordion("Histories", elem_id="chat-history-accordion"):
309
+ channel_btns.append(gr.Button(channels[0], elem_classes=["custom-btn-highlight"]))
310
+
311
+ for channel in channels[1:]:
312
+ channel_btns.append(gr.Button(channel, elem_classes=["custom-btn"]))
313
+
314
+ with gr.Column(scale=8, elem_id="right-pane"):
315
+ with gr.Column(elem_id="initial-popup", visible=False) as example_block:
316
+ with gr.Row(scale=1):
317
+ with gr.Column(elem_id="initial-popup-left-pane"):
318
+ gr.Markdown("GradioChat", elem_id="initial-popup-title")
319
+ gr.Markdown("Making the community's best AI chat models available to everyone.")
320
+ with gr.Column(elem_id="initial-popup-right-pane"):
321
+ gr.Markdown("Chat UI is now open sourced on Hugging Face Hub")
322
+ gr.Markdown("check out the [↗ repository](https://huggingface.co/spaces/chansung/test-multi-conv)")
323
+
324
+ with gr.Column(scale=1):
325
+ gr.Markdown("Examples")
326
+ with gr.Row() as text_block:
327
+ for example in examples:
328
+ ex_btns.append(gr.Button(example, elem_classes=["example-btn"]))
329
+
330
+ with gr.Column(elem_id="aux-btns-popup", visible=True):
331
+ with gr.Row():
332
+ # stop = gr.Button("Stop", elem_classes=["aux-btn"])
333
+ # regenerate = gr.Button("Regenerate", elem_classes=["aux-btn"])
334
+ clean = gr.Button("Clean", elem_classes=["aux-btn"])
335
+
336
+ chatbot = gr.Chatbot(elem_id='chatbot')
337
+ instruction_txtbox = gr.Textbox(
338
+ placeholder="Ask anything", label="",
339
+ elem_id="prompt-txt"
340
+ )
341
 
342
+ for btn in channel_btns:
343
+ btn.click(
344
+ set_chatbot,
345
+ [btn, local_data],
346
+ [chatbot, idx, example_block]
347
+ ).then(
348
+ None, btn, None,
349
+ _js=update_left_btns_state
350
+ )
351
+
352
+ for btn in ex_btns:
353
+ btn.click(
354
+ set_example,
355
+ [btn],
356
+ [instruction_txtbox, example_block]
357
+ )
358
+
359
+ instruction_txtbox.submit(
360
+ lambda: gr.update(visible=False),
361
+ None,
362
+ example_block
363
+ ).then(
364
+ add_pingpong,
365
+ [idx, local_data, instruction_txtbox],
366
+ [instruction_txtbox, chatbot, local_data]
367
+ ).then(
368
+ None, local_data, None,
369
+ _js="(v)=>{ setStorage('local_data',v) }"
370
+ )
371
 
372
+ clean.click(
373
+ reset_chat,
374
+ [idx, local_data],
375
+ [instruction_txtbox, chatbot, local_data, example_block]
376
+ ).then(
377
+ None, local_data, None,
378
+ _js="(v)=>{ setStorage('local_data',v) }"
379
  )
380
+
381
+ demo.load(
382
+ None,
383
+ inputs=None,
384
+ outputs=[chatbot, local_data],
385
+ _js=get_local_storage,
386
+ )
387
 
388
  demo.launch()