Spaces:
Running
Running
fixed cached
Browse files
app.py
CHANGED
@@ -15,7 +15,7 @@ import tempfile
|
|
15 |
from pydub import AudioSegment
|
16 |
import itertools
|
17 |
from typing import List, Tuple, Set, Dict
|
18 |
-
from hashlib import sha1
|
19 |
|
20 |
class User:
|
21 |
def __init__(self, user_id: str):
|
@@ -415,7 +415,7 @@ INSTR = """
|
|
415 |
## 🗳️ Vote
|
416 |
|
417 |
* Input text (English only) to synthesize audio.
|
418 |
-
* Press ⚡ to
|
419 |
* Press 🎲 to randomly select text for a list. Slow.
|
420 |
* Listen to the two audio clips, one after the other.
|
421 |
* Vote on which audio sounds more natural to you.
|
@@ -1029,6 +1029,10 @@ def synthandreturn(text):
|
|
1029 |
|
1030 |
# cache the result
|
1031 |
for model in [mdl1k, mdl2k]:
|
|
|
|
|
|
|
|
|
1032 |
already_cached = False
|
1033 |
# check if already cached
|
1034 |
for cached_sample in cached_samples:
|
@@ -1040,12 +1044,9 @@ def synthandreturn(text):
|
|
1040 |
if (already_cached):
|
1041 |
continue
|
1042 |
|
1043 |
-
print(f"Cached {model}")
|
1044 |
cached_samples.append(Sample(results[model], text, model))
|
1045 |
-
# print(cached_samples)
|
1046 |
|
1047 |
-
all_pairs = generate_matching_pairs(cached_samples)
|
1048 |
-
# print(all_pairs)
|
1049 |
|
1050 |
print(f"Retrieving models {mdl1k} and {mdl2k} from API")
|
1051 |
return (
|
@@ -1116,31 +1117,42 @@ def unlock_vote(btn_index, aplayed, bplayed):
|
|
1116 |
|
1117 |
return [gr.update(), gr.update(), aplayed, bplayed, aud2]
|
1118 |
|
1119 |
-
|
1120 |
-
def cachedsent(request: gr.Request):
|
1121 |
-
# add new userid to voting_users from Browser session hash
|
1122 |
-
# stored only in RAM
|
1123 |
if request.username:
|
1124 |
print('auth by username')
|
1125 |
# by HuggingFace username
|
1126 |
-
|
1127 |
else:
|
1128 |
print('auth by ip')
|
1129 |
# by IP address
|
1130 |
-
|
1131 |
# by browser session hash
|
1132 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1133 |
|
1134 |
if userid not in voting_users:
|
1135 |
voting_users[userid] = User(userid)
|
1136 |
|
1137 |
def get_next_pair(user: User):
|
|
|
1138 |
# all_pairs = generate_matching_pairs(cached_samples)
|
1139 |
|
1140 |
# for pair in all_pairs:
|
1141 |
for pair in generate_matching_pairs(cached_samples):
|
1142 |
-
|
1143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1144 |
return pair
|
1145 |
return None
|
1146 |
|
@@ -1148,8 +1160,6 @@ def cachedsent(request: gr.Request):
|
|
1148 |
if pair is None:
|
1149 |
return [*clear_stuff(), gr.update(interactive=False)]
|
1150 |
|
1151 |
-
# TODO: move to abisbetter
|
1152 |
-
voting_users[userid].voted_pairs.add((pair[0].filename, pair[1].filename))
|
1153 |
return (
|
1154 |
pair[0].transcript,
|
1155 |
"Synthesize",
|
@@ -1164,11 +1174,23 @@ def cachedsent(request: gr.Request):
|
|
1164 |
gr.update(visible=False), #prevmodel2
|
1165 |
gr.update(visible=False), #nxt round btn
|
1166 |
# reset aplayed, bplayed audio playback events
|
1167 |
-
|
1168 |
-
|
1169 |
# fetch cached btn
|
1170 |
gr.update(interactive=True)
|
1171 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1172 |
def randomsent():
|
1173 |
return '⚡', random.choice(sents), '🎲'
|
1174 |
def clear_stuff():
|
@@ -1178,8 +1200,8 @@ def clear_stuff():
|
|
1178 |
gr.update(visible=False), # r2
|
1179 |
'', # model1
|
1180 |
'', # model2
|
1181 |
-
gr.update(visible=False, autoplay=False), # aud1
|
1182 |
-
gr.update(visible=False, autoplay=False), # aud2
|
1183 |
gr.update(visible=False, interactive=False), #abetter
|
1184 |
gr.update(visible=False, interactive=False), #bbetter
|
1185 |
gr.update(visible=False), #prevmodel1
|
@@ -1190,9 +1212,9 @@ def clear_stuff():
|
|
1190 |
]
|
1191 |
|
1192 |
def disable():
|
1193 |
-
return [gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False)]
|
1194 |
def enable():
|
1195 |
-
return [gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True)]
|
1196 |
with gr.Blocks() as vote:
|
1197 |
# sample played
|
1198 |
aplayed = gr.State(value=False)
|
@@ -1202,7 +1224,7 @@ with gr.Blocks() as vote:
|
|
1202 |
gr.Markdown(INSTR)
|
1203 |
with gr.Group():
|
1204 |
with gr.Row():
|
1205 |
-
cachedt = gr.Button('⚡', scale=0, min_width=0, variant='tool', interactive=
|
1206 |
text = gr.Textbox(container=False, show_label=False, placeholder="Enter text to synthesize", lines=1, max_lines=1, scale=9999999, min_width=0)
|
1207 |
randomt = gr.Button('🎲', scale=0, min_width=0, variant='tool')
|
1208 |
randomt.click(randomsent, outputs=[cachedt, text, randomt])
|
@@ -1267,11 +1289,17 @@ with gr.Blocks() as vote:
|
|
1267 |
gr.update(visible=False), #prevmodel1
|
1268 |
gr.update(visible=False), #prevmodel2
|
1269 |
gr.update(visible=False), #nxt round btn"""
|
1270 |
-
btn
|
1271 |
-
|
|
|
|
|
|
|
1272 |
|
1273 |
# fetch a comparison pair from cache
|
1274 |
-
cachedt
|
|
|
|
|
|
|
1275 |
|
1276 |
# Allow interaction with the vote buttons only when both audio samples have finished playing
|
1277 |
aud1.stop(unlock_vote, outputs=[abetter, bbetter, aplayed, bplayed, aud2], inputs=[gr.State(value=0), aplayed, bplayed])
|
@@ -1280,8 +1308,12 @@ with gr.Blocks() as vote:
|
|
1280 |
|
1281 |
# nxt_outputs = [prevmodel1, prevmodel2, abetter, bbetter]
|
1282 |
nxt_outputs = [abetter, bbetter, prevmodel1, prevmodel2, nxtroundbtn]
|
1283 |
-
abetter
|
1284 |
-
|
|
|
|
|
|
|
|
|
1285 |
# skipbtn.click(b_is_better, outputs=outputs, inputs=[model1, model2, useridstate])
|
1286 |
|
1287 |
# bothbad.click(both_bad, outputs=outputs, inputs=[model1, model2, useridstate])
|
|
|
15 |
from pydub import AudioSegment
|
16 |
import itertools
|
17 |
from typing import List, Tuple, Set, Dict
|
18 |
+
from hashlib import md5, sha1
|
19 |
|
20 |
class User:
|
21 |
def __init__(self, user_id: str):
|
|
|
415 |
## 🗳️ Vote
|
416 |
|
417 |
* Input text (English only) to synthesize audio.
|
418 |
+
* Press ⚡ to get cached samples you have yet to vote on. Fast.
|
419 |
* Press 🎲 to randomly select text for a list. Slow.
|
420 |
* Listen to the two audio clips, one after the other.
|
421 |
* Vote on which audio sounds more natural to you.
|
|
|
1029 |
|
1030 |
# cache the result
|
1031 |
for model in [mdl1k, mdl2k]:
|
1032 |
+
# skip caching if not hardcoded sentence
|
1033 |
+
if (text not in sents):
|
1034 |
+
break
|
1035 |
+
|
1036 |
already_cached = False
|
1037 |
# check if already cached
|
1038 |
for cached_sample in cached_samples:
|
|
|
1044 |
if (already_cached):
|
1045 |
continue
|
1046 |
|
|
|
1047 |
cached_samples.append(Sample(results[model], text, model))
|
|
|
1048 |
|
1049 |
+
# all_pairs = generate_matching_pairs(cached_samples)
|
|
|
1050 |
|
1051 |
print(f"Retrieving models {mdl1k} and {mdl2k} from API")
|
1052 |
return (
|
|
|
1117 |
|
1118 |
return [gr.update(), gr.update(), aplayed, bplayed, aud2]
|
1119 |
|
1120 |
+
def get_userid(request: gr.Request):
|
|
|
|
|
|
|
1121 |
if request.username:
|
1122 |
print('auth by username')
|
1123 |
# by HuggingFace username
|
1124 |
+
return sha1(bytes(request.username.encode('ascii'))).hexdigest()
|
1125 |
else:
|
1126 |
print('auth by ip')
|
1127 |
# by IP address
|
1128 |
+
return sha1(bytes(request.client.host.encode('ascii'))).hexdigest()
|
1129 |
# by browser session hash
|
1130 |
+
# Issue: Not a cookie, session hash changes on page reload
|
1131 |
+
# return sha1(bytes(request.session_hash.encode('ascii')), usedforsecurity=False).hexdigest()
|
1132 |
+
|
1133 |
+
# Give user a cached audio sample pair they have yet to vote on
|
1134 |
+
def give_cached_sample(request: gr.Request):
|
1135 |
+
# add new userid to voting_users from Browser session hash
|
1136 |
+
# stored only in RAM
|
1137 |
+
userid = get_userid(request)
|
1138 |
|
1139 |
if userid not in voting_users:
|
1140 |
voting_users[userid] = User(userid)
|
1141 |
|
1142 |
def get_next_pair(user: User):
|
1143 |
+
# FIXME: all_pairs var out of scope
|
1144 |
# all_pairs = generate_matching_pairs(cached_samples)
|
1145 |
|
1146 |
# for pair in all_pairs:
|
1147 |
for pair in generate_matching_pairs(cached_samples):
|
1148 |
+
hash1 = md5(bytes((pair[0].modelName + pair[0].transcript).encode('ascii'))).hexdigest()
|
1149 |
+
hash2 = md5(bytes((pair[1].modelName + pair[1].transcript).encode('ascii'))).hexdigest()
|
1150 |
+
pair_key = (hash1, hash2)
|
1151 |
+
if (
|
1152 |
+
pair_key not in user.voted_pairs
|
1153 |
+
# or in reversed order
|
1154 |
+
and (pair_key[1], pair_key[0]) not in user.voted_pairs
|
1155 |
+
):
|
1156 |
return pair
|
1157 |
return None
|
1158 |
|
|
|
1160 |
if pair is None:
|
1161 |
return [*clear_stuff(), gr.update(interactive=False)]
|
1162 |
|
|
|
|
|
1163 |
return (
|
1164 |
pair[0].transcript,
|
1165 |
"Synthesize",
|
|
|
1174 |
gr.update(visible=False), #prevmodel2
|
1175 |
gr.update(visible=False), #nxt round btn
|
1176 |
# reset aplayed, bplayed audio playback events
|
1177 |
+
False, #aplayed
|
1178 |
+
False, #bplayed
|
1179 |
# fetch cached btn
|
1180 |
gr.update(interactive=True)
|
1181 |
)
|
1182 |
+
|
1183 |
+
# note the vote on cached sample pair
|
1184 |
+
def voted_on_cached(modelName1: str, modelName2: str, transcript: str, request: gr.Request):
|
1185 |
+
userid = get_userid(request)
|
1186 |
+
if userid not in voting_users:
|
1187 |
+
voting_users[userid] = User(userid)
|
1188 |
+
|
1189 |
+
hash1 = md5(bytes((modelName1 + transcript).encode('ascii'))).hexdigest()
|
1190 |
+
hash2 = md5(bytes((modelName2 + transcript).encode('ascii'))).hexdigest()
|
1191 |
+
|
1192 |
+
voting_users[userid].voted_pairs.add((hash1, hash2))
|
1193 |
+
|
1194 |
def randomsent():
|
1195 |
return '⚡', random.choice(sents), '🎲'
|
1196 |
def clear_stuff():
|
|
|
1200 |
gr.update(visible=False), # r2
|
1201 |
'', # model1
|
1202 |
'', # model2
|
1203 |
+
gr.update(visible=False, interactive=False, autoplay=False), # aud1
|
1204 |
+
gr.update(visible=False, interactive=False, autoplay=False), # aud2
|
1205 |
gr.update(visible=False, interactive=False), #abetter
|
1206 |
gr.update(visible=False, interactive=False), #bbetter
|
1207 |
gr.update(visible=False), #prevmodel1
|
|
|
1212 |
]
|
1213 |
|
1214 |
def disable():
|
1215 |
+
return [gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=False)]
|
1216 |
def enable():
|
1217 |
+
return [gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=True)]
|
1218 |
with gr.Blocks() as vote:
|
1219 |
# sample played
|
1220 |
aplayed = gr.State(value=False)
|
|
|
1224 |
gr.Markdown(INSTR)
|
1225 |
with gr.Group():
|
1226 |
with gr.Row():
|
1227 |
+
cachedt = gr.Button('⚡', scale=0, min_width=0, variant='tool', interactive=True)
|
1228 |
text = gr.Textbox(container=False, show_label=False, placeholder="Enter text to synthesize", lines=1, max_lines=1, scale=9999999, min_width=0)
|
1229 |
randomt = gr.Button('🎲', scale=0, min_width=0, variant='tool')
|
1230 |
randomt.click(randomsent, outputs=[cachedt, text, randomt])
|
|
|
1289 |
gr.update(visible=False), #prevmodel1
|
1290 |
gr.update(visible=False), #prevmodel2
|
1291 |
gr.update(visible=False), #nxt round btn"""
|
1292 |
+
btn\
|
1293 |
+
.click(disable, outputs=[btn, abetter, bbetter, cachedt])\
|
1294 |
+
.then(synthandreturn, inputs=[text], outputs=outputs)\
|
1295 |
+
.then(enable, outputs=[btn, gr.State(), gr.State(), cachedt])
|
1296 |
+
nxtroundbtn.click(give_cached_sample, outputs=[*outputs, cachedt])
|
1297 |
|
1298 |
# fetch a comparison pair from cache
|
1299 |
+
cachedt\
|
1300 |
+
.click(disable, outputs=[btn, abetter, bbetter, cachedt])\
|
1301 |
+
.then(give_cached_sample, outputs=[*outputs, cachedt])\
|
1302 |
+
.then(enable, outputs=[btn, gr.State(), gr.State(), cachedt])
|
1303 |
|
1304 |
# Allow interaction with the vote buttons only when both audio samples have finished playing
|
1305 |
aud1.stop(unlock_vote, outputs=[abetter, bbetter, aplayed, bplayed, aud2], inputs=[gr.State(value=0), aplayed, bplayed])
|
|
|
1308 |
|
1309 |
# nxt_outputs = [prevmodel1, prevmodel2, abetter, bbetter]
|
1310 |
nxt_outputs = [abetter, bbetter, prevmodel1, prevmodel2, nxtroundbtn]
|
1311 |
+
abetter\
|
1312 |
+
.click(a_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate])\
|
1313 |
+
.then(voted_on_cached, inputs=[model1, model2, text])
|
1314 |
+
bbetter\
|
1315 |
+
.click(b_is_better, outputs=nxt_outputs, inputs=[model1, model2, useridstate])\
|
1316 |
+
.then(voted_on_cached, inputs=[model1, model2, text])
|
1317 |
# skipbtn.click(b_is_better, outputs=outputs, inputs=[model1, model2, useridstate])
|
1318 |
|
1319 |
# bothbad.click(both_bad, outputs=outputs, inputs=[model1, model2, useridstate])
|