Luigi commited on
Commit
df40b1d
·
1 Parent(s): b7e5000

Major UI/UX improvements for better user experience

Browse files

✨ Enhanced Interface:
- Modern gradient theme with Soft design and custom colors
- Organized layout with clear visual hierarchy
- Collapsible accordions for advanced settings
- Better spacing and visual grouping

🎨 Visual Improvements:
- Custom CSS with gradient headers and smooth transitions
- Improved chatbot styling with shadows and rounded corners
- Enhanced button designs with hover effects
- Better form controls with info tooltips

🚀 UX Enhancements:
- Auto-hide web search settings when disabled
- Example prompts to help users get started
- Improved tooltips and descriptions for all controls
- Better responsive layout for different screen sizes
- Clear visual feedback for all interactions

📱 User-Friendly Features:
- Copy button on chat messages
- Larger, more accessible input area
- Prominent Send and Stop buttons
- Collapsible debug info to reduce clutter
- Helpful footer with usage tips

🎯 Balance:
- Simple interface by default (core settings always visible)
- Advanced options hidden in accordions for power users
- Clean, modern aesthetic without overwhelming complexity

Files changed (3) hide show
  1. __pycache__/app.cpython-312.pyc +0 -0
  2. app.py +159 -25
  3. style.css +150 -0
__pycache__/app.cpython-312.pyc ADDED
Binary file (28.8 kB). View file
 
