Pendrokar commited on
Commit
cc1e3ba
·
1 Parent(s): 5a35ee6

sample caching

Browse files
Files changed (5) hide show
  1. app/cookie.js +30 -0
  2. app/synth.py +28 -21
  3. app/ui.py +1 -0
  4. app/ui_vote.py +37 -27
  5. app/vote.py +45 -33
app/cookie.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.getArenaCookie = function getArenaCookie(cname) {
2
+ let name = cname + "=";
3
+ let decodedCookie = decodeURIComponent(window.document.cookie);
4
+ let ca = decodedCookie.split(';');
5
+ for (let i = 0; i < ca.length; i++) {
6
+ let c = ca[i];
7
+ while (c.charAt(0) == ' ') {
8
+ c = c.substring(1);
9
+ }
10
+ if (c.indexOf(name) == 0) {
11
+ return c.substring(name.length, c.length);
12
+ }
13
+ }
14
+ return "";
15
+ }
16
+
17
+ window.setArenaCookie = function setArenaCookie(cname, cvalue, exdays) {
18
+ const d = new Date();
19
+ d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
20
+ let expires = "expires=" + d.toUTCString();
21
+ window.document.cookie = cname + "=" + cvalue + ";" + expires + "; path=/; SameSite=None; Secure";
22
+ }
23
+
24
+ if (window.getArenaCookie('session').length == 0)
25
+ {
26
+ const d = new Date();
27
+ // store cookie for 90 days, about the time the the cached audio should be deleted
28
+ window.setArenaCookie('session', d.getTime().toString(), 90);
29
+ console.log('Session cookie created')
30
+ }
app/synth.py CHANGED
@@ -3,6 +3,7 @@ from .models import *
3
  from .utils import *
4
  from .config import *
5
  from .init import *
 
6
 
7
  import gradio as gr
8
  from pydub import AudioSegment
@@ -203,6 +204,28 @@ def synthandreturn(text, autoplay, request: gr.Request):
203
 
204
  return inputs
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  mdl1k = mdl1
207
  mdl2k = mdl2
208
  print(mdl1k, mdl2k)
@@ -222,10 +245,10 @@ def synthandreturn(text, autoplay, request: gr.Request):
222
  ):
223
  # run Zero-GPU spaces one at a time
224
  predict_and_update_result(text, mdl1k, results, request)
225
- # _cache_sample(text, mdl1k)
226
 
227
  predict_and_update_result(text, mdl2k, results, request)
228
- # _cache_sample(text, mdl2k)
229
  else:
230
  # use multithreading
231
  thread1 = threading.Thread(target=predict_and_update_result, args=(text, mdl1k, results, request))
@@ -240,8 +263,8 @@ def synthandreturn(text, autoplay, request: gr.Request):
240
  thread2.join(120)
241
 
242
  # cache the result
243
- # for model in [mdl1k, mdl2k]:
244
- # _cache_sample(text, model)
245
 
246
  print(f"Retrieving models {mdl1k} and {mdl2k} from API")
247
  return (
@@ -358,24 +381,8 @@ def synthandreturn_battle(text, mdl1, mdl2, autoplay):
358
  gr.update(visible=False), #nxt round btn
359
  )
360
 
361
- # Unlock vote
362
-
363
- def unlock_vote(btn_index, aplayed, bplayed):
364
- # sample played
365
- if btn_index == 0:
366
- aplayed = gr.State(value=True)
367
- if btn_index == 1:
368
- bplayed = gr.State(value=True)
369
-
370
- # both audio samples played
371
- if bool(aplayed) and bool(bplayed):
372
- print('Both audio samples played, voting unlocked')
373
- return [gr.update(interactive=True), gr.update(interactive=True), gr.update(), gr.update()]
374
-
375
- return [gr.update(), gr.update(), aplayed, bplayed]
376
-
377
  def randomsent():
378
- return random.choice(sents), '🎲'
379
  def randomsent_battle():
380
  return tuple(randomsent()) + tuple(random_m())
381
  def clear_stuff():
 
3
  from .utils import *
4
  from .config import *
