Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -343,49 +343,284 @@ def generate_reply(
|
|
| 343 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 344 |
# 6. GRADIO CHAT INTERFACE โ ZeroGPU compatible (must use demo.launch())
|
| 345 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
latex_delimiters=[
|
| 351 |
{"left": "$$", "right": "$$", "display": True},
|
| 352 |
{"left": "$", "right": "$", "display": False},
|
| 353 |
{"left": "\\(", "right": "\\)", "display": False},
|
| 354 |
{"left": "\\[", "right": "\\]", "display": True},
|
| 355 |
],
|
| 356 |
-
)
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
gr.
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
|
| 390 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 391 |
# 7. LAUNCH โ must use demo.launch() for ZeroGPU @spaces.GPU registration
|
|
|
|
| 343 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 344 |
# 6. GRADIO CHAT INTERFACE โ ZeroGPU compatible (must use demo.launch())
|
| 345 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 346 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 347 |
+
# 6. GRADIO UI โ Custom design inspired by index.html
|
| 348 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 349 |
+
|
| 350 |
+
CSS = """
|
| 351 |
+
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap');
|
| 352 |
+
@import url('https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@400;500;700;800&display=swap');
|
| 353 |
+
|
| 354 |
+
:root {
|
| 355 |
+
--v: #6d28d9; --v2: #7c3aed; --teal: #0d9488;
|
| 356 |
+
--cream: #faf8f5; --ink: #1c1917; --ink3: #78716c; --ink4: #a8a29e;
|
| 357 |
+
--line: #e4dfd8; --fog: #ede9e3;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
/* Global overrides */
|
| 361 |
+
.gradio-container { background: var(--cream) !important; font-family: 'Cabinet Grotesk', sans-serif !important; }
|
| 362 |
+
footer { display: none !important; }
|
| 363 |
+
|
| 364 |
+
/* Animated background orbs */
|
| 365 |
+
#orbs { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
|
| 366 |
+
.orb { position: absolute; border-radius: 50%; filter: blur(80px); opacity: .45; animation: drift linear infinite; }
|
| 367 |
+
.orb1 { width: 500px; height: 500px; background: radial-gradient(circle, rgba(109,40,217,.35), transparent 70%); top: -100px; left: -100px; animation-duration: 22s; }
|
| 368 |
+
.orb2 { width: 380px; height: 380px; background: radial-gradient(circle, rgba(16,185,129,.28), transparent 70%); top: 5%; right: -60px; animation-duration: 28s; animation-delay: -9s; }
|
| 369 |
+
.orb3 { width: 320px; height: 320px; background: radial-gradient(circle, rgba(252,211,77,.22), transparent 70%); bottom: -60px; left: 35%; animation-duration: 19s; animation-delay: -5s; }
|
| 370 |
+
@keyframes drift { 0%{transform:translate(0,0) scale(1)} 33%{transform:translate(40px,-30px) scale(1.05)} 66%{transform:translate(-20px,20px) scale(.97)} 100%{transform:translate(0,0) scale(1)} }
|
| 371 |
+
.bg-grid { position: absolute; inset: 0; background-image: radial-gradient(circle, rgba(28,25,23,.05) 1px, transparent 1px); background-size: 28px 28px; }
|
| 372 |
+
|
| 373 |
+
/* Header banner */
|
| 374 |
+
#header-banner { text-align: center; padding: 24px 16px 8px; position: relative; z-index: 1; }
|
| 375 |
+
#header-banner .logo-icon { display: inline-flex; width: 56px; height: 56px; border-radius: 16px; background: linear-gradient(135deg, #6d28d9, #a78bfa, #10b981); align-items: center; justify-content: center; font-size: 28px; box-shadow: 0 8px 30px rgba(109,40,217,.25); margin-bottom: 10px; animation: float 4s ease-in-out infinite; }
|
| 376 |
+
@keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-6px)} }
|
| 377 |
+
#header-banner h1 { font-family: 'Instrument Serif', serif !important; font-size: 32px !important; color: var(--ink) !important; font-weight: 400 !important; margin: 0 !important; padding: 0 !important; background: none !important; }
|
| 378 |
+
#header-banner h1 em { color: var(--v); font-style: italic; }
|
| 379 |
+
#header-banner .sub { font-size: 13px; color: var(--ink3); margin-top: 4px; }
|
| 380 |
+
#header-banner .badges { display: flex; gap: 8px; justify-content: center; margin-top: 10px; flex-wrap: wrap; }
|
| 381 |
+
#header-banner .badge { font-size: 11px; font-weight: 600; padding: 4px 12px; border-radius: 20px; font-family: 'Geist Mono', monospace; }
|
| 382 |
+
.wb-purple { background: rgba(109,40,217,.08); color: var(--v); }
|
| 383 |
+
.wb-green { background: rgba(22,163,74,.08); color: #16a34a; }
|
| 384 |
+
.wb-amber { background: rgba(217,119,6,.08); color: #d97706; }
|
| 385 |
+
.wb-teal { background: rgba(13,148,136,.08); color: var(--teal); }
|
| 386 |
+
|
| 387 |
+
/* Model card */
|
| 388 |
+
#model-card { margin: 8px auto; max-width: 680px; padding: 14px 18px; border-radius: 12px; border: 1.5px solid rgba(109,40,217,.2); background: linear-gradient(135deg, rgba(109,40,217,.04), rgba(16,185,129,.03)); position: relative; z-index: 1; }
|
| 389 |
+
#model-card .mc-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
|
| 390 |
+
#model-card .mc-name { font-size: 13px; font-weight: 700; color: var(--ink); }
|
| 391 |
+
#model-card .mc-arch { font-size: 9px; font-weight: 700; padding: 2px 8px; border-radius: 10px; background: rgba(109,40,217,.08); color: var(--v); font-family: 'Geist Mono', monospace; letter-spacing: .4px; }
|
| 392 |
+
#model-card .mc-stats { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
|
| 393 |
+
#model-card .mc-stat { font-size: 9px; font-weight: 600; padding: 2px 7px; border-radius: 6px; font-family: 'Geist Mono', monospace; }
|
| 394 |
+
.mc-hl { background: rgba(109,40,217,.08); color: var(--v); }
|
| 395 |
+
.mc-ok { background: rgba(22,163,74,.09); color: #16a34a; }
|
| 396 |
+
#model-card .mc-desc { font-size: 10px; color: var(--ink3); line-height: 1.6; }
|
| 397 |
+
#model-card .mc-links { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
|
| 398 |
+
#model-card .mc-links a { font-size: 10px; font-weight: 700; padding: 3px 10px; border-radius: 16px; text-decoration: none; transition: all .2s; display: inline-flex; align-items: center; gap: 4px; }
|
| 399 |
+
|
| 400 |
+
/* Example cards */
|
| 401 |
+
#examples-area { max-width: 680px; margin: 12px auto; display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; position: relative; z-index: 1; }
|
| 402 |
+
.ex-card { background: white; border: 1.5px solid var(--line); border-radius: 12px; padding: 12px 14px; cursor: pointer; transition: all .22s; }
|
| 403 |
+
.ex-card:hover { border-color: rgba(109,40,217,.3); box-shadow: 0 2px 12px rgba(28,25,23,.06); transform: translateY(-2px); }
|
| 404 |
+
.ex-icon { font-size: 18px; display: block; margin-bottom: 4px; }
|
| 405 |
+
.ex-title { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 2px; }
|
| 406 |
+
.ex-desc { font-size: 10px; color: var(--ink4); }
|
| 407 |
+
|
| 408 |
+
/* Chat area styling */
|
| 409 |
+
#chatbot { border-radius: 16px !important; border: 1.5px solid var(--line) !important; background: rgba(255,255,255,.7) !important; backdrop-filter: blur(12px); position: relative; z-index: 1; }
|
| 410 |
+
#chatbot .message { font-family: 'Cabinet Grotesk', sans-serif !important; }
|
| 411 |
+
#chatbot .bot { background: rgba(109,40,217,.03) !important; border-left: 3px solid rgba(109,40,217,.2) !important; }
|
| 412 |
+
|
| 413 |
+
/* Settings row */
|
| 414 |
+
#settings-row { position: relative; z-index: 1; }
|
| 415 |
+
#settings-row .gr-accordion { border-radius: 12px !important; border: 1.5px solid var(--line) !important; background: rgba(255,255,255,.6) !important; }
|
| 416 |
+
|
| 417 |
+
/* Input area */
|
| 418 |
+
#chat-input { border-radius: 14px !important; border: 1.5px solid var(--line) !important; background: white !important; }
|
| 419 |
+
#chat-input:focus-within { border-color: rgba(109,40,217,.35) !important; box-shadow: 0 0 0 3px rgba(109,40,217,.08) !important; }
|
| 420 |
+
|
| 421 |
+
/* Submit button */
|
| 422 |
+
.primary { background: linear-gradient(135deg, var(--v), var(--v2)) !important; border: none !important; border-radius: 12px !important; }
|
| 423 |
+
|
| 424 |
+
/* Model dropdown */
|
| 425 |
+
#model-select .wrap { border-color: rgba(109,40,217,.2) !important; }
|
| 426 |
+
#model-select .wrap:focus-within { border-color: var(--v) !important; box-shadow: 0 0 0 3px rgba(109,40,217,.08) !important; }
|
| 427 |
+
|
| 428 |
+
@media(max-width:768px) {
|
| 429 |
+
#examples-area { grid-template-columns: 1fr; }
|
| 430 |
+
#header-banner h1 { font-size: 24px !important; }
|
| 431 |
+
}
|
| 432 |
+
"""
|
| 433 |
+
|
| 434 |
+
HEADER_HTML = """
|
| 435 |
+
<div id="orbs"><div class="orb orb1"></div><div class="orb orb2"></div><div class="orb orb3"></div><div class="bg-grid"></div></div>
|
| 436 |
+
<div id="header-banner">
|
| 437 |
+
<div class="logo-icon">๐</div>
|
| 438 |
+
<h1>Hello, I'm <em>Gemma 4</em></h1>
|
| 439 |
+
<div class="sub">Google DeepMind's most intelligent open model โ Dense 31B or MoE 26B-A4B ยท Vision ยท Thinking ยท Apache 2.0</div>
|
| 440 |
+
<div class="badges">
|
| 441 |
+
<span class="badge wb-purple">AIME 89.2%</span>
|
| 442 |
+
<span class="badge wb-green">GPQA 84.3%</span>
|
| 443 |
+
<span class="badge wb-amber">Codeforces 2150</span>
|
| 444 |
+
<span class="badge wb-teal">256K context</span>
|
| 445 |
+
<a href="https://huggingface.co/collections/google/gemma-4" target="_blank" class="badge wb-purple" style="text-decoration:none;">๐ค Gemma 4 โ</a>
|
| 446 |
+
</div>
|
| 447 |
+
</div>
|
| 448 |
+
"""
|
| 449 |
+
|
| 450 |
+
MODEL_CARD_HTML = """
|
| 451 |
+
<div id="model-card">
|
| 452 |
+
<div class="mc-top">
|
| 453 |
+
<span class="mc-name" id="mcName">Gemma-4-26B-A4B-it</span>
|
| 454 |
+
<span class="mc-arch" id="mcArch">MoE 3.8B / 26B</span>
|
| 455 |
+
</div>
|
| 456 |
+
<div class="mc-stats" id="mcStats">
|
| 457 |
+
<span class="mc-stat mc-hl">GPQA 82.3%</span>
|
| 458 |
+
<span class="mc-stat mc-ok">AIME 88.3%</span>
|
| 459 |
+
<span class="mc-stat mc-ok">๐๏ธ Vision</span>
|
| 460 |
+
<span class="mc-stat mc-ok">256K ctx</span>
|
| 461 |
+
</div>
|
| 462 |
+
<div class="mc-desc" id="mcDesc">MoE 128 experts ยท 3.8B active params ยท 31B์ 95% ์ฑ๋ฅ, ์ถ๋ก ~8๋ฐฐ ๋น ๋ฆ ยท 140+ languages</div>
|
| 463 |
+
<div class="mc-links">
|
| 464 |
+
<a id="mcHfLink" href="https://huggingface.co/google/gemma-4-26B-A4B-it" target="_blank" style="background:rgba(109,40,217,.08);color:#6d28d9;border:1px solid rgba(109,40,217,.15);">๐ค Model Card โ</a>
|
| 465 |
+
<a href="https://deepmind.google/models/gemma/gemma-4/" target="_blank" style="background:rgba(16,185,129,.08);color:#059669;border:1px solid rgba(16,185,129,.15);">๐ฌ DeepMind โ</a>
|
| 466 |
+
</div>
|
| 467 |
+
</div>
|
| 468 |
+
"""
|
| 469 |
+
|
| 470 |
+
EXAMPLES_HTML = """
|
| 471 |
+
<div id="examples-area">
|
| 472 |
+
<div class="ex-card" onclick="document.querySelector('#chat-input textarea').value='Explain how Gemma 4 MoE architecture works with 128 experts and hybrid attention.';document.querySelector('#chat-input textarea').dispatchEvent(new Event('input',{bubbles:true}));">
|
| 473 |
+
<span class="ex-icon">๐</span><div class="ex-title">Gemma 4 Architecture</div><div class="ex-desc">MoE + hybrid attention explained</div>
|
| 474 |
+
</div>
|
| 475 |
+
<div class="ex-card" onclick="document.querySelector('#chat-input textarea').value='Write a Python async web scraper with retry logic, rate limiting, and type hints.';document.querySelector('#chat-input textarea').dispatchEvent(new Event('input',{bubbles:true}));">
|
| 476 |
+
<span class="ex-icon">๐ป</span><div class="ex-title">Code Generation</div><div class="ex-desc">Production-quality Python</div>
|
| 477 |
+
</div>
|
| 478 |
+
<div class="ex-card" onclick="document.querySelector('#chat-input textarea').value='ํ๊ตญ์ K-pop์ด ์ธ๊ณ์ ์ผ๋ก ์ฑ๊ณตํ ์ด์ ๋ฅผ ๋ฌธํ์ , ๊ฒฝ์ ์ ๊ด์ ์์ ๋ถ์ํด์ฃผ์ธ์.';document.querySelector('#chat-input textarea').dispatchEvent(new Event('input',{bubbles:true}));">
|
| 479 |
+
<span class="ex-icon">๐</span><div class="ex-title">140+ Languages</div><div class="ex-desc">Korean, Japanese, Arabicโฆ</div>
|
| 480 |
+
</div>
|
| 481 |
+
<div class="ex-card" onclick="document.querySelector('#chat-input textarea').value='Solve: Find all real solutions to xยณ - 6xยฒ + 11x - 6 = 0. Show step-by-step reasoning.';document.querySelector('#chat-input textarea').dispatchEvent(new Event('input',{bubbles:true}));">
|
| 482 |
+
<span class="ex-icon">๐งฎ</span><div class="ex-title">Math Reasoning</div><div class="ex-desc">Step-by-step problem solving</div>
|
| 483 |
+
</div>
|
| 484 |
+
</div>
|
| 485 |
+
"""
|
| 486 |
+
|
| 487 |
+
# Model switcher JS (injected into the page)
|
| 488 |
+
MODEL_SWITCH_JS = """
|
| 489 |
+
<script>
|
| 490 |
+
const MODEL_INFO = {
|
| 491 |
+
'Gemma-4-26B-A4B-it': {
|
| 492 |
+
name: 'Gemma-4-26B-A4B-it', arch: 'MoE 3.8B / 26B',
|
| 493 |
+
stats: '<span class="mc-stat mc-hl">GPQA 82.3%</span><span class="mc-stat mc-ok">AIME 88.3%</span><span class="mc-stat mc-ok">๐๏ธ Vision</span><span class="mc-stat mc-ok">256K ctx</span>',
|
| 494 |
+
desc: 'MoE 128 experts ยท 3.8B active params ยท 31B์ 95% ์ฑ๋ฅ, ์ถ๋ก ~8๋ฐฐ ๋น ๋ฆ ยท 140+ languages',
|
| 495 |
+
hf: 'https://huggingface.co/google/gemma-4-26B-A4B-it'
|
| 496 |
+
},
|
| 497 |
+
'Gemma-4-31B-it': {
|
| 498 |
+
name: 'Gemma-4-31B-it', arch: 'Dense 30.7B',
|
| 499 |
+
stats: '<span class="mc-stat mc-hl">AIME 89.2%</span><span class="mc-stat mc-ok">GPQA 84.3%</span><span class="mc-stat mc-ok">๐๏ธ Vision</span><span class="mc-stat mc-ok">256K ctx</span>',
|
| 500 |
+
desc: 'Dense 31B ยท ์ต๊ณ ํ์ง ยท Codeforces 2150 ยท Arena ์คํ๋ชจ๋ธ 3์ ยท 140+ languages',
|
| 501 |
+
hf: 'https://huggingface.co/google/gemma-4-31B-it'
|
| 502 |
+
}
|
| 503 |
+
};
|
| 504 |
+
// Watch for model dropdown changes
|
| 505 |
+
new MutationObserver(() => {
|
| 506 |
+
const sel = document.querySelector('#model-select input');
|
| 507 |
+
if (!sel) return;
|
| 508 |
+
const val = sel.value;
|
| 509 |
+
const m = MODEL_INFO[val];
|
| 510 |
+
if (!m) return;
|
| 511 |
+
const n = document.getElementById('mcName');
|
| 512 |
+
if (n && n.textContent !== m.name) {
|
| 513 |
+
n.textContent = m.name;
|
| 514 |
+
document.getElementById('mcArch').textContent = m.arch;
|
| 515 |
+
document.getElementById('mcStats').innerHTML = m.stats;
|
| 516 |
+
document.getElementById('mcDesc').textContent = m.desc;
|
| 517 |
+
document.getElementById('mcHfLink').href = m.hf;
|
| 518 |
+
}
|
| 519 |
+
}).observe(document.body, {subtree: true, childList: true, characterData: true});
|
| 520 |
+
</script>
|
| 521 |
+
"""
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
with gr.Blocks(css=CSS, title="๐ Gemma 4 Playground", fill_height=True) as demo:
|
| 525 |
+
|
| 526 |
+
gr.HTML(HEADER_HTML)
|
| 527 |
+
gr.HTML(MODEL_CARD_HTML)
|
| 528 |
+
|
| 529 |
+
with gr.Accordion("โ๏ธ Settings", open=False, elem_id="settings-row"):
|
| 530 |
+
with gr.Row():
|
| 531 |
+
model_dd = gr.Dropdown(
|
| 532 |
+
choices=list(MODELS.keys()), value=DEFAULT_MODEL,
|
| 533 |
+
label="Model", elem_id="model-select", scale=2,
|
| 534 |
+
info="26B-A4B: MoE (fast) | 31B: Dense (best quality)",
|
| 535 |
+
)
|
| 536 |
+
thinking_radio = gr.Radio(
|
| 537 |
+
choices=["โก Fast", "๐ง Thinking"],
|
| 538 |
+
value="โก Fast", label="Mode", scale=1,
|
| 539 |
+
)
|
| 540 |
+
with gr.Row():
|
| 541 |
+
sys_prompt = gr.Textbox(
|
| 542 |
+
value=PRESETS["general"], label="System Prompt", lines=2, scale=3,
|
| 543 |
+
)
|
| 544 |
+
with gr.Row():
|
| 545 |
+
with gr.Column(scale=1):
|
| 546 |
+
preset_dd = gr.Dropdown(
|
| 547 |
+
choices=list(PRESETS.keys()), value="general",
|
| 548 |
+
label="Preset", info="Quick system prompt selection",
|
| 549 |
+
)
|
| 550 |
+
with gr.Column(scale=1):
|
| 551 |
+
max_tok_sl = gr.Slider(64, 8192, value=4096, step=64, label="Max Tokens")
|
| 552 |
+
with gr.Column(scale=1):
|
| 553 |
+
temp_sl = gr.Slider(0.0, 1.5, value=0.6, step=0.05, label="Temperature")
|
| 554 |
+
with gr.Column(scale=1):
|
| 555 |
+
topp_sl = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-P")
|
| 556 |
+
|
| 557 |
+
# Preset โ System Prompt
|
| 558 |
+
preset_dd.change(
|
| 559 |
+
fn=lambda k: PRESETS.get(k, PRESETS["general"]),
|
| 560 |
+
inputs=[preset_dd], outputs=[sys_prompt],
|
| 561 |
+
)
|
| 562 |
+
|
| 563 |
+
gr.HTML(EXAMPLES_HTML)
|
| 564 |
+
|
| 565 |
+
image_input = gr.Textbox(value="", visible=False)
|
| 566 |
+
|
| 567 |
+
chatbot = gr.Chatbot(
|
| 568 |
+
elem_id="chatbot", scale=1, type="messages",
|
| 569 |
latex_delimiters=[
|
| 570 |
{"left": "$$", "right": "$$", "display": True},
|
| 571 |
{"left": "$", "right": "$", "display": False},
|
| 572 |
{"left": "\\(", "right": "\\)", "display": False},
|
| 573 |
{"left": "\\[", "right": "\\]", "display": True},
|
| 574 |
],
|
| 575 |
+
)
|
| 576 |
+
|
| 577 |
+
with gr.Row():
|
| 578 |
+
chat_input = gr.Textbox(
|
| 579 |
+
placeholder="Message Gemma 4โฆ", lines=1, scale=7,
|
| 580 |
+
elem_id="chat-input", show_label=False, autofocus=True,
|
| 581 |
+
)
|
| 582 |
+
send_btn = gr.Button("Send", variant="primary", scale=1, min_width=80)
|
| 583 |
+
|
| 584 |
+
# โโ Chat logic โโ
|
| 585 |
+
def user_msg(message, history):
|
| 586 |
+
if not message.strip():
|
| 587 |
+
return "", history
|
| 588 |
+
history = history + [{"role": "user", "content": message}]
|
| 589 |
+
return "", history
|
| 590 |
+
|
| 591 |
+
def bot_reply(history, thinking_mode, image_data, system_prompt,
|
| 592 |
+
max_new_tokens, temperature, top_p, model_choice):
|
| 593 |
+
if not history or history[-1]["role"] != "user":
|
| 594 |
+
return history
|
| 595 |
+
|
| 596 |
+
user_text = history[-1]["content"]
|
| 597 |
+
past = history[:-1]
|
| 598 |
+
|
| 599 |
+
history = history + [{"role": "assistant", "content": ""}]
|
| 600 |
+
|
| 601 |
+
for chunk in generate_reply(
|
| 602 |
+
user_text, past, thinking_mode, image_data,
|
| 603 |
+
system_prompt, max_new_tokens, temperature, top_p, model_choice,
|
| 604 |
+
):
|
| 605 |
+
history[-1]["content"] = chunk
|
| 606 |
+
yield history
|
| 607 |
+
|
| 608 |
+
common_inputs = [
|
| 609 |
+
chatbot, thinking_radio, image_input, sys_prompt,
|
| 610 |
+
max_tok_sl, temp_sl, topp_sl, model_dd,
|
| 611 |
+
]
|
| 612 |
+
|
| 613 |
+
# Send on button click
|
| 614 |
+
send_btn.click(user_msg, [chat_input, chatbot], [chat_input, chatbot], queue=False).then(
|
| 615 |
+
bot_reply, common_inputs, chatbot,
|
| 616 |
+
)
|
| 617 |
+
# Send on Enter
|
| 618 |
+
chat_input.submit(user_msg, [chat_input, chatbot], [chat_input, chatbot], queue=False).then(
|
| 619 |
+
bot_reply, common_inputs, chatbot,
|
| 620 |
+
)
|
| 621 |
+
|
| 622 |
+
gr.HTML(MODEL_SWITCH_JS)
|
| 623 |
+
|
| 624 |
|
| 625 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 626 |
# 7. LAUNCH โ must use demo.launch() for ZeroGPU @spaces.GPU registration
|