Spaces:
Running
Running
Commit ·
723e020
1
Parent(s): e30c292
refined control styles
Browse files- app.py +62 -27
- web/score-player.css +1 -1
app.py
CHANGED
|
@@ -203,17 +203,19 @@ def _log_panel (raw=''):
|
|
| 203 |
return sys_log
|
| 204 |
|
| 205 |
|
| 206 |
-
def run_generation (prompt, measures, temperature, max_patches, seed, store, top_k=0, top_p=0.9
|
| 207 |
-
|
| 208 |
-
'''Streaming generate callback. Yields updates for (log, editor, file_list, store, seed).
|
| 209 |
|
| 210 |
store: {label: lyl_text} dict held in gr.State; the produced document is added
|
| 211 |
to it under a timestamped label once generation finishes.
|
| 212 |
|
| 213 |
top_k / top_p have fixed defaults (no UI controls); pass them explicitly to override.
|
| 214 |
|
| 215 |
-
|
| 216 |
-
|
|
|
|
|
|
|
|
|
|
| 217 |
|
| 218 |
The output file is named with the seed used for THIS generation; on completion
|
| 219 |
the seed slider is randomized (final yield) so the next click uses a fresh seed.
|
|
@@ -227,7 +229,6 @@ def run_generation (prompt, measures, temperature, max_patches, seed, store, top
|
|
| 227 |
n_yields = 0
|
| 228 |
mp = int(max_patches)
|
| 229 |
t0 = time.perf_counter()
|
| 230 |
-
progress(0.0, desc='Starting…')
|
| 231 |
try:
|
| 232 |
gen = get_generator()
|
| 233 |
# drop a marker in the log timeline; _log_panel expands it to the live output,
|
|
@@ -238,25 +239,22 @@ def run_generation (prompt, measures, temperature, max_patches, seed, store, top
|
|
| 238 |
top_k=int(top_k), top_p=float(top_p), measures=meas, seed=int(seed)):
|
| 239 |
if not done:
|
| 240 |
n_yields += 1
|
| 241 |
-
# progress: by measures (
|
| 242 |
-
# measure count was requested, else by
|
| 243 |
if meas:
|
| 244 |
-
|
| 245 |
-
desc = 'measure %d/%d' % (min(raw.count('|'), meas), meas)
|
| 246 |
else:
|
| 247 |
-
|
| 248 |
-
desc = 'patch %d/%d' % (max(0, n_yields - 1), mp)
|
| 249 |
-
progress(min(frac, 0.99) if not done else 1.0, desc=desc)
|
| 250 |
# The log streams every patch (raw text). The editor, however, must stay
|
| 251 |
# syntactically valid: only sync it at a measure boundary — i.e. when the
|
| 252 |
# accumulated text ends with the measure separator `|` (so it never shows a
|
| 253 |
# half-generated, incomplete measure). `done` forces a final sync.
|
| 254 |
at_boundary = raw.rstrip().endswith('|')
|
| 255 |
editor_update = pretty if (at_boundary or done) else gr.update()
|
| 256 |
-
yield _log_panel(raw), editor_update, gr.update(), store, gr.update()
|
| 257 |
except Exception as e:
|
| 258 |
LOG.exception('generation failed: %s', e)
|
| 259 |
-
yield _log_panel(raw), pretty, gr.update(), store, gr.update()
|
| 260 |
return
|
| 261 |
|
| 262 |
# timing: the stream yields once for prefill + once per generated patch, so the
|
|
@@ -278,7 +276,7 @@ def run_generation (prompt, measures, temperature, max_patches, seed, store, top
|
|
| 278 |
# randomize the seed slider for the next run (the file above already used the
|
| 279 |
# seed this generation ran with, so naming is unaffected)
|
| 280 |
next_seed = random.randint(0, 2147483647)
|
| 281 |
-
yield _log_panel(raw), pretty, gr.update(choices=list(store.keys()), value=label), store, gr.update(value=next_seed)
|
| 282 |
|
| 283 |
|
| 284 |
def load_file (label, store):
|
|
@@ -361,11 +359,25 @@ function (text) {
|
|
| 361 |
# must return its args unchanged — returning nothing makes Gradio send null for
|
| 362 |
# every input (which breaks e.g. the temperature Slider's preprocessor).
|
| 363 |
_JS_GEN_START = '''
|
| 364 |
-
function (...args) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
'''
|
| 366 |
|
| 367 |
_JS_GEN_END = '''
|
| 368 |
-
function () {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
'''
|
| 370 |
|
| 371 |
|
|
@@ -390,6 +402,25 @@ CUSTOM_CSS = '''
|
|
| 390 |
max-height: 324px;
|
| 391 |
overflow-y: auto;
|
| 392 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 393 |
'''
|
| 394 |
|
| 395 |
|
|
@@ -423,8 +454,8 @@ def build_ui ():
|
|
| 423 |
max_patches = gr.Number(label='max patches', value=1024, precision=0)
|
| 424 |
seed = gr.Slider(0, 2147483647, value=42, step=1, label='seed')
|
| 425 |
with gr.Row():
|
| 426 |
-
gen_btn = gr.Button('Generate', variant='primary')
|
| 427 |
-
stop_btn = gr.Button('Stop', variant='stop')
|
| 428 |
|
| 429 |
with gr.Accordion('Logs', open=True):
|
| 430 |
log = gr.Textbox(show_label=False, lines=10, max_lines=10,
|
|
@@ -465,12 +496,12 @@ def build_ui ():
|
|
| 465 |
gen_event = gen_btn.click(
|
| 466 |
run_generation,
|
| 467 |
inputs=[prompt, measures, temperature, max_patches, seed, store],
|
| 468 |
-
outputs=[log, editor, file_list, store, seed],
|
| 469 |
js=_JS_GEN_START,
|
| 470 |
-
#
|
| 471 |
-
#
|
| 472 |
-
#
|
| 473 |
-
show_progress='
|
| 474 |
)
|
| 475 |
gen_event.then(None, None, None, js=_JS_GEN_END)
|
| 476 |
|
|
@@ -479,8 +510,12 @@ def build_ui ():
|
|
| 479 |
# virtualises long docs in the DOM, so scraping it client-side truncates).
|
| 480 |
editor.change(None, inputs=[editor], outputs=None, js=_JS_RENDER)
|
| 481 |
|
| 482 |
-
# Stop: cancel generation,
|
| 483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
file_list.select(load_file, inputs=[file_list, store], outputs=[editor])
|
| 485 |
|
| 486 |
return demo
|
|
|
|
| 203 |
return sys_log
|
| 204 |
|
| 205 |
|
| 206 |
+
def run_generation (prompt, measures, temperature, max_patches, seed, store, top_k=0, top_p=0.9):
|
| 207 |
+
'''Streaming generate callback. Yields updates for (log, editor, file_list, store, seed, gen_btn).
|
|
|
|
| 208 |
|
| 209 |
store: {label: lyl_text} dict held in gr.State; the produced document is added
|
| 210 |
to it under a timestamped label once generation finishes.
|
| 211 |
|
| 212 |
top_k / top_p have fixed defaults (no UI controls); pass them explicitly to override.
|
| 213 |
|
| 214 |
+
Progress is shown on the Generate button itself: its label becomes
|
| 215 |
+
"Generating… M/N" (by completed measures when a measure count is requested, else
|
| 216 |
+
by patches out of max_patches) during the run, and reverts to "Generate" at the
|
| 217 |
+
end. (Gradio's native progress bar can't render on a Button, so we drive the
|
| 218 |
+
label directly.)
|
| 219 |
|
| 220 |
The output file is named with the seed used for THIS generation; on completion
|
| 221 |
the seed slider is randomized (final yield) so the next click uses a fresh seed.
|
|
|
|
| 229 |
n_yields = 0
|
| 230 |
mp = int(max_patches)
|
| 231 |
t0 = time.perf_counter()
|
|
|
|
| 232 |
try:
|
| 233 |
gen = get_generator()
|
| 234 |
# drop a marker in the log timeline; _log_panel expands it to the live output,
|
|
|
|
| 239 |
top_k=int(top_k), top_p=float(top_p), measures=meas, seed=int(seed)):
|
| 240 |
if not done:
|
| 241 |
n_yields += 1
|
| 242 |
+
# progress on the Generate button label: by measures (completed `|`
|
| 243 |
+
# separators vs target) when a measure count was requested, else by patches.
|
| 244 |
if meas:
|
| 245 |
+
btn_label = 'Generating… %d/%d' % (min(raw.count('|'), meas), meas)
|
|
|
|
| 246 |
else:
|
| 247 |
+
btn_label = 'Generating… %d/%d' % (max(0, n_yields - 1), mp)
|
|
|
|
|
|
|
| 248 |
# The log streams every patch (raw text). The editor, however, must stay
|
| 249 |
# syntactically valid: only sync it at a measure boundary — i.e. when the
|
| 250 |
# accumulated text ends with the measure separator `|` (so it never shows a
|
| 251 |
# half-generated, incomplete measure). `done` forces a final sync.
|
| 252 |
at_boundary = raw.rstrip().endswith('|')
|
| 253 |
editor_update = pretty if (at_boundary or done) else gr.update()
|
| 254 |
+
yield _log_panel(raw), editor_update, gr.update(), store, gr.update(), gr.update(value=btn_label)
|
| 255 |
except Exception as e:
|
| 256 |
LOG.exception('generation failed: %s', e)
|
| 257 |
+
yield _log_panel(raw), pretty, gr.update(), store, gr.update(), gr.update(value='Generate')
|
| 258 |
return
|
| 259 |
|
| 260 |
# timing: the stream yields once for prefill + once per generated patch, so the
|
|
|
|
| 276 |
# randomize the seed slider for the next run (the file above already used the
|
| 277 |
# seed this generation ran with, so naming is unaffected)
|
| 278 |
next_seed = random.randint(0, 2147483647)
|
| 279 |
+
yield _log_panel(raw), pretty, gr.update(choices=list(store.keys()), value=label), store, gr.update(value=next_seed), gr.update(value='Generate')
|
| 280 |
|
| 281 |
|
| 282 |
def load_file (label, store):
|
|
|
|
| 359 |
# must return its args unchanged — returning nothing makes Gradio send null for
|
| 360 |
# every input (which breaks e.g. the temperature Slider's preprocessor).
|
| 361 |
_JS_GEN_START = '''
|
| 362 |
+
function (...args) {
|
| 363 |
+
if (window.LilyScore) window.LilyScore.setGenerating(true);
|
| 364 |
+
// turn Generate yellow + Stop red while running
|
| 365 |
+
['gen-btn', 'stop-btn'].forEach(function (idv) {
|
| 366 |
+
const b = document.getElementById(idv);
|
| 367 |
+
if (b) b.classList.add('ls-generating');
|
| 368 |
+
});
|
| 369 |
+
return args;
|
| 370 |
+
}
|
| 371 |
'''
|
| 372 |
|
| 373 |
_JS_GEN_END = '''
|
| 374 |
+
function () {
|
| 375 |
+
if (window.LilyScore) window.LilyScore.setGenerating(false);
|
| 376 |
+
['gen-btn', 'stop-btn'].forEach(function (idv) {
|
| 377 |
+
const b = document.getElementById(idv);
|
| 378 |
+
if (b) b.classList.remove('ls-generating');
|
| 379 |
+
});
|
| 380 |
+
}
|
| 381 |
'''
|
| 382 |
|
| 383 |
|
|
|
|
| 402 |
max-height: 324px;
|
| 403 |
overflow-y: auto;
|
| 404 |
}
|
| 405 |
+
/* Generate button turns yellow while a generation is running (the .ls-generating
|
| 406 |
+
class is toggled by the generation-gate js). !important beats the primary variant. */
|
| 407 |
+
#gen-btn.ls-generating {
|
| 408 |
+
background: #f5c518 !important;
|
| 409 |
+
background-image: none !important;
|
| 410 |
+
border-color: #d4a800 !important;
|
| 411 |
+
color: #3a2f00 !important;
|
| 412 |
+
}
|
| 413 |
+
/* Stop button: grey by default (theme look), solid red only while generating
|
| 414 |
+
(the .ls-generating class is toggled by the generation-gate js). */
|
| 415 |
+
#stop-btn.ls-generating {
|
| 416 |
+
background: #e23b3b !important;
|
| 417 |
+
background-image: none !important;
|
| 418 |
+
border-color: #c42b2b !important;
|
| 419 |
+
color: #fff !important;
|
| 420 |
+
}
|
| 421 |
+
#stop-btn.ls-generating:hover {
|
| 422 |
+
background: #cf2e2e !important;
|
| 423 |
+
}
|
| 424 |
'''
|
| 425 |
|
| 426 |
|
|
|
|
| 454 |
max_patches = gr.Number(label='max patches', value=1024, precision=0)
|
| 455 |
seed = gr.Slider(0, 2147483647, value=42, step=1, label='seed')
|
| 456 |
with gr.Row():
|
| 457 |
+
gen_btn = gr.Button('Generate', variant='primary', elem_id='gen-btn')
|
| 458 |
+
stop_btn = gr.Button('Stop', variant='stop', elem_id='stop-btn')
|
| 459 |
|
| 460 |
with gr.Accordion('Logs', open=True):
|
| 461 |
log = gr.Textbox(show_label=False, lines=10, max_lines=10,
|
|
|
|
| 496 |
gen_event = gen_btn.click(
|
| 497 |
run_generation,
|
| 498 |
inputs=[prompt, measures, temperature, max_patches, seed, store],
|
| 499 |
+
outputs=[log, editor, file_list, store, seed, gen_btn],
|
| 500 |
js=_JS_GEN_START,
|
| 501 |
+
# progress is shown on the Generate button's own label ("Generating… M/N"),
|
| 502 |
+
# driven by run_generation. Hide Gradio's native progress overlay (it can't
|
| 503 |
+
# render on a Button and otherwise covers the Logs/editor outputs).
|
| 504 |
+
show_progress='hidden',
|
| 505 |
)
|
| 506 |
gen_event.then(None, None, None, js=_JS_GEN_END)
|
| 507 |
|
|
|
|
| 510 |
# virtualises long docs in the DOM, so scraping it client-side truncates).
|
| 511 |
editor.change(None, inputs=[editor], outputs=None, js=_JS_RENDER)
|
| 512 |
|
| 513 |
+
# Stop: cancel generation, reset the Generate button label (the cancelled
|
| 514 |
+
# run never reaches its final yield, so it'd otherwise stay "Generating…"),
|
| 515 |
+
# then lift the gate (js) so the player returns + button colors revert.
|
| 516 |
+
stop_btn.click(
|
| 517 |
+
lambda: gr.update(value='Generate'), None, outputs=[gen_btn], cancels=[gen_event],
|
| 518 |
+
).then(None, None, None, js=_JS_GEN_END)
|
| 519 |
file_list.select(load_file, inputs=[file_list, store], outputs=[editor])
|
| 520 |
|
| 521 |
return demo
|
web/score-player.css
CHANGED
|
@@ -27,7 +27,7 @@
|
|
| 27 |
.ls-status.ls-err { color: #c0392b; }
|
| 28 |
|
| 29 |
.ls-svg {
|
| 30 |
-
background: #
|
| 31 |
display: inline-block;
|
| 32 |
min-width: 100%;
|
| 33 |
}
|
|
|
|
| 27 |
.ls-status.ls-err { color: #c0392b; }
|
| 28 |
|
| 29 |
.ls-svg {
|
| 30 |
+
background: #fffdf2; /* faint warm/yellow tint behind the score */
|
| 31 |
display: inline-block;
|
| 32 |
min-width: 100%;
|
| 33 |
}
|