manthilaffs commited on
Commit
635f6f2
·
verified ·
1 Parent(s): 9fb401f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +209 -105
app.py CHANGED
@@ -58,58 +58,99 @@ with gr.Blocks(
58
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Sinhala:wght@400;500;600;700&display=swap');
59
 
60
  .gradio-container {
61
- max-width:1200px !important;
62
- margin:auto;
 
63
  font-family:'Noto Sans Sinhala','Inter',sans-serif !important;
64
  }
65
 
 
 
 
 
 
 
 
66
  h1,h2,h3,h4,h5 {text-align:center;}
67
 
68
  #title-bar {
69
  background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);
70
  color:white;
71
- padding:2rem 1rem;
72
- border-radius:1.5rem;
73
- margin-bottom:2rem;
74
- box-shadow:0 8px 32px rgba(102,126,234,0.3);
75
  }
76
 
77
  #title-bar h1 {
78
- font-size:2.5rem;
79
  font-weight:700;
80
- margin-bottom:0.5rem;
81
  text-shadow:2px 2px 4px rgba(0,0,0,0.2);
82
  }
83
 
84
  #title-bar h4 {
85
- font-size:1.2rem;
86
  font-weight:400;
87
  opacity:0.95;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
 
90
  textarea,input,.gr-text-input,.gr-textbox {
91
  font-family:'Noto Sans Sinhala',sans-serif !important;
92
- font-size:1.05rem !important;
93
- line-height:1.8 !important;
94
- border-radius:0.75rem !important;
 
 
 
 
 
 
 
95
  }
96
 
97
  #output-box {
98
  background:#f8f9fa;
99
  border:2px solid #e9ecef;
100
- border-radius:1rem;
101
- padding:1.5rem;
102
- min-height:200px;
103
- font-size:1.1rem !important;
104
- line-height:1.9 !important;
 
 
105
  box-shadow:inset 0 2px 8px rgba(0,0,0,0.05);
106
  }
107
 
 
 
 
 
 
 
 
 
 
108
  #status-text {
109
  text-align:center;
110
- font-size:1.1rem;
111
  font-weight:600;
112
- padding:0.75rem;
113
  border-radius:0.5rem;
114
  margin:0.5rem 0;
115
  }
