Spaces:
Running on Zero
Running on Zero
feat(ui): expand tooltips.py + apply info= to cover/extend/edit/lyrics tabs
Browse filesAdds COVER_*, EXTEND_*, EDIT_*, LYRICS_*, LORA_*, and POST_* tooltip
strings to the central tooltips module and wires them into the
corresponding ui.py builders. gr.Audio / gr.File widgets don't accept
info= in Gradio 6.14 — those are skipped (visible labels carry the
intent already). gr.Button likewise has no info= so the post-process
action row keeps its descriptive button labels as the affordance.
- tooltips.py +45 -0
- ui.py +22 -6
tooltips.py
CHANGED
|
@@ -1,6 +1,51 @@
|
|
| 1 |
"""Centralised tooltip / `info=` strings — single source of truth."""
|
| 2 |
|
|
|
|
| 3 |
GENERATE_PROMPT = "Describe the song. Genre, instruments, tempo, mood."
|
| 4 |
GENERATE_LYRICS = "Use [verse] [chorus] [bridge] tags. Open the Lyrics tab to draft with Qwen 2.5."
|
| 5 |
GENERATE_DURATION = "Output length in seconds. Longer outputs cost more compute."
|
| 6 |
GENERATE_VOCAL = "With vocals: full song. Instrumental: no singing, just music."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
"""Centralised tooltip / `info=` strings — single source of truth."""
|
| 2 |
|
| 3 |
+
# --- Generate tab ---
|
| 4 |
GENERATE_PROMPT = "Describe the song. Genre, instruments, tempo, mood."
|
| 5 |
GENERATE_LYRICS = "Use [verse] [chorus] [bridge] tags. Open the Lyrics tab to draft with Qwen 2.5."
|
| 6 |
GENERATE_DURATION = "Output length in seconds. Longer outputs cost more compute."
|
| 7 |
GENERATE_VOCAL = "With vocals: full song. Instrumental: no singing, just music."
|
| 8 |
+
|
| 9 |
+
# --- Cover tab ---
|
| 10 |
+
COVER_REF_AUDIO = "Reference clip (≤ 60 s recommended). The first ~12 s drives the style most strongly."
|
| 11 |
+
COVER_PROMPT = "Override the reference's vibe with a new style direction. Leave blank to inherit fully."
|
| 12 |
+
COVER_LYRICS = "New lyrics sung over the reference style. Use [verse] [chorus] tags."
|
| 13 |
+
COVER_DURATION = "Length of the generated cover."
|
| 14 |
+
COVER_STRENGTH = "0.0 = ignore reference. 1.0 = clone reference. 0.93 is a balanced default."
|
| 15 |
+
|
| 16 |
+
# --- Extend tab ---
|
| 17 |
+
EXTEND_SEED_AUDIO = "The song to continue. Last few seconds influence the extension most."
|
| 18 |
+
EXTEND_PROMPT = "Style hint for what should come next."
|
| 19 |
+
EXTEND_LYRICS = "Lyrics for the extension (optional — leave blank for instrumental continuation)."
|
| 20 |
+
EXTEND_DURATION = "Extra time to generate after the seed."
|
| 21 |
+
EXTEND_CROSSFADE = "Smooth the seam between seed and extension (experimental — not yet wired in the installed acestep build)."
|
| 22 |
+
|
| 23 |
+
# --- Edit tab ---
|
| 24 |
+
EDIT_SOURCE_AUDIO = "The existing song. The segment you select will be regenerated."
|
| 25 |
+
EDIT_SUB_MODE = "repaint: rewrite the segment with new lyrics. flow_edit: morph the caption (experimental — falls back to a low-strength repaint in this build)."
|
| 26 |
+
EDIT_SOURCE_LYRICS = "Original lyrics for context."
|
| 27 |
+
EDIT_TARGET_LYRICS = "What the new segment should sing."
|
| 28 |
+
EDIT_SEGMENT_START = "Where the editable segment begins (seconds into the source)."
|
| 29 |
+
EDIT_SEGMENT_END = "Where the editable segment ends (seconds into the source)."
|
| 30 |
+
|
| 31 |
+
# --- Lyrics tab ---
|
| 32 |
+
LYRICS_BRIEF = "Describe the song. Tone, mood, references, lines to avoid. Free-form prose."
|
| 33 |
+
LYRICS_STRUCTURE = "Section sequence. Comma-separated. The LM honors this layout."
|
| 34 |
+
LYRICS_LANGUAGE = "Output language for the lyrics. Qwen 2.5 7B handles 10+ languages well."
|
| 35 |
+
LYRICS_TONE = "Comma-separated descriptors. Influences word choice and rhythm."
|
| 36 |
+
LYRICS_TEMPERATURE = "0.0 = deterministic. 1.0 = creative. 0.85 balances both."
|
| 37 |
+
LYRICS_TOP_P = "Nucleus sampling. 0.9 keeps coherence with a bit of variety."
|
| 38 |
+
LYRICS_TOP_K = "Limits the candidate token pool. 40 is a good default; 0 disables."
|
| 39 |
+
LYRICS_MAX_TOKENS = "Generation budget. 600 tokens ≈ 30 lines."
|
| 40 |
+
|
| 41 |
+
# --- LoRA accordion (shared across all song modes) ---
|
| 42 |
+
LORA_PRESET = "Pick an official ACE-Step LoRA — downloads from Hugging Face on first use."
|
| 43 |
+
LORA_UPLOAD = (
|
| 44 |
+
"Upload any compatible .safetensors LoRA. Header is validated against ACE-Step 1.5 XL DiT modules."
|
| 45 |
+
)
|
| 46 |
+
LORA_STRENGTH = "0.0 = LoRA disabled. 1.0 = full effect. > 1.0 = overdrive (may degrade quality)."
|
| 47 |
+
|
| 48 |
+
# --- Post-process action row ---
|
| 49 |
+
POST_STEMS = "Run Demucs (htdemucs_ft) to split into vocals / drums / bass / other."
|
| 50 |
+
POST_NORMALISE = "Normalise output to -14 LUFS (streaming spec)."
|
| 51 |
+
POST_MP3 = "Export the current output as a 320 kbps stereo MP3."
|
ui.py
CHANGED
|
@@ -60,6 +60,7 @@ def _build_lora_accordion(components: dict[str, gr.components.Component]) -> Non
|
|
| 60 |
step=0.05,
|
| 61 |
value=0.95,
|
| 62 |
label="Strength",
|
|
|
|
| 63 |
elem_classes=["ams-lora-strength"],
|
| 64 |
)
|
| 65 |
components["lora_active"] = gr.Markdown(
|
|
@@ -212,11 +213,13 @@ def build_cover_tab() -> dict[str, gr.components.Component]:
|
|
| 212 |
label="New style prompt (optional)",
|
| 213 |
placeholder="faster, more aggressive leads",
|
| 214 |
lines=2,
|
|
|
|
| 215 |
)
|
| 216 |
components["lyrics"] = gr.Textbox(
|
| 217 |
label="New lyrics",
|
| 218 |
placeholder="[verse] new lyrics over the reference style",
|
| 219 |
lines=5,
|
|
|
|
| 220 |
)
|
| 221 |
with gr.Row():
|
| 222 |
components["duration_s"] = gr.Slider(
|
|
@@ -225,6 +228,7 @@ def build_cover_tab() -> dict[str, gr.components.Component]:
|
|
| 225 |
step=5,
|
| 226 |
value=30,
|
| 227 |
label="Duration (s)",
|
|
|
|
| 228 |
)
|
| 229 |
components["audio_cover_strength"] = gr.Slider(
|
| 230 |
minimum=0.0,
|
|
@@ -232,7 +236,7 @@ def build_cover_tab() -> dict[str, gr.components.Component]:
|
|
| 232 |
step=0.01,
|
| 233 |
value=0.93,
|
| 234 |
label="Cover strength",
|
| 235 |
-
info=
|
| 236 |
)
|
| 237 |
|
| 238 |
_build_lora_accordion(components)
|
|
@@ -275,11 +279,13 @@ def build_extend_tab() -> dict[str, gr.components.Component]:
|
|
| 275 |
label="Extension prompt",
|
| 276 |
placeholder="build to climax, layered acid leads",
|
| 277 |
lines=2,
|
|
|
|
| 278 |
)
|
| 279 |
components["extension_lyrics"] = gr.Textbox(
|
| 280 |
label="Extension lyrics (optional)",
|
| 281 |
placeholder="[bridge] the drop is coming...",
|
| 282 |
lines=4,
|
|
|
|
| 283 |
)
|
| 284 |
with gr.Row():
|
| 285 |
components["extra_duration_s"] = gr.Slider(
|
|
@@ -288,6 +294,7 @@ def build_extend_tab() -> dict[str, gr.components.Component]:
|
|
| 288 |
step=5,
|
| 289 |
value=60,
|
| 290 |
label="Extra duration (s)",
|
|
|
|
| 291 |
)
|
| 292 |
components["wav_crossfade_s"] = gr.Slider(
|
| 293 |
minimum=0.0,
|
|
@@ -295,7 +302,7 @@ def build_extend_tab() -> dict[str, gr.components.Component]:
|
|
| 295 |
step=0.1,
|
| 296 |
value=2.0,
|
| 297 |
label="WAV crossfade (s)",
|
| 298 |
-
info=
|
| 299 |
)
|
| 300 |
|
| 301 |
with gr.Accordion(
|
|
@@ -374,30 +381,31 @@ def build_edit_tab() -> dict[str, gr.components.Component]:
|
|
| 374 |
choices=["repaint", "flow_edit"],
|
| 375 |
value="repaint",
|
| 376 |
label="Edit sub-mode",
|
| 377 |
-
info=
|
| 378 |
-
"repaint: regenerate the segment from new lyrics. "
|
| 379 |
-
"flow_edit: morph caption-to-caption (experimental)."
|
| 380 |
-
),
|
| 381 |
)
|
| 382 |
components["source_lyrics"] = gr.Textbox(
|
| 383 |
label="Source lyrics",
|
| 384 |
lines=3,
|
|
|
|
| 385 |
)
|
| 386 |
components["target_lyrics"] = gr.Textbox(
|
| 387 |
label="Target lyrics",
|
| 388 |
placeholder="[chorus] new chorus replaces the old",
|
| 389 |
lines=3,
|
|
|
|
| 390 |
)
|
| 391 |
with gr.Row():
|
| 392 |
components["segment_start_s"] = gr.Number(
|
| 393 |
value=0.0,
|
| 394 |
label="Segment start (s)",
|
| 395 |
precision=1,
|
|
|
|
| 396 |
)
|
| 397 |
components["segment_end_s"] = gr.Number(
|
| 398 |
value=30.0,
|
| 399 |
label="Segment end (s)",
|
| 400 |
precision=1,
|
|
|
|
| 401 |
)
|
| 402 |
|
| 403 |
with gr.Accordion(
|
|
@@ -484,16 +492,19 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 484 |
label="Brief",
|
| 485 |
lines=4,
|
| 486 |
placeholder=("Describe the song. Tone, mood, references, specific images, lines to avoid…"),
|
|
|
|
| 487 |
)
|
| 488 |
with gr.Row():
|
| 489 |
c["structure"] = gr.Textbox(
|
| 490 |
label="Structure",
|
| 491 |
value="intro, verse, chorus, verse, chorus, bridge, chorus, outro",
|
|
|
|
| 492 |
)
|
| 493 |
c["language"] = gr.Dropdown(
|
| 494 |
choices=["en", "zh", "ja", "ko", "es", "fr", "de"],
|
| 495 |
value="en",
|
| 496 |
label="Language",
|
|
|
|
| 497 |
)
|
| 498 |
with gr.Row():
|
| 499 |
c["verse_lines"] = gr.Slider(
|
|
@@ -520,6 +531,7 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 520 |
c["tone"] = gr.Textbox(
|
| 521 |
label="Tone / mood",
|
| 522 |
placeholder="euphoric, hypnotic, transcendent, not cheesy",
|
|
|
|
| 523 |
)
|
| 524 |
c["rhyme"] = gr.Radio(
|
| 525 |
choices=["strict", "loose", "none"],
|
|
@@ -537,6 +549,7 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 537 |
value=0.85,
|
| 538 |
step=0.05,
|
| 539 |
label="Temperature",
|
|
|
|
| 540 |
)
|
| 541 |
c["top_p"] = gr.Slider(
|
| 542 |
minimum=0.0,
|
|
@@ -544,6 +557,7 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 544 |
value=0.9,
|
| 545 |
step=0.05,
|
| 546 |
label="Top-p",
|
|
|
|
| 547 |
)
|
| 548 |
c["top_k"] = gr.Slider(
|
| 549 |
minimum=0,
|
|
@@ -551,6 +565,7 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 551 |
value=40,
|
| 552 |
step=1,
|
| 553 |
label="Top-k",
|
|
|
|
| 554 |
)
|
| 555 |
c["max_new_tokens"] = gr.Slider(
|
| 556 |
minimum=100,
|
|
@@ -558,6 +573,7 @@ def build_lyrics_tab() -> dict[str, gr.components.Component]:
|
|
| 558 |
value=600,
|
| 559 |
step=50,
|
| 560 |
label="Max new tokens",
|
|
|
|
| 561 |
)
|
| 562 |
c["seed"] = gr.Number(
|
| 563 |
value=42,
|
|
|
|
| 60 |
step=0.05,
|
| 61 |
value=0.95,
|
| 62 |
label="Strength",
|
| 63 |
+
info=tooltips.LORA_STRENGTH,
|
| 64 |
elem_classes=["ams-lora-strength"],
|
| 65 |
)
|
| 66 |
components["lora_active"] = gr.Markdown(
|
|
|
|
| 213 |
label="New style prompt (optional)",
|
| 214 |
placeholder="faster, more aggressive leads",
|
| 215 |
lines=2,
|
| 216 |
+
info=tooltips.COVER_PROMPT,
|
| 217 |
)
|
| 218 |
components["lyrics"] = gr.Textbox(
|
| 219 |
label="New lyrics",
|
| 220 |
placeholder="[verse] new lyrics over the reference style",
|
| 221 |
lines=5,
|
| 222 |
+
info=tooltips.COVER_LYRICS,
|
| 223 |
)
|
| 224 |
with gr.Row():
|
| 225 |
components["duration_s"] = gr.Slider(
|
|
|
|
| 228 |
step=5,
|
| 229 |
value=30,
|
| 230 |
label="Duration (s)",
|
| 231 |
+
info=tooltips.COVER_DURATION,
|
| 232 |
)
|
| 233 |
components["audio_cover_strength"] = gr.Slider(
|
| 234 |
minimum=0.0,
|
|
|
|
| 236 |
step=0.01,
|
| 237 |
value=0.93,
|
| 238 |
label="Cover strength",
|
| 239 |
+
info=tooltips.COVER_STRENGTH,
|
| 240 |
)
|
| 241 |
|
| 242 |
_build_lora_accordion(components)
|
|
|
|
| 279 |
label="Extension prompt",
|
| 280 |
placeholder="build to climax, layered acid leads",
|
| 281 |
lines=2,
|
| 282 |
+
info=tooltips.EXTEND_PROMPT,
|
| 283 |
)
|
| 284 |
components["extension_lyrics"] = gr.Textbox(
|
| 285 |
label="Extension lyrics (optional)",
|
| 286 |
placeholder="[bridge] the drop is coming...",
|
| 287 |
lines=4,
|
| 288 |
+
info=tooltips.EXTEND_LYRICS,
|
| 289 |
)
|
| 290 |
with gr.Row():
|
| 291 |
components["extra_duration_s"] = gr.Slider(
|
|
|
|
| 294 |
step=5,
|
| 295 |
value=60,
|
| 296 |
label="Extra duration (s)",
|
| 297 |
+
info=tooltips.EXTEND_DURATION,
|
| 298 |
)
|
| 299 |
components["wav_crossfade_s"] = gr.Slider(
|
| 300 |
minimum=0.0,
|
|
|
|
| 302 |
step=0.1,
|
| 303 |
value=2.0,
|
| 304 |
label="WAV crossfade (s)",
|
| 305 |
+
info=tooltips.EXTEND_CROSSFADE,
|
| 306 |
)
|
| 307 |
|
| 308 |
with gr.Accordion(
|
|
|
|
| 381 |
choices=["repaint", "flow_edit"],
|
| 382 |
value="repaint",
|
| 383 |
label="Edit sub-mode",
|
| 384 |
+
info=tooltips.EDIT_SUB_MODE,
|
|
|
|
|
|
|
|
|
|
| 385 |
)
|
| 386 |
components["source_lyrics"] = gr.Textbox(
|
| 387 |
label="Source lyrics",
|
| 388 |
lines=3,
|
| 389 |
+
info=tooltips.EDIT_SOURCE_LYRICS,
|
| 390 |
)
|
| 391 |
components["target_lyrics"] = gr.Textbox(
|
| 392 |
label="Target lyrics",
|
| 393 |
placeholder="[chorus] new chorus replaces the old",
|
| 394 |
lines=3,
|
| 395 |
+
info=tooltips.EDIT_TARGET_LYRICS,
|
| 396 |
)
|
| 397 |
with gr.Row():
|
| 398 |
components["segment_start_s"] = gr.Number(
|
| 399 |
value=0.0,
|
| 400 |
label="Segment start (s)",
|
| 401 |
precision=1,
|
| 402 |
+
info=tooltips.EDIT_SEGMENT_START,
|
| 403 |
)
|
| 404 |
components["segment_end_s"] = gr.Number(
|
| 405 |
value=30.0,
|
| 406 |
label="Segment end (s)",
|
| 407 |
precision=1,
|
| 408 |
+
info=tooltips.EDIT_SEGMENT_END,
|
| 409 |
)
|
| 410 |
|
| 411 |
with gr.Accordion(
|
|
|
|
| 492 |
label="Brief",
|
| 493 |
lines=4,
|
| 494 |
placeholder=("Describe the song. Tone, mood, references, specific images, lines to avoid…"),
|
| 495 |
+
info=tooltips.LYRICS_BRIEF,
|
| 496 |
)
|
| 497 |
with gr.Row():
|
| 498 |
c["structure"] = gr.Textbox(
|
| 499 |
label="Structure",
|
| 500 |
value="intro, verse, chorus, verse, chorus, bridge, chorus, outro",
|
| 501 |
+
info=tooltips.LYRICS_STRUCTURE,
|
| 502 |
)
|
| 503 |
c["language"] = gr.Dropdown(
|
| 504 |
choices=["en", "zh", "ja", "ko", "es", "fr", "de"],
|
| 505 |
value="en",
|
| 506 |
label="Language",
|
| 507 |
+
info=tooltips.LYRICS_LANGUAGE,
|
| 508 |
)
|
| 509 |
with gr.Row():
|
| 510 |
c["verse_lines"] = gr.Slider(
|
|
|
|
| 531 |
c["tone"] = gr.Textbox(
|
| 532 |
label="Tone / mood",
|
| 533 |
placeholder="euphoric, hypnotic, transcendent, not cheesy",
|
| 534 |
+
info=tooltips.LYRICS_TONE,
|
| 535 |
)
|
| 536 |
c["rhyme"] = gr.Radio(
|
| 537 |
choices=["strict", "loose", "none"],
|
|
|
|
| 549 |
value=0.85,
|
| 550 |
step=0.05,
|
| 551 |
label="Temperature",
|
| 552 |
+
info=tooltips.LYRICS_TEMPERATURE,
|
| 553 |
)
|
| 554 |
c["top_p"] = gr.Slider(
|
| 555 |
minimum=0.0,
|
|
|
|
| 557 |
value=0.9,
|
| 558 |
step=0.05,
|
| 559 |
label="Top-p",
|
| 560 |
+
info=tooltips.LYRICS_TOP_P,
|
| 561 |
)
|
| 562 |
c["top_k"] = gr.Slider(
|
| 563 |
minimum=0,
|
|
|
|
| 565 |
value=40,
|
| 566 |
step=1,
|
| 567 |
label="Top-k",
|
| 568 |
+
info=tooltips.LYRICS_TOP_K,
|
| 569 |
)
|
| 570 |
c["max_new_tokens"] = gr.Slider(
|
| 571 |
minimum=100,
|
|
|
|
| 573 |
value=600,
|
| 574 |
step=50,
|
| 575 |
label="Max new tokens",
|
| 576 |
+
info=tooltips.LYRICS_MAX_TOKENS,
|
| 577 |
)
|
| 578 |
c["seed"] = gr.Number(
|
| 579 |
value=42,
|