5
  from .init import *
6
+ from .sample_caching import *
7
 
8
  import gradio as gr
9
  from pydub import AudioSegment
 
204
 
205
  return inputs
206
 
207
+ def _cache_sample(text, model):
208
+ # skip caching if not hardcoded sentence
209
+ if (text not in sents):
210
+ return False
211
+
212
+ already_cached = False
213
+ # check if already cached
214
+ for cached_sample in cached_samples:
215
+ # TODO:replace cached with newer version
216
+ if (cached_sample.transcript == text and cached_sample.modelName == model):
217
+ already_cached = True
218
+ return True
219
+
220
+ if (already_cached):
221
+ return False
222
+
223
+ try:
224
+ cached_samples.append(Sample(results[model], text, model))
225
+ except:
226
+ print('Error when trying to cache sample')
227
+ return False
228
+
229
  mdl1k = mdl1
230
  mdl2k = mdl2
231
  print(mdl1k, mdl2k)
 
245
  ):
246
  # run Zero-GPU spaces one at a time
247
  predict_and_update_result(text, mdl1k, results, request)
248
+ _cache_sample(text, mdl1k)
249
 
250
  predict_and_update_result(text, mdl2k, results, request)
251
+ _cache_sample(text, mdl2k)
252
  else:
253
  # use multithreading
254
  thread1 = threading.Thread(target=predict_and_update_result, args=(text, mdl1k, results, request))
 
263
  thread2.join(120)
264
 
265
  # cache the result
266
+ for model in [mdl1k, mdl2k]:
267
+ _cache_sample(text, model)
268
 
269
  print(f"Retrieving models {mdl1k} and {mdl2k} from API")
270
  return (
 
381
  gr.update(visible=False), #nxt round btn
382
  )
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  def randomsent():
385
+ return '⚡', random.choice(sents), '🎲'
386
  def randomsent_battle():
387
  return tuple(randomsent()) + tuple(random_m())
388
  def clear_stuff():
app/ui.py CHANGED
@@ -33,6 +33,7 @@ document.addEventListener('keypress', shortcuts, false);
33
 
34
  """
35
  head_js += shortcut_js
 
36
  head_js += '</script>'
37
 
38
  with gr.Blocks() as about:
 
33
 
34
  """
35
  head_js += shortcut_js
36
+ head_js += open("app/cookie.js").read()
37
  head_js += '</script>'
38
 
39
  with gr.Blocks() as about:
app/ui_vote.py CHANGED
@@ -3,37 +3,23 @@ from .config import *
3
  from .synth import *
4
  from .vote import *
5
  from .messages import *
 
6
 
7
  blur_text_js = 'document.getElementById("arena-text-input").classList.add("blurred-text")'
8
  unblur_text_js = 'document.getElementById("arena-text-input").classList.remove("blurred-text")'
9
 
10
  def disable():
11
- return [gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False)]
12
  def enable():
13
- return [gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True)]
14
  def blur_text():
15
  return gr.update(elem_classes=['blurred-text'])
16
  def unblur_text():
17
  return gr.update(elem_classes=[])
18
 
19
- def unlock_vote(autoplay, btn_index, aplayed, bplayed):
20
- if autoplay == False:
21
- return [gr.update(), gr.update(), aplayed, bplayed]
22
-
23
- # sample played
24
- if btn_index == 0:
25
- aplayed = True
26
- if btn_index == 1:
27
- bplayed = True
28
-
29
- # both audio samples played
30
- if bool(aplayed) and bool(bplayed):
31
- # print('Both audio samples played, voting unlocked')
32
- return [gr.update(interactive=True), gr.update(interactive=True), True, True]
33
-
34
- return [gr.update(), gr.update(), aplayed, bplayed]
35
-
36
  with gr.Blocks() as vote:
 
 
37
  # sample played, using Checkbox so that JS can fetch the value
38
  aplayed = gr.Checkbox(visible=False, value=False)
39
  bplayed = gr.Checkbox(visible=False, value=False)
@@ -42,6 +28,7 @@ with gr.Blocks() as vote:
42
  gr.Markdown(INSTR)
