DeepSeekOracle commited on
Commit
4dc6f42
Β·
verified Β·
1 Parent(s): 4c58416

Upload GRADIO_TIPS_TRICKS_HELPER.txt with huggingface_hub

Browse files
Files changed (1) hide show
  1. GRADIO_TIPS_TRICKS_HELPER.txt +134 -0
GRADIO_TIPS_TRICKS_HELPER.txt ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GRADIO TIPS, TRICKS, BEST PRACTICES & TROUBLESHOOTING REFERENCE
2
+ # For LYGO Resonance Engine HF Space rebuild (saved 2026-06-13)
3
+ # Source: Official Gradio docs (gradio.app), GitHub gradio-app/gradio issues/PRs (2025-2026), community discussions, and hijacked patterns from ClawHub skills (especially .grok/skills/lygo-resonance/gradio_app.py and related).
4
+ # Purpose: Methodical troubleshooting reference. Use this when controls don't affect output, UI freezes, logs missing, visibility broken, etc.
5
+ # "Hijack anything good": We butcher clean patterns from the lygo-resonance skill's gradio_app.py (clean Blocks layout, exact input ordering, batch handling, logging to textbox) and official examples into our HF app.py + future clean base.
6
+ # Rule: Build ONLY from rock-solid working foundation (current "buzzing + clear sound" in Standard is our lock-in base). Add STRICT modules that ENHANCE without breaking. Log everything.
7
+
8
+ ## 1. CORE ARCHITECTURE RULES (Blocks > Interface for complex apps like ours)
9
+ - ALWAYS use `with gr.Blocks() as demo:` (or `gr.Blocks(theme=...)`). Never put components outside the context β€” this was the root of previous "components not rendering / errors" in our space.
10
+ - Layout: gr.Row() + gr.Column(scale=1) for side-by-side (input | output). Use gr.Accordion() for grouped controls (Global Settings, LYGO Protocol Settings, Creative Sonification).
11
+ - Modes/Tabs: Use gr.Radio(["Standard Beat Tools", "LYGO Protocol"], value="Standard Beat Tools", label=...) + .change() to toggle visibility of accordions (see current toggle_ldq_visibility in app.py β€” keep this pattern).
12
+ - Alternative (from docs): gr.Tabs() + gr.Tab("Factory") for true tab isolation if Radio+visibility gets state bugs.
13
+ - Event binding (CRITICAL for "BPM and tools not changing anything"):
14
+ - submit_btn.click( fn=process_image, inputs=[img_input, core_mode, ..., bpm_slider, swing_slider], outputs=[text_output, audio_player, file_download] )
15
+ - The INPUTS LIST ORDER **MUST EXACTLY MATCH** the fn def signature order. Mismatch = silent param ignore (our current bug for some sliders?).
16
+ - For live feel on sliders (optional, expensive for audio gen): slider.change(fn=..., inputs=..., outputs=...) but queue it.
17
+ - Always call `demo.queue(max_size=10, default_concurrency_limit=1)` before launch() for any non-trivial app (audio synthesis, batch, long runs). Without queue: generators fail, UI freezes on tab switch (see GitHub issues #13198, #7189), multiple users break.
18
+ - Recommendation from perf guide: Increase concurrency_limit while you have memory/CPU. Set status_update_rate="auto".
19
+ - Visibility & dynamic UI (our LDQ accordion):
20
+ - def toggle_...(mode): return gr.update(visible=(mode == "LYGO Protocol"))
21
+ - core_mode.change(toggle_..., inputs=core_mode, outputs=ldq_accordion)
22
+ - Use gr.update() for value/visible/interactive changes. Never mutate components after definition.
23
+ - State management (to avoid globals/determinism bugs):
24
+ - Use gr.State() for per-session things (e.g., last_image_path, current_tab).
25
+ - Global state (variables outside fn) is shared across ALL users β€” bad for our deterministic per-user seeds.
26
+ - Browser state (gr.BrowserState) for persistence across refresh (e.g., last preset choice).
27
+ - From skill hijack: lygo-resonance/gradio_app.py uses no heavy State yet β€” add gr.State(value={}) for "last_config" if we need to debug param mapping.
28
+ - Theming & polish: `gr.Blocks(theme=gr.themes.Soft() or gr.themes.Box())`. Markdown with emojis for headers.
29
+
30
+ ## 2. COMMON PITFALLS & WHY "CONTROLS DON'T CHANGE GENERATION" (our exact symptoms)
31
+ - Param not wired in the Python fn (most likely our case):
32
+ - BPM, swing, etc. are ONLY used inside the `if cfg.get("use_ldq") and ... == "ldq":` block (see resonance_engine.py:234).
33
+ - Standard path (the "buzzing + clear" foundation) ignores tempo_bpm/swing/percussion_mode/genre_manifold/perceptual_polish.
34
+ - Fix (strict modules): In standard synthesis, add *light* influence, e.g.:
35
+ - Use bpm to scale melody event timing or drone modulation.
36
+ - Swing for slight random offset on starts (even without full TempoGrid).
37
+ - Always log: "STANDARD PATH | bpm_influence_applied: True/False | effective_tempo: XX"
38
+ - Seed: It IS used (np.random.seed at top of synthesize if random_seed). If not changing, either (a) same image + same seed always deterministic, or (b) user not noticing small differences, or (c) noise layer dominates.
39
+ - Gradio caching / no re-run: By default Gradio may cache identical inputs. Add `gr.Caching()` or set `cache_examples=False`. Or force via unique seed in filename.
40
+ - Queue not enabled: Long gens or generators (if we yield logs) require queue().
41
+ - Input ordering or type mismatch: Number vs Slider β€” both fine, but must be in the exact list passed to .click().
42
+ - Tab/Accordion state loss on submit: Use gr.State to remember mode.
43
+ - From GitHub (2026 issues): Tab switching can freeze in some 6.11+ versions β€” our Radio+visibility is safer. Test with .select() on tabs if we switch to gr.Tabs.
44
+ - Visibility on wrong components: The LDQ accordion is correctly inside Blocks now (previous fix).
45
+
46
+ ## 3. LOGGING BEST PRACTICES (MANDATORY: "LOG issue and LOG when things are working and how much")
47
+ - Inside every fn (process_image, run_creative..., engine methods):
48
+ ```python
49
+ log_lines = []
50
+ log_lines.append(f"PATH: {'STANDARD' if not use_ldq else 'LYGO/LDQ'} | mode={core_mode} | ldq_enabled={enable_ldq} | percussion={percussion_mode}")
51
+ log_lines.append(f"CONFIG: {config}") # full dict dump
52
+ log_lines.append(f"FEATURES: edge={features['edge_density']:.4f}, contours={len(features['contours'])}, lines={len(features['lines'])}, keypoints={len(features['keypoints'])}")
53
+ log_lines.append(f"PRESET: {style} | seed={seed} | duration={duration} | bpm={bpm} | swing={swing}")
54
+ log_lines.append(f"VOLUMES_APPLIED: noise={cfg.get('noise_vol')}, drone=..., note=... | lowpass={cfg.get('noise_lowpass_hz')}")
55
+ if os.path.exists(out_path):
56
+ log_lines.append(f"OUTPUT: {out_path} | size={os.path.getsize(out_path)} | PEAK (if computed) = ...")
57
+ log_text = "\n".join(log_lines)
58
+ # Return or update the textbox with it + any success message
59
+ ```
60
+ - Return the log as first output (text_output). User sees exact what was used.
61
+ - For "when working": Add success markers like "FOUNDATION_LOCK: buzzing+clear audio generated with X energy layers".
62
+ - In engine:
63
+ - At start of synthesize: print or collect "SYNTHESIZE | use_ldq={cfg.get('use_ldq')} | random_seed set={...}"
64
+ - In standard loop: log per layer "Layer1 noise added vol=XX", "Melody events placed: N (timing scaled by bpm? Y/N)"
65
+ - After write: "SAVED | peak={np.max(np.abs(audio)):.3f}"
66
+ - Gradio tips for logs: Use textbox with lines=15-20, interactive=False. For real-time streaming logs during long gen: yield log updates (requires queue + generator fn).
67
+ - Hijacked from lygo-resonance/gradio_app.py: It returns detailed "βœ“ {img.name} β†’ {out}" strings + uses try/except per batch item. Copy that pattern for robustness.
68
+
69
+ ## 4. PERFORMANCE, QUEUE, CONCURRENCY & HF SPACE TIPS
70
+ - `demo.queue(max_size=20, default_concurrency_limit=1).launch()` β€” essential for our audio gens (prevents overlap, shows queue position).
71
+ - In HF Spaces: Set sdk_version in README.md (we have 6.18.0). Use cpu-basic or upgrade if needed. Add `hf spaces hardware ...` if heavy.
72
+ - Concurrency: For army/batch use, higher limit but watch memory (our numpy audio can be big).
73
+ - Caching: Disable for development. `gr.Examples(..., cache_examples=False)`
74
+ - File outputs: Use temp files or /tmp in HF, return paths. gr.Files() for multi-download.
75
+ - Image inputs: type="filepath" (as we do) is best for cv2.
76
+
77
+ ## 5. HIJACKED / BUTCHERED PATTERNS FROM CLAWHUB SKILLS (lygo-resonance is gold)
78
+ - From .grok/skills/lygo-resonance/gradio_app.py (butcher this into HF app.py for rock-solid base):
79
+ - Clean process_image that handles SINGLE + BATCH in one fn with try/except per item.
80
+ - Exact input list matching (style, seed, duration, noise_filter, export_*, batch_*).
81
+ - Returns: log string, audio_player path or None, list of downloadable paths.
82
+ - UI: gr.Blocks(theme=gr.themes.Box()), Markdown headers with links, Row/Column, multiple Accordions, gr.Files() for manifest.
83
+ - Batch: folder.glob + loop, collect results strings + files.
84
+ - No heavy globals; everything passed via config dict.
85
+ - "butcher" action: Merge its batch + clean logging + single-mode clarity with our current mode Radio + creative accordion + LDQ toggles.
86
+ - Other skills: lygo-ollama-army has no direct Gradio but resonance_utility.py can be hijacked for "army-assisted generation" (call resonance-analyst daemon from a button to suggest BPM/preset for an image).
87
+ - lyra-openclaw: Mentions browser/discord but no full Gradio β€” ignore for UI, use for future "post to Discord from HF" module.
88
+ - General: Copy the "submit_btn = gr.Button(..., variant='primary')" + click wiring exactly.
89
+
90
+ ## 6. STRICT MODULE SUPPORT DESIGN (per user directive)
91
+ - Foundation (Standard Beat Tools): Always the current working "buzzing + clear" 4-layer. NEVER mutate its core without a new "foundation lock" test.
92
+ - Modules as enhancers (additive, toggleable, logged):
93
+ - BPM/Swing module: Even in standard, create a lightweight TempoGrid or simple math: melody start times quantized to grid, slight swing offset. Log "BPM_MODULE: applied, effective timing scale = 140/60".
94
+ - Seed: Already global at synthesize top β€” enhance with per-layer seeds if needed.
95
+ - Style/Preset: Map more aggressively to layer vols + lowpass (already partially done in last edit).
96
+ - LDQ full module: Only when enable_ldq + percussion=ldq (strict guard we have). Returns early with full production.
97
+ - "Light Production Enhance" module (safe subset of ldq_music_production): Optional checkbox even in Standard β€” applies sidechain/freq-sep/limiter to the base audio for "proper engine" clarity without drums/buzz risk. Map to a boolean in config.
98
+ - Creative TOP 3: Treat as separate modules that can output raw or "piped through current foundation + chosen enhance modules".
99
+ - Every UI control must appear in the log + have a measurable effect (or explicit "no-op in this mode for determinism" note).
100
+ - Determinism: Document "same image+seed+config = identical output". BPM changes the *structure* (timing) so different BPM = different (but related) output.
101
+
102
+ ## 7. TROUBLESHOOTING CHECKLIST (use before every edit)
103
+ - [ ] Is the control in the .click() inputs= list in correct position?
104
+ - [ ] Does the Python fn actually *use* the value (grep for bpm_slider / bpm in resonance_engine.py)?
105
+ - [ ] Which path was taken? (Add the PATH log line first!)
106
+ - [ ] Queue enabled?
107
+ - [ ] Components inside with gr.Blocks() ?
108
+ - [ ] Run locally with `python -B app.py` and watch console prints.
109
+ - [ ] After edit: hf upload the specific files (app.py, resonance_engine.py) + full restart. Then `hf download ...` to verify live code.
110
+ - [ ] Test with very different BPM (80 vs 180) + same seed/image β€” listen for timing/groove change.
111
+ - [ ] Log the *effective* value used in synthesis (not just the slider value).
112
+
113
+ ## 8. NEXT STEPS FOR LYGO (methodical, from current working foundation)
114
+ 1. Add the verbose logging (see section 3) to both app.py process_image and resonance_engine synthesize + layer loops.
115
+ 2. Wire light BPM/swing influence into the STANDARD 4-layer (quantize melody starts, modulate drone freq slightly). Log the effect.
116
+ 3. In LYGO Protocol path: If not full LDQ, still apply "light production enhance" so it sounds *different/better* than pure default.
117
+ 4. Butcher more from lygo-resonance/gradio_app.py: Improve batch, add per-item logging, make creative outputs show "used foundation + X module".
118
+ 5. Create army role "gradioui-auditor" (already in rebuild plan) to review the UI wiring.
119
+ 6. Update Hugging face/memory.md + LYGO_HF_REBUILD_PLAN.md with this helper reference + test logs.
120
+ 7. HF upload + restart + user re-test. Log "BEFORE: controls no-op | AFTER: BPM changed groove by XX ms on events".
121
+
122
+ ## 9. EXTERNAL REFERENCES (as of 2026-06-13 crawl)
123
+ - Official: https://gradio.app/docs/gradio/blocks , /queue , /state-in-blocks , /tab
124
+ - Perf: https://gradio.app/guides/setting-up-a-demo-for-maximum-performance
125
+ - GitHub issues: tab freezes (#13198), event stacking on tabs (#7189), queue required for generators.
126
+ - YouTube crash courses and Medium articles on Blocks + State (global vs session).
127
+ - Hijack source: .grok/skills/lygo-resonance/gradio_app.py (the cleanest local example we control).
128
+
129
+ # END OF HELPER β€” Append real test logs below this line when working.
130
+ # Example entry:
131
+ # 2026-06-13 21:xx | Standard | image=foo.jpg | seed=123 | bpm=140 (no effect pre-fix) | LOG: PATH=STANDARD, features edge=0.023, 12 contours | OUTPUT: buzzing+clear, peak=0.87 | FOUNDATION_LOCKED
132
+ # After BPM wire: bpm=140 | LOG: BPM_MODULE applied, 8 melody events quantized to 140bpm grid, timing variance reduced 40%
133
+
134
+ Keep this file in the HF mirror. Update on every Gradio change or new bug found. This + the LDQ protocol txt + REBUILD_PLAN.md = our meticulous build bible.