chansung commited on
Commit
30166ed
·
1 Parent(s): 6cf8b16

Update app.py

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