43
  with gr.Group():
44
  with gr.Row():
 
45
  text = gr.Textbox(
46
  container=False,
47
  show_label=False,
@@ -54,7 +41,7 @@ with gr.Blocks() as vote:
54
  )
55
  randomt = gr.Button('🎲', scale=0, min_width=0, variant='tool')
56
  randomt\
57
- .click(randomsent, outputs=[text, randomt])\
58
  .then(None, js="() => "+ unblur_text_js)
59
  btn = gr.Button("Synthesize", variant='primary')
60
  model1 = gr.Textbox(interactive=False, lines=1, max_lines=1, visible=False)
@@ -138,19 +125,26 @@ with gr.Blocks() as vote:
138
  gr.update(visible=False), #nxt round btn"""
139
  # , concurrency_count=1, concurrency_id="sync_queue"
140
  btn\
141
- .click(disable, outputs=[btn, abetter, bbetter])\
142
  .then(synthandreturn, inputs=[text, autoplay], outputs=outputs)\
143
- .then(enable, outputs=[btn, gr.State(), gr.State()])\
144
  .then(None, js="() => "+ unblur_text_js)
145
  # Next Round ; blur text
146
  nxtroundbtn\
147
  .click(clear_stuff, outputs=outputs)\
148
- .then(randomsent, outputs=[text, randomt])\
149
- .then(synthandreturn, inputs=[text, autoplay], outputs=outputs)\
150
- .then(enable, outputs=[btn, gr.State(), gr.State()])
151
  # blur text
152
  nxtroundbtn.click(None, js="() => "+ blur_text_js)
153
 
 
 
 
 
 
 
 
154
  # Allow interaction with the vote buttons only when both audio samples have finished playing
155
  aud1\
156
  .stop(
@@ -174,5 +168,21 @@ with gr.Blocks() as vote:
174
  aud2.stop(None, inputs=[aplayed], js="(a) => a ? "+ unblur_text_js +" : 0;")
175
 
176
  nxt_outputs = [abetter, bbetter, prevmodel1, prevmodel2, nxtroundbtn]
177
- abetter.click(a_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate])
178
- bbetter.click(b_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from .synth import *
4
  from .vote import *
5
  from .messages import *
6
+ from .sample_caching import *
7
 
8
  blur_text_js = 'document.getElementById("arena-text-input").classList.add("blurred-text")'
9
  unblur_text_js = 'document.getElementById("arena-text-input").classList.remove("blurred-text")'
10
 
11
  def disable():
12
+ return [gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False)]
13
  def enable():
14
+ return [gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True)]
15
  def blur_text():
16
  return gr.update(elem_classes=['blurred-text'])
17
  def unblur_text():
18
  return gr.update(elem_classes=[])
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  with gr.Blocks() as vote:
21
+ session_hash = gr.Textbox(visible=False, value='')
22
+
23
  # sample played, using Checkbox so that JS can fetch the value
24
  aplayed = gr.Checkbox(visible=False, value=False)
25
  bplayed = gr.Checkbox(visible=False, value=False)
 
28
  gr.Markdown(INSTR)
29
  with gr.Group():
30
  with gr.Row():
31
+ cachedt = gr.Button('⚡', scale=0, min_width=0, variant='tool', interactive=True)
32
  text = gr.Textbox(
33
  container=False,
34
  show_label=False,
 
41
  )
42
  randomt = gr.Button('🎲', scale=0, min_width=0, variant='tool')
43
  randomt\
44
+ .click(randomsent, outputs=[cachedt, text, randomt])\
45
  .then(None, js="() => "+ unblur_text_js)
46
  btn = gr.Button("Synthesize", variant='primary')
47
  model1 = gr.Textbox(interactive=False, lines=1, max_lines=1, visible=False)
 
125
  gr.update(visible=False), #nxt round btn"""
126
  # , concurrency_count=1, concurrency_id="sync_queue"
127
  btn\
128
+ .click(disable, outputs=[btn, abetter, bbetter, cachedt])\
129
  .then(synthandreturn, inputs=[text, autoplay], outputs=outputs)\
