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])
|