app.py CHANGED
@@ -600,35 +600,160 @@ def update_duration_estimate(model_name, enable_search, max_results, max_chars,
600
  # ------------------------------
601
  # Gradio UI
602
  # ------------------------------
603
- with gr.Blocks(title="LLM Inference with ZeroGPU") as demo:
604
- gr.Markdown("## 🧠 ZeroGPU LLM Inference with Web Search")
605
- gr.Markdown("Interact with the model. Select parameters and chat below.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
  with gr.Row():
 
607
  with gr.Column(scale=3):
608
- model_dd = gr.Dropdown(label="Select Model", choices=list(MODELS.keys()), value="Qwen3-1.7B")
609
- search_chk = gr.Checkbox(label="Enable Web Search", value=False)
610
- sys_prompt = gr.Textbox(label="System Prompt", lines=3, value=update_default_prompt(search_chk.value))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611
 
612
- duration_display = gr.Markdown(value=update_duration_estimate("Qwen3-1.7B", False, 4, 50, 1024, 5.0))
 
 
 
 
613
 
614
- gr.Markdown("### Generation Parameters")
615
- max_tok = gr.Slider(64, 16384, value=1024, step=32, label="Max Tokens")
616
- temp = gr.Slider(0.1, 2.0, value=0.7, step=0.1, label="Temperature")
617
- k = gr.Slider(1, 100, value=40, step=1, label="Top-K")
618
- p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-P")
619
- rp = gr.Slider(1.0, 2.0, value=1.2, step=0.1, label="Repetition Penalty")
620
- gr.Markdown("### Web Search Settings")
621
- mr = gr.Number(value=4, precision=0, label="Max Results")
622
- mc = gr.Number(value=50, precision=0, label="Max Chars/Result")
623
- st = gr.Slider(minimum=0.0, maximum=30.0, step=0.5, value=5.0, label="Search Timeout (s)")
624
- clr = gr.Button("Clear Chat")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  with gr.Column(scale=7):
626
- chat = gr.Chatbot(type="messages", height=600)
 
 
 
 
 
 
 
 
 
627
  with gr.Row():
628
- txt = gr.Textbox(placeholder="Type your message...", scale=8, container=False)
629
- submit_btn = gr.Button("Submit", variant="primary", scale=1)
630
- cancel_btn = gr.Button("⏹️ Cancel", variant="stop", visible=False, scale=1)
631
- dbg = gr.Markdown()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
 
633
  # --- Event Listeners ---
634
 
@@ -731,8 +856,17 @@ with gr.Blocks(title="LLM Inference with ZeroGPU") as demo:
731
  for component in duration_inputs:
732
  component.change(fn=update_duration_estimate, inputs=duration_inputs, outputs=duration_display)
733
 
734
- # Other minor event listeners
735
- search_chk.change(fn=update_default_prompt, inputs=search_chk, outputs=sys_prompt)
 
 
 
 
 
 
 
 
 
736
  clr.click(fn=lambda: ([], "", ""), outputs=[chat, txt, dbg])
737
 
738
  demo.launch()
 
600
  # ------------------------------
601
  # Gradio UI
602
  # ------------------------------
603
+ with gr.Blocks(
604
+ title="LLM Inference with ZeroGPU",
605
+ theme=gr.themes.Soft(
606
+ primary_hue="indigo",
607
+ secondary_hue="purple",
608
+ neutral_hue="slate",
609
+ radius_size="lg",
610
+ font=[gr.themes.GoogleFont("Inter"), "Arial", "sans-serif"]
611
+ ),
612
+ css="""
613
+ .duration-estimate { background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%); border-left: 4px solid #667eea; padding: 12px; border-radius: 8px; margin: 16px 0; }
614
+ .chatbot { border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
615
+ button.primary { font-weight: 600; }
616
+ .gradio-accordion { margin-bottom: 12px; }
617
+ """
618
+ ) as demo:
619
+ # Header
620
+ gr.Markdown("""
621
+ # 🧠 ZeroGPU LLM Inference
622
+ ### Powered by Hugging Face ZeroGPU with Web Search Integration
623
+ """)
624
+
625
  with gr.Row():
626
+ # Left Panel - Configuration
627
  with gr.Column(scale=3):
628
+ # Core Settings (Always Visible)
629
+ with gr.Group():
630
+ gr.Markdown("### ⚙️ Core Settings")
631
+ model_dd = gr.Dropdown(
632
+ label="🤖 Model",
633
+ choices=list(MODELS.keys()),
634
+ value="Qwen3-1.7B",
635
+ info="Select the language model to use"
636
+ )
637
+ search_chk = gr.Checkbox(
638
+ label="🔍 Enable Web Search",
639
+ value=False,
640
+ info="Augment responses with real-time web data"
641
+ )
642
+ sys_prompt = gr.Textbox(
643
+ label="📝 System Prompt",
644
+ lines=3,
645
+ value=update_default_prompt(search_chk.value),
646
+ placeholder="Define the assistant's behavior and personality..."
647
+ )
648
 
649
+ # Duration Estimate
650
+ duration_display = gr.Markdown(
651
+ value=update_duration_estimate("Qwen3-1.7B", False, 4, 50, 1024, 5.0),
652
+ elem_classes="duration-estimate"
653
+ )
654
 
655
+ # Advanced Settings (Collapsible)
656
+ with gr.Accordion("🎛️ Advanced Generation Parameters", open=False):
657
+ max_tok = gr.Slider(
658
+ 64, 16384, value=1024, step=32,
659
+ label="Max Tokens",
660
+ info="Maximum length of generated response"
661
+ )
662
+ temp = gr.Slider(
663
+ 0.1, 2.0, value=0.7, step=0.1,
664
+ label="Temperature",
665
+ info="Higher = more creative, Lower = more focused"
666
+ )
667
+ with gr.Row():
668
+ k = gr.Slider(
669
+ 1, 100, value=40, step=1,
670
+ label="Top-K",
671
+ info="Number of top tokens to consider"
672
+ )
673
+ p = gr.Slider(
674
+ 0.1, 1.0, value=0.9, step=0.05,
675
+ label="Top-P",
676
+ info="Nucleus sampling threshold"
677
+ )
678
+ rp = gr.Slider(
679
+ 1.0, 2.0, value=1.2, step=0.1,
680
+ label="Repetition Penalty",
681
+ info="Penalize repeated tokens"
682
+ )
683
+
684
+ # Web Search Settings (Collapsible)
685
+ with gr.Accordion("🌐 Web Search Settings", open=False, visible=False) as search_settings:
686
+ mr = gr.Number(
687
+ value=4, precision=0,
688
+ label="Max Results",
689
+ info="Number of search results to retrieve"
690
+ )
691
+ mc = gr.Number(
692
+ value=50, precision=0,
693
+ label="Max Chars/Result",
694
+ info="Character limit per search result"
695
+ )
696
+ st = gr.Slider(
697
+ minimum=0.0, maximum=30.0, step=0.5, value=5.0,
698
+ label="Search Timeout (s)",
699
+ info="Maximum time to wait for search results"
700
+ )
701
+
702
+ # Actions
703
+ with gr.Row():
704
+ clr = gr.Button("🗑️ Clear Chat", variant="secondary", scale=1)
705
+
706
+ # Right Panel - Chat Interface
707
  with gr.Column(scale=7):
708
+ chat = gr.Chatbot(
709
+ type="messages",
710
+ height=600,
711
+ label="💬 Conversation",
712
+ show_copy_button=True,
713
+ avatar_images=(None, "🤖"),
714
+ bubble_full_width=False
715
+ )
716
+
717
+ # Input Area
718
  with gr.Row():
719
+ txt = gr.Textbox(
720
+ placeholder="💭 Type your message here... (Press Enter to send)",
721
+ scale=9,
722
+ container=False,
723
+ show_label=False,
724
+ lines=1,
725
+ max_lines=5
726
+ )
727
+ with gr.Column(scale=1, min_width=120):
728
+ submit_btn = gr.Button("📤 Send", variant="primary", size="lg")
729
+ cancel_btn = gr.Button("⏹️ Stop", variant="stop", visible=False, size="lg")
730
+
731
+ # Example Prompts
732
+ gr.Examples(
733
+ examples=[
734
+ ["Explain quantum computing in simple terms"],
735
+ ["Write a Python function to calculate fibonacci numbers"],
736
+ ["What are the latest developments in AI? (Enable web search)"],
737
+ ["Tell me a creative story about a time traveler"],
738
+ ["Help me debug this code: def add(a,b): return a+b+1"]
739
+ ],
740
+ inputs=txt,
741
+ label="💡 Example Prompts"
742
+ )
743
+
744
+ # Debug/Status Info (Collapsible)
745
+ with gr.Accordion("🔍 Debug Info", open=False):
746
+ dbg = gr.Markdown()
747
+
748
+ # Footer
749
+ gr.Markdown("""
750
+ ---
751
+ 💡 **Tips:**
752
+ - Use **Advanced Parameters** to fine-tune creativity and response length
753
+ - Enable **Web Search** for real-time, up-to-date information
754
+ - Try different **models** for various tasks (reasoning, coding, general chat)
755
+ - Click the **Copy** button on responses to save them to your clipboard
756
+ """, elem_classes="footer")
757
 
758
  # --- Event Listeners ---
759
 
 
856
  for component in duration_inputs:
857
  component.change(fn=update_duration_estimate, inputs=duration_inputs, outputs=duration_display)
858
 
859
+ # Toggle web search settings visibility
860
+ def toggle_search_settings(enabled):
861
+ return gr.update(visible=enabled)
862
+
863
+ search_chk.change(
864
+ fn=lambda enabled: (update_default_prompt(enabled), gr.update(visible=enabled)),
865
+ inputs=search_chk,
866
+ outputs=[sys_prompt, search_settings]
867
+ )
868
+
869
+ # Clear chat action
870
  clr.click(fn=lambda: ([], "", ""), outputs=[chat, txt, dbg])
871
 
872
  demo.launch()
style.css ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom CSS for LLM Inference Interface */
2
+
3
+ /* Header styling */
4
+ .markdown h1 {
5
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
6
+ -webkit-background-clip: text;
7
+ -webkit-text-fill-color: transparent;
8
+ background-clip: text;
9
+ font-weight: 800;
10
+ margin-bottom: 0.5rem;
11
+ }
12
+
13
+ .markdown h3 {
14
+ color: #4a5568;
15
+ font-weight: 600;
16
+ margin-top: 0.25rem;
17
+ }
18
+
19
+ /* Duration estimate styling */
20
+ .duration-estimate {
21
+ background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%);
22
+ border-left: 4px solid #667eea;
23
+ padding: 12px;
24
+ border-radius: 8px;
25
+ margin: 16px 0;
26
+ font-size: 0.9em;
27
+ }
28
+
29
+ /* Group styling for better visual separation */
30
+ .gradio-group {
31
+ border: 1px solid #e2e8f0;
32
+ border-radius: 12px;
33
+ padding: 16px;
34
+ background: #f8fafc;
35
+ margin-bottom: 16px;
36
+ }
37
+
38
+ /* Accordion styling */
39
+ .gradio-accordion {
40
+ border: 1px solid #e2e8f0;
41
+ border-radius: 8px;
42
+ margin-bottom: 12px;
43
+ }
44
+
45
+ .gradio-accordion .label-wrap {
46
+ background: #f1f5f9;
47
+ font-weight: 600;
48
+ }
49
+
50
+ /* Chat interface improvements */
51
+ .chatbot {
52
+ border-radius: 12px;
53
+ border: 1px solid #e2e8f0;
54
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
55
+ }
56
+
57
+ /* Input area styling */
58
+ .textbox-container {
59
+ border-radius: 24px;
60
+ border: 2px solid #e2e8f0;
61
+ transition: border-color 0.2s;
62
+ }
63
+
64
+ .textbox-container:focus-within {
65
+ border-color: #667eea;
66
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
67
+ }
68
+
69
+ /* Button improvements */
70
+ .gradio-button {
71
+ border-radius: 8px;
72
+ font-weight: 600;
73
+ transition: all 0.2s;
74
+ }
75
+
76
+ .gradio-button.primary {
77
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
78
+ border: none;
79
+ }
80
+
81
+ .gradio-button.primary:hover {
82
+ transform: translateY(-2px);
83
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
84
+ }
85
+
86
+ .gradio-button.secondary {
87
+ border: 2px solid #e2e8f0;
88
+ background: white;
89
+ }
90
+
91
+ .gradio-button.secondary:hover {
92
+ border-color: #cbd5e0;
93
+ background: #f7fafc;
94
+ }
95
+
96
+ /* Slider styling */
97
+ .gradio-slider {
98
+ margin: 8px 0;
99
+ }
100
+
101
+ .gradio-slider input[type="range"] {
102
+ accent-color: #667eea;
103
+ }
104
+
105
+ /* Info text styling */
106
+ .info {
107
+ color: #718096;
108
+ font-size: 0.85em;
109
+ font-style: italic;
110
+ }
111
+
112
+ /* Footer styling */
113
+ .footer .markdown {
114
+ text-align: center;
115
+ color: #718096;
116
+ font-size: 0.9em;
117
+ padding: 16px;
118
+ background: #f8fafc;
119
+ border-radius: 8px;
120
+ }
121
+
122
+ /* Responsive adjustments */
123
+ @media (max-width: 768px) {
124
+ .gradio-row {
125
+ flex-direction: column;
126
+ }
127
+
128
+ .chatbot {
129
+ height: 400px !important;
130
+ }
131
+ }
132
+
133
+ /* Loading animation */
134
+ @keyframes pulse {
135
+ 0%, 100% {
136
+ opacity: 1;
137
+ }
138
+ 50% {
139
+ opacity: 0.5;
140
+ }
141
+ }
142
+
143
+ .generating {
144
+ animation: pulse 1.5s ease-in-out infinite;
145
+ }
146
+
147
+ /* Smooth transitions */
148
+ * {
149
+ transition: background-color 0.2s, border-color 0.2s;
150
+ }