130
+ .then(enable, outputs=[btn, gr.State(), gr.State(), gr.State()])\
131
  .then(None, js="() => "+ unblur_text_js)
132
  # Next Round ; blur text
133
  nxtroundbtn\
134
  .click(clear_stuff, outputs=outputs)\
135
+ .then(disable, outputs=[btn, abetter, bbetter, cachedt])\
136
+ .then(give_cached_sample, inputs=[session_hash], outputs=[*outputs, cachedt])\
137
+ .then(enable, outputs=[btn, gr.State(), gr.State(), gr.State()])
138
  # blur text
139
  nxtroundbtn.click(None, js="() => "+ blur_text_js)
140
 
141
+ # fetch a comparison pair from cache
142
+ cachedt\
143
+ .click(disable, outputs=[btn, abetter, bbetter, cachedt])\
144
+ .then(give_cached_sample, inputs=[session_hash], outputs=[*outputs, cachedt])\
145
+ .then(enable, outputs=[btn, gr.State(), gr.State(), gr.State()])
146
+ # TODO: await download of sample before allowing playback
147
+
148
  # Allow interaction with the vote buttons only when both audio samples have finished playing
149
  aud1\
150
  .stop(
 
168
  aud2.stop(None, inputs=[aplayed], js="(a) => a ? "+ unblur_text_js +" : 0;")
169
 
170
  nxt_outputs = [abetter, bbetter, prevmodel1, prevmodel2, nxtroundbtn]
171
+ abetter\
172
+ .click(a_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate, text])\
173
+ .then(voted_on_cached, inputs=[model1, model2, text, session_hash], outputs=[])
174
+ bbetter\
175
+ .click(b_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate, text])\
176
+ .then(voted_on_cached, inputs=[model1, model2, text, session_hash], outputs=[])
177
+
178
+ # get session cookie
179
+ vote\
180
+ .load(
181
+ None,
182
+ None,
183
+ session_hash,
184
+ js="() => { return getArenaCookie('session') }",
185
+ )
186
+ # give a cached sample pair to voter; .then() did not work here
187
+ vote\
188
+ .load(give_cached_sample, inputs=[session_hash, autoplay], outputs=[*outputs, cachedt])
app/vote.py CHANGED
@@ -60,56 +60,68 @@ def b_is_better_battle(model1, model2, userid):
60
 
61
  # A/B better
62
 
63
- def a_is_better(model1, model2, userid, battle=False):
64
- print("A is better", model1, model2)
65
- if not model1 in AVAILABLE_MODELS.keys() and not model1 in AVAILABLE_MODELS.values():
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  raise gr.Error('Sorry, please try voting again.')
 
 
67
  userid = mkuuid(userid)
68
  if model1 and model2:
69
  conn = get_db()
70
  cursor = conn.cursor()
71
- cursor.execute('INSERT INTO votelog (username, chosen, rejected) VALUES (?, ?, ?)', (str(userid), model1, model2,))
72
- if scheduler:
73
- with scheduler.lock:
74
- conn.commit()
75
  else:
 
 
 
76
  conn.commit()
77
- cursor.close()
78
- upvote_model(model1, str(userid), battle)
79
- downvote_model(model2, str(userid), battle)
80
- return reload(model1, model2, userid, chose_a=True)
81
- def b_is_better(model1, model2, userid, battle=False):
82
- print("B is better", model1, model2)
83
- if not model1 in AVAILABLE_MODELS.keys() and not model1 in AVAILABLE_MODELS.values():
84
- raise gr.Error('Sorry, please try voting again.')
85
- userid = mkuuid(userid)
86
- if model1 and model2:
87
- conn = get_db()
88
- cursor = conn.cursor()
89
- cursor.execute('INSERT INTO votelog (username, chosen, rejected) VALUES (?, ?, ?)', (str(userid), model2, model1,))
90
- if scheduler:
91
- with scheduler.lock:
92
- conn.commit()
93
  else:
94
- conn.commit()
95
- cursor.close()
96
- upvote_model(model2, str(userid), battle)
97
- downvote_model(model1, str(userid), battle)
98
- return reload(model1, model2, userid, chose_b=True)
99
 