@@ -128,14 +169,21 @@ with gr.Blocks(
128
  .primary-btn {
129
  background:linear-gradient(135deg,#667eea 0%,#764ba2 100%) !important;
130
  border:none !important;
131
- font-size:1.1rem !important;
132
  font-weight:600 !important;
133
- padding:0.75rem 2rem !important;
134
- border-radius:0.75rem !important;
135
  box-shadow:0 4px 15px rgba(102,126,234,0.4) !important;
136
  transition:all 0.3s ease !important;
137
  }
138
 
 
 
 
 
 
 
 
139
  .primary-btn:hover {
140
  transform:translateY(-2px);
141
  box-shadow:0 6px 20px rgba(102,126,234,0.5) !important;
@@ -144,137 +192,189 @@ with gr.Blocks(
144
  .secondary-btn {
145
  background:#6c757d !important;
146
  border:none !important;
147
- font-size:1rem !important;
148
- border-radius:0.75rem !important;
 
149
  }
150
 
151
  .label-text {
152
- font-size:1rem !important;
153
  font-weight:600 !important;
154
  color:#2d3748 !important;
155
- margin-bottom:0.5rem !important;
156
- }
157
-
158
- .example-box {
159
- border-radius:0.75rem;
160
- padding:0.5rem;
161
- transition:all 0.2s ease;
162
- }
163
-
164
- .example-box:hover {
165
- background:#f8f9fa;
166
- transform:translateX(4px);
167
  }
168
 
169
  #footer-info {
170
  text-align:center;
171
- padding:2rem 1rem;
172
- margin-top:3rem;
173
  border-top:2px solid #e9ecef;
174
  color:#6c757d;
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
  .token-counter {
178
- font-size:0.9rem;
179
  color:#6c757d;
180
  text-align:right;
181
- padding:0.25rem 0.5rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
  """,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  ) as demo:
185
 
186
  gr.HTML("""
187
  <div id='title-bar'>
188
- <h1>🧠 Gamunu 4B Instruct Alpha</h1>
189
- <h4>සිංහල භාෂාව සඳහා නිර්මාණය කළ අධිකරණ භාෂා ආකෘතියක්</h4>
190
  </div>
191
  """)
192
 
193
- with gr.Row(equal_height=False):
194
- with gr.Column(scale=5, min_width=400):
195
- instruction = gr.Textbox(
196
- label="📝 උපදෙස / ප්‍රශ්නය (Instruction / Question)",
197
- placeholder="උදාහරණ: හායි! මම සමන්. ඔයාට කොහොමද?\nया: ෆොටෝසින්තසිස් ක්‍රියාවලිය පැහැදිලි කරන්න.",
198
- lines=5,
199
- elem_classes="label-text"
200
- )
201
-
202
- input_text = gr.Textbox(
203
- label="📄 අමතර සන්දර්භය (Additional Context) - විකල්ප",
204
- placeholder="අමතර තොරතුරු හෝ සන්දර්භය මෙහි ඇතුළත් කරන්න...",
205
- lines=3,
206
- elem_classes="label-text"
207
- )
208
 
209
- with gr.Row():
210
- with gr.Column(scale=2):
211
- with gr.Accordion("⚙️ උසස් සැකසීම් (Advanced Settings)", open=False):
212
- max_new_tokens = gr.Slider(
213
- 64, 1024, value=512, step=32,
214
- label="🔢 උපරිම නව සලකුණු (Max New Tokens)",
215
- info="දිගු ප්‍රතිචාර සඳහා වැඩි කරන්න"
216
- )
217
-
218
- with gr.Column(scale=1):
219
- token_count = gr.Markdown("", elem_classes="token-counter")
220
 
221
- with gr.Row():
222
- run_btn = gr.Button("🚀 ප්‍රතිචාරය උත්පාදනය කරන්න", variant="primary", elem_classes="primary-btn", scale=3)
223
- clear_btn = gr.Button("🗑️ මකන්න", elem_classes="secondary-btn", scale=1)
224
-
225
- status = gr.Markdown("", elem_id="status-text")
226
 
227
- with gr.Column(scale=5, min_width=450):
228
- gr.Markdown("### 💬 ගැමුණු ප්‍රතිචාරය (Gamunu Response)")
229
- output = gr.Markdown("", elem_id="output-box")
230
-
231
- with gr.Row():
232
- copy_btn = gr.Button("📋 පිටපත් කරන්න (Copy)", size="sm")
233
 
234
- # --- Example prompts ---
235
- with gr.Accordion("📚 උදාහරණ ප්‍රශ්න (Example Prompts by Category)", open=True):
236
- with gr.Tab("🔢 ගණිතය (Maths)"):
237
  gr.Examples(
238
  examples=[
239
  ["රු. 30 කින් මිලදී ගත් දේ රු. 60 නම් මිල වෙනස ප්‍රතිශතයකින් කීයද?", ""],
240
- ["සියයට 10 ක වර්ධනයක් තිබේ නම් අලුත් අගය කීයද?", ""],
241
  ["2x + 5 = 15 සමීකරණය විසඳන්න.", ""],
242
  ],
243
- inputs=[instruction, input_text]
244
  )
245
 
246
- with gr.Tab("🎭 භූමිකා (Roleplay)"):
247
  gr.Examples(
248
  examples=[
249
- ["ඔබ ගුරුවරයෙකු ලෙස ක්‍රියාකරන්න. ශිෂ්‍යයාට ගණිතය උගන්වන්න.",
250
- "රු. 30 කින් මිලදී ගත් දේ රු. 60 නම් මිල වෙනස ප්‍රතිශතයකින් කීයද?"],
251
  ["ඔබ පරිසර විද්‍යාඥයෙකු ලෙස වායු මණ්ඩලය පැහැදිලි කරන්න.", ""],
252
- ["ඔබ කාර්මික විශේෂඥයෙකු ලෙස ක්‍රියා කරමින් මෘදුකාංග සංවර්ධනය පැහැදිලි කරන්න.", ""],
253
  ],
254
- inputs=[instruction, input_text]
255
  )
256
 
257
- with gr.Tab("❓ ප්‍රශ්න සහ පිළිතුරු (Q&A)"):
258
  gr.Examples(
259
  examples=[
260
  ["ෆොටෝසින්තසිස් ක්‍රියාවලිය පැහැදිලි කරන්න.", ""],
261
  ["ජලයේ රසායනික සූත්‍රය කුමක්ද?", ""],
262
- ["ශ්‍රී ලංකාවේ පළමු අගමැති කවුද?", ""],
263
  ],
264
- inputs=[instruction, input_text]
265
  )
266
 
267
- with gr.Tab("🔤 භාෂා සැකසුම (NLP)"):
268
  gr.Examples(
269
  examples=[
270
  ["මෙම වාක්‍යය සිංහලයට පරිවර්තනය කරන්න: 'The sun rises in the east.'", ""],
271
  ["වචන 'ආදරය' සඳහා සමානාර්ථ පද 3ක් දෙන්න.", ""],
272
- ["මෙම වාක්‍යය සරල කරන්න: 'අධිකාරිය විසින් නිකුත් කරන ලද නියෝගය අනුව ක්‍රියාත්මක වේ.'", ""],
273
  ],
274
- inputs=[instruction, input_text]
275
  )
276
 
277
- # --- Button feedback with improved status ---
278
  def process_with_status(instruction, input_text, max_new_tokens):
279
  if not instruction.strip():
280
  return "⚠️ කරුණාකර උපදෙසක් ඇතුළත් කරන්න", gr.update(interactive=True), "", ""
@@ -289,23 +389,27 @@ with gr.Blocks(
289
  try:
290
  result = infer(instruction, input_text, max_new_tokens)
291
  approx_tokens = len(result.split())
292
- token_info = f"📊 ආසන්න වශයෙන් වචන {approx_tokens}ක්"
293
  yield (
294
  "✅ සාර්ථකයි!",
295
- gr.update(interactive=True, value="🚀 ප්‍රතිචාරය උත්පාදනය කරන්න"),
296
  result,
297
  token_info
298
  )
299
  except Exception as e:
300
  yield (
301
  f"❌ දෝෂයක්: {str(e)}",
302
- gr.update(interactive=True, value="🚀 ප්‍රතිචාරය උත්පාදනය කරන්න"),
303
  "",
304
  ""
305
  )
306
 
307
  def clear_all():
308
- return "", "", 512, "", gr.update(value="🚀 ප්‍රතිචාරය උත්පාදනය කරන්න", interactive=True), ""
 
 
 
 
309
 
310
  run_btn.click(
311
  process_with_status,
@@ -321,11 +425,11 @@ with gr.Blocks(
321
 
322
  gr.HTML("""
323
  <div id='footer-info'>
324
- <p style='font-size:1.1rem; margin-bottom:0.5rem;'>
325
- 🪶 <strong>Model:</strong> <a href='https://huggingface.co/manthilaffs/Gamunu-4B-Instruct-Alpha' target='_blank'>manthilaffs/Gamunu-4B-Instruct-Alpha</a>
326
  </p>
327
- <p style='font-size:0.95rem; color:#868e96;'>
328
- © 2025 Gamunu Project | Experimental Release | Made with ❤️ for Sinhala NLP
329
  </p>
330
  </div>
331
  """)
 
58
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Sinhala:wght@400;500;600;700&display=swap');
59
 
60
  .gradio-container {
61
+ max-width:100% !important;
62
+ margin:0 auto !important;
63
+ padding:0.5rem !important;
64
  font-family:'Noto Sans Sinhala','Inter',sans-serif !important;
65
  }
66
 
67
+ @media (min-width: 768px) {
68
+ .gradio-container {
69
+ max-width:1100px !important;
70
+ padding:1rem !important;
71
+ }
72
+ }
73
+
74
  h1,h2,h3,h4,h5 {text-align:center;}
75
 
76
  #title-bar {
77
  background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);
78
  color:white;
79
+ padding:1rem;
80
+ border-radius:1rem;
81
+ margin-bottom:1rem;
82
+ box-shadow:0 4px 15px rgba(102,126,234,0.3);
83
  }
84
 
85
  #title-bar h1 {
86
+ font-size:1.5rem;
87
  font-weight:700;
88
+ margin-bottom:0.25rem;
89
  text-shadow:2px 2px 4px rgba(0,0,0,0.2);
90
  }
91
 
92
  #title-bar h4 {
93
+ font-size:0.9rem;
94
  font-weight:400;
95
  opacity:0.95;
96
+ margin:0;
97
+ }
98
+
99
+ @media (min-width: 768px) {
100
+ #title-bar {
101
+ padding:1.5rem;
102
+ margin-bottom:1.5rem;
103
+ }
104
+ #title-bar h1 {
105
+ font-size:2rem;
106
+ margin-bottom:0.5rem;
107
+ }
108
+ #title-bar h4 {
109
+ font-size:1.1rem;
110
+ }
111
  }
112
 
113
  textarea,input,.gr-text-input,.gr-textbox {
114
  font-family:'Noto Sans Sinhala',sans-serif !important;
115
+ font-size:0.95rem !important;
116
+ line-height:1.6 !important;
117
+ border-radius:0.5rem !important;
118
+ }
119
+
120
+ @media (min-width: 768px) {
121
+ textarea,input,.gr-text-input,.gr-textbox {
122
+ font-size:1rem !important;
123
+ line-height:1.7 !important;
124
+ }
125
  }
126
 
127
  #output-box {
128
  background:#f8f9fa;
129
  border:2px solid #e9ecef;
130
+ border-radius:0.75rem;
131
+ padding:1rem;
132
+ min-height:150px;
133
+ max-height:400px;
134
+ overflow-y:auto;
135
+ font-size:0.95rem !important;
136
+ line-height:1.7 !important;
137
  box-shadow:inset 0 2px 8px rgba(0,0,0,0.05);
138
  }
139
 
140
+ @media (min-width: 768px) {
141
+ #output-box {
142
+ padding:1.25rem;
143
+ min-height:180px;
144
+ font-size:1.05rem !important;
145
+ line-height:1.8 !important;
146
+ }
147
+ }
148
+
149
  #status-text {
150
  text-align:center;
151
+ font-size:0.9rem;
152
  font-weight:600;
153
+ padding:0.5rem;
154
  border-radius:0.5rem;
155
  margin:0.5rem 0;
156
  }
 
169
  .primary-btn {
170
  background:linear-gradient(135deg,#667eea 0%,#764ba2 100%) !important;
171
  border:none !important;
172
+ font-size:0.95rem !important;
173
  font-weight:600 !important;
174
+ padding:0.6rem 1rem !important;
175
+ border-radius:0.5rem !important;
176
  box-shadow:0 4px 15px rgba(102,126,234,0.4) !important;
177
  transition:all 0.3s ease !important;
178
  }
179
 
180
+ @media (min-width: 768px) {
181
+ .primary-btn {
182
+ font-size:1.05rem !important;
183
+ padding:0.7rem 1.5rem !important;
184
+ }
185
+ }
186
+
187
  .primary-btn:hover {
188
  transform:translateY(-2px);
189
  box-shadow:0 6px 20px rgba(102,126,234,0.5) !important;
 
192
  .secondary-btn {
193
  background:#6c757d !important;
194
  border:none !important;
195
+ font-size:0.85rem !important;
196
+ border-radius:0.5rem !important;
197
+ padding:0.6rem 1rem !important;
198
  }
199
 
200
  .label-text {
201
+ font-size:0.9rem !important;
202
  font-weight:600 !important;
203
  color:#2d3748 !important;
204
+ margin-bottom:0.25rem !important;
 
 
 
 
 
 
 
 
 
 
 
205
  }
206
 
207
  #footer-info {
208
  text-align:center;
209
+ padding:1rem;
210
+ margin-top:1.5rem;
211
  border-top:2px solid #e9ecef;
212
  color:#6c757d;
213
+ font-size:0.85rem;
214
+ }
215
+
216
+ @media (min-width: 768px) {
217
+ #footer-info {
218
+ padding:1.5rem;
219
+ margin-top:2rem;
220
+ font-size:0.95rem;
221
+ }
222
  }
223
 
224
  .token-counter {
225
+ font-size:0.8rem;
226
  color:#6c757d;
227
  text-align:right;
228
+ padding:0.25rem 0;
229
+ }
230
+
231
+ /* Compact accordion styling */
232
+ .gr-accordion {
233
+ margin:0.5rem 0 !important;
234
+ }
235
+
236
+ /* Mobile optimization */
237
+ @media (max-width: 767px) {
238
+ .gr-row {
239
+ flex-direction:column !important;
240
+ }
241
+ .gr-column {
242
+ width:100% !important;
243
+ min-width:100% !important;
244
+ }
245
+ }
246
+
247
+ /* Scroll to top button */
248
+ #scroll-top-btn {
249
+ position:fixed;
250
+ bottom:20px;
251
+ right:20px;
252
+ display:none;
253
+ z-index:1000;
254
+ padding:0.75rem 1rem;
255
+ background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);
256
+ color:white;
257
+ border:none;
258
+ border-radius:50px;
259
+ box-shadow:0 4px 15px rgba(0,0,0,0.3);
260
+ cursor:pointer;
261
+ font-size:1.2rem;
262
  }
263
  """,
264
+ js="""
265
+ function addScrollToTop() {
266
+ // Create scroll to top button
267
+ const scrollBtn = document.createElement('button');
268
+ scrollBtn.id = 'scroll-top-btn';
269
+ scrollBtn.innerHTML = '↑';
270
+ scrollBtn.title = 'මුලට යන්න';
271
+ document.body.appendChild(scrollBtn);
272
+
273
+ // Show/hide on scroll
274
+ window.addEventListener('scroll', function() {
275
+ if (window.pageYOffset > 300) {
276
+ scrollBtn.style.display = 'block';
277
+ } else {
278
+ scrollBtn.style.display = 'none';
279
+ }
280
+ });
281
+
282
+ // Scroll to top on click
283
+ scrollBtn.addEventListener('click', function() {
284
+ window.scrollTo({top: 0, behavior: 'smooth'});
285
+ });
286
+ }
287
+
288
+ // Initialize on load
289
+ if (document.readyState === 'loading') {
290
+ document.addEventListener('DOMContentLoaded', addScrollToTop);
291
+ } else {
292
+ addScrollToTop();
293
+ }
294
+ """
295
  ) as demo:
296
 
297
  gr.HTML("""
298
  <div id='title-bar'>
299
+ <h1>🧠 Gamunu 4B</h1>
300
+ <h4>සිංහල AI සහායකයා</h4>
301
  </div>
302
  """)
303
 
304
+ # Main input section - always at top
305
+ with gr.Column(elem_id="input-section"):
306
+ instruction = gr.Textbox(
307
+ label="📝 උපදෙස / ප්‍රශ්නය",
308
+ placeholder="උදා: හායි! ඔයාට කොහොමද?",
309
+ lines=3,
310
+ elem_classes="label-text"
311
+ )
312
+
313
+ input_text = gr.Textbox(
314
+ label="📄 අමතර සන්දර්භය (විකල්ප)",
315
+ placeholder="අමතර තොරතුරු...",
316
+ lines=2,
317
+ elem_classes="label-text"
318
+ )
319
 
320
+ with gr.Accordion("⚙️ උසස් සැකසීම්", open=False):
321
+ max_new_tokens = gr.Slider(
322
+ 64, 1024, value=512, step=64,
323
+ label="උපරිම නව සලකුණු",
324
+ info="දිගු ප්‍රතිචාර සඳහා වැඩි කරන්න"
325
+ )
 
 
 
 
 
326
 
327
+ with gr.Row():
328
+ run_btn = gr.Button("🚀 උත්පාදනය කරන්න", variant="primary", elem_classes="primary-btn", scale=2)
329
+ clear_btn = gr.Button("🗑️", elem_classes="secondary-btn", scale=0, min_width=50)
330
+
331
+ status = gr.Markdown("", elem_id="status-text")
332
 
333
+ # Output section
334
+ with gr.Column():
335
+ gr.Markdown("### 💬 ප්‍රතිචාරය")
336
+ output = gr.Markdown("", elem_id="output-box")
337
+ token_count = gr.Markdown("", elem_classes="token-counter")
 
338
 
339
+ # Examples section - compact
340
+ with gr.Accordion("📚 උදාහරණ", open=False):
341
+ with gr.Tab("🔢 ගණිතය"):
342
  gr.Examples(
343
  examples=[
344
  ["රු. 30 කින් මිලදී ගත් දේ රු. 60 නම් මිල වෙනස ප්‍රතිශතයකින් කීයද?", ""],
 
345
  ["2x + 5 = 15 සමීකරණය විසඳන්න.", ""],
346
  ],
347
+ inputs=[instruction, input_text],
348
  )
349
 
350
+ with gr.Tab("🎭 භූමිකා"):
351
  gr.Examples(
352
  examples=[
353
+ ["ඔබ ගුරුවරයෙකු ලෙස ක්‍රියාකරන්න.", "ගණිතය උගන්වන්න"],
 
354
  ["ඔබ පරිසර විද්‍යාඥයෙකු ලෙස වායු මණ්ඩලය පැහැදිලි කරන්න.", ""],
 
355
  ],
356
+ inputs=[instruction, input_text],
357
  )
358
 
359
+ with gr.Tab("❓ ප්‍රශ්න"):
360
  gr.Examples(
361
  examples=[
362
  ["ෆොටෝසින්තසිස් ක්‍රියාවලිය පැහැදිලි කරන්න.", ""],
363
  ["ජලයේ රසායනික සූත්‍රය කුමක්ද?", ""],
 
364
  ],
365
+ inputs=[instruction, input_text],
366
  )
367
 
368
+ with gr.Tab("🔤 භාෂාව"):
369
  gr.Examples(
370
  examples=[
371
  ["මෙම වාක්‍යය සිංහලයට පරිවර්තනය කරන්න: 'The sun rises in the east.'", ""],
372
  ["වචන 'ආදරය' සඳහා සමානාර්ථ පද 3ක් දෙන්න.", ""],
 
373
  ],
374
+ inputs=[instruction, input_text],
375
  )
376
 
377
+ # --- Processing functions ---
378
  def process_with_status(instruction, input_text, max_new_tokens):
379
  if not instruction.strip():
380
  return "⚠️ කරුණාකර උපදෙසක් ඇතුළත් කරන්න", gr.update(interactive=True), "", ""
 
389
  try:
390
  result = infer(instruction, input_text, max_new_tokens)
391
  approx_tokens = len(result.split())
392
+ token_info = f"📊 වචන {approx_tokens}ක් ආසන්න වශයෙන්"
393
  yield (
394
  "✅ සාර්ථකයි!",
395
+ gr.update(interactive=True, value="🚀 උත්පාදනය කරන්න"),
396
  result,
397
  token_info
398
  )
399
  except Exception as e:
400
  yield (
401
  f"❌ දෝෂයක්: {str(e)}",
402
+ gr.update(interactive=True, value="🚀 උත්පාදනය කරන්න"),
403
  "",
404
  ""
405
  )
406
 
407
  def clear_all():
408
+ return "", "", 512, "", gr.update(value="🚀 උත්පාදනය කරන්න", interactive=True), ""
409
+
410
+ # Scroll to top when example is clicked
411
+ def scroll_and_set(inst, inp):
412
+ return inst, inp
413
 
414
  run_btn.click(
415
  process_with_status,
 
425
 
426
  gr.HTML("""
427
  <div id='footer-info'>
428
+ <p style='margin-bottom:0.25rem;'>
429
+ 🪶 <strong>Model:</strong> <a href='https://huggingface.co/manthilaffs/Gamunu-4B-Instruct-Alpha' target='_blank'>Gamunu-4B-Instruct-Alpha</a>
430
  </p>
431
+ <p style='font-size:0.8rem; color:#868e96; margin:0;'>
432
+ © 2025 Gamunu Project | Experimental Release
433
  </p>
434
  </div>
435
  """)