100
- # Reload
101
 
 
102
  def reload(chosenmodel1=None, chosenmodel2=None, userid=None, chose_a=False, chose_b=False):
 
 
103
  out = [
104
  gr.update(interactive=False, visible=False),
105
  gr.update(interactive=False, visible=False)
106
  ]
 
107
  if chose_a == True:
108
- out.append(gr.update(value=f'Your vote: {chosenmodel1}', interactive=False, visible=True))
109
- out.append(gr.update(value=f'{chosenmodel2}', interactive=False, visible=True))
110
  else:
111
- out.append(gr.update(value=f'{chosenmodel1}', interactive=False, visible=True))
112
- out.append(gr.update(value=f'Your vote: {chosenmodel2}', interactive=False, visible=True))
113
  out.append(gr.update(visible=True))
114
  return out
115
 
 
60
 
61
  # A/B better
62
 
63
+ def a_is_better(model1, model2, userid, text):
64
+ return is_better(model1, model2, userid, text, True)
65
+ def b_is_better(model1, model2, userid, text):
66
+ return is_better(model1, model2, userid, text, False)
67
+
68
+ def is_better(model1, model2, userid, text, chose_a):
69
+ if(
70
+ (
71
+ not model1 in AVAILABLE_MODELS.keys()
72
+ and not model1 in AVAILABLE_MODELS.values()
73
+ )
74
+ or (
75
+ not model2 in AVAILABLE_MODELS.keys()
76
+ and not model2 in AVAILABLE_MODELS.values()
77
+ )
78
+ ):
79
  raise gr.Error('Sorry, please try voting again.')
80
+
81
+ # userid is unique for each cast vote pair
82
  userid = mkuuid(userid)
83
  if model1 and model2:
84
  conn = get_db()
85
  cursor = conn.cursor()
86
+ sql_query = 'INSERT INTO votelog (username, chosen, rejected) VALUES (?, ?, ?)'
87
+ if chose_a:
88
+ cursor.execute(sql_query, (str(userid), model1, model2))
 
89
  else:
90
+ cursor.execute(sql_query, (str(userid), model2, model1))
91
+
92
+ with scheduler.lock:
93
  conn.commit()
94
+ # also retrieve primary key ID
95
+ cursor.execute('SELECT last_insert_rowid()')
96
+ votelogid = cursor.fetchone()[0]
97
+ cursor.close()
98
+
99
+ if chose_a:
100
+ upvote_model(model1, str(userid))
101
+ downvote_model(model2, str(userid))
 
 
 
 
 
 
 
 
102
  else:
103
+ upvote_model(model2, str(userid))
104
+ downvote_model(model1, str(userid))
105
+ log_text(text)
106
+ # log_text(text, votelogid)
 
107
 
108
+ return reload(model1, model2, userid, chose_a=chose_a, chose_b=(not chose_a))
109
 
110
+ # Reload
111
  def reload(chosenmodel1=None, chosenmodel2=None, userid=None, chose_a=False, chose_b=False):
112
+ # chosenmodel1 = make_link_to_space(chosenmodel1)
113
+ # chosenmodel2 = make_link_to_space(chosenmodel2)
114
  out = [
115
  gr.update(interactive=False, visible=False),
116
  gr.update(interactive=False, visible=False)
117
  ]
118
+ style = 'text-align: center; font-size: 1rem; margin-bottom: 0; padding: var(--input-padding)'
119
  if chose_a == True:
120
+ out.append(gr.update(value=f'<p style="{style}">Your vote: {chosenmodel1}</p>', visible=True))
121
+ out.append(gr.update(value=f'<p style="{style}">{chosenmodel2}</p>', visible=True))
122
  else:
123
+ out.append(gr.update(value=f'<p style="{style}">{chosenmodel1}</p>', visible=True))
124
+ out.append(gr.update(value=f'<p style="{style}">Your vote: {chosenmodel2}</p>', visible=True))
125
  out.append(gr.update(visible=True))
126
  return out
127