Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -347,97 +347,95 @@ def generate_reply(
|
|
| 347 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 348 |
|
| 349 |
CSS = """
|
| 350 |
-
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap');
|
| 351 |
-
@import url('https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@400;500;700;800&display=swap');
|
| 352 |
-
|
| 353 |
footer { display: none !important; }
|
| 354 |
.gradio-container { background: #faf8f5 !important; }
|
| 355 |
-
|
| 356 |
-
.mcard { padding: 10px 12px; border-radius: 10px; border: 2px solid #e4dfd8; background: rgba(255,255,255,.6); cursor: pointer; transition: all .2s; margin-bottom: 6px; }
|
| 357 |
-
.mcard:hover { border-color: rgba(109,40,217,.3); box-shadow: 0 2px 10px rgba(109,40,217,.08); }
|
| 358 |
-
.mcard.active { border-color: #6d28d9 !important; background: linear-gradient(135deg, rgba(109,40,217,.06), rgba(16,185,129,.04)) !important; }
|
| 359 |
-
.mc-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
|
| 360 |
-
.mc-name { font-size: 13px; font-weight: 700; }
|
| 361 |
-
.mc-badge { font-size: 9px; font-weight: 700; padding: 2px 7px; border-radius: 8px; background: rgba(109,40,217,.08); color: #6d28d9; }
|
| 362 |
-
.mc-stats { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 4px; }
|
| 363 |
-
.mc-stat { font-size: 9px; font-weight: 600; padding: 1px 6px; border-radius: 5px; }
|
| 364 |
-
.mc-hl { background: rgba(109,40,217,.08); color: #6d28d9; }
|
| 365 |
-
.mc-ok { background: rgba(22,163,74,.09); color: #16a34a; }
|
| 366 |
-
.mc-desc { font-size: 10px; color: #78716c; }
|
| 367 |
-
.mc-check { display: none; } .mcard.active .mc-check { display: inline; }
|
| 368 |
-
|
| 369 |
-
.pchip { display: inline-block; font-size: 10px; font-weight: 600; padding: 3px 10px; border-radius: 16px; background: #ede9e3; border: 1px solid #e4dfd8; color: #78716c; cursor: pointer; transition: all .2s; margin: 2px; }
|
| 370 |
-
.pchip:hover { background: rgba(109,40,217,.08); border-color: rgba(109,40,217,.25); color: #6d28d9; }
|
| 371 |
-
|
| 372 |
#send-btn { background: linear-gradient(135deg, #6d28d9, #7c3aed) !important; border: none !important; border-radius: 12px !important; color: white !important; font-size: 18px !important; min-width: 48px !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
"""
|
| 374 |
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
</
|
| 381 |
-
<
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
</div>
|
| 386 |
-
"""
|
| 387 |
-
|
| 388 |
-
PRESETS_CHIPS = '<div style="margin-bottom:8px">' + ''.join(
|
| 389 |
-
f'<span class="pchip" onclick="window._pre(\'{k}\')">{k.title()}</span>' for k in PRESETS
|
| 390 |
-
) + '</div>'
|
| 391 |
-
|
| 392 |
-
JS = """<script>
|
| 393 |
-
window._sel=function(n){
|
| 394 |
-
document.querySelectorAll('.mcard').forEach(function(c){c.classList.remove('active')});
|
| 395 |
-
document.getElementById(n==='Gemma-4-26B-A4B-it'?'card-moe':'card-dense').classList.add('active');
|
| 396 |
-
var d=document.querySelector('#model-dd input');
|
| 397 |
-
if(d){var s=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set;s.call(d,n);d.dispatchEvent(new Event('input',{bubbles:true}));}
|
| 398 |
-
};
|
| 399 |
-
window._pre=function(k){
|
| 400 |
-
var p=""" + json.dumps(PRESETS) + """;
|
| 401 |
-
var t=document.querySelector('#sys-prompt textarea');
|
| 402 |
-
if(t){var s=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,'value').set;s.call(t,p[k]||p.general);t.dispatchEvent(new Event('input',{bubbles:true}));}
|
| 403 |
-
};
|
| 404 |
-
</script>"""
|
| 405 |
|
| 406 |
with gr.Blocks(title="Gemma 4 Playground") as demo:
|
| 407 |
|
| 408 |
-
gr.Markdown("## π Gemma 4 Playground\nGoogle DeepMind Β· Dense 31B
|
| 409 |
|
| 410 |
with gr.Row():
|
| 411 |
-
#
|
| 412 |
-
with gr.Column(scale=0, min_width=
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
max_tok = gr.Slider(64, 8192, value=4096, step=64, label="Max Tokens")
|
| 420 |
temp = gr.Slider(0.0, 1.5, value=0.6, step=0.05, label="Temperature")
|
| 421 |
topp = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-P")
|
| 422 |
-
clear_btn = gr.Button("ποΈ Clear", size="sm")
|
| 423 |
|
| 424 |
-
#
|
| 425 |
with gr.Column(scale=3):
|
| 426 |
-
chatbot = gr.Chatbot(elem_id="chatbot", show_label=False, height=
|
| 427 |
-
image_input = gr.Textbox(value="", visible=False)
|
| 428 |
with gr.Row():
|
| 429 |
-
chat_input = gr.Textbox(
|
|
|
|
|
|
|
|
|
|
| 430 |
send_btn = gr.Button("β", variant="primary", scale=0, min_width=48, elem_id="send-btn")
|
| 431 |
|
| 432 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
|
| 434 |
-
# ββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
def user_msg(msg, hist):
|
| 436 |
-
if not msg.strip():
|
|
|
|
| 437 |
return "", hist + [{"role": "user", "content": msg}]
|
| 438 |
|
| 439 |
def bot_reply(hist, think, img, sysp, maxt, tmp, tp, model):
|
| 440 |
-
if not hist or hist[-1]["role"] != "user":
|
|
|
|
| 441 |
txt, past = hist[-1]["content"], hist[:-1]
|
| 442 |
hist = hist + [{"role": "assistant", "content": ""}]
|
| 443 |
for chunk in generate_reply(txt, past, think, img, sysp, maxt, tmp, tp, model):
|
|
@@ -445,10 +443,23 @@ with gr.Blocks(title="Gemma 4 Playground") as demo:
|
|
| 445 |
yield hist
|
| 446 |
|
| 447 |
ins = [chatbot, thinking_radio, image_input, sys_prompt, max_tok, temp, topp, model_dd]
|
| 448 |
-
|
| 449 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 450 |
clear_btn.click(lambda: [], None, chatbot, queue=False)
|
| 451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
if __name__ == "__main__":
|
| 453 |
print(f"[BOOT] Gemma 4 Playground Β· Default: {DEFAULT_MODEL}", flush=True)
|
| 454 |
demo.launch(server_name="0.0.0.0", server_port=7860, css=CSS)
|
|
|
|
| 347 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 348 |
|
| 349 |
CSS = """
|
|
|
|
|
|
|
|
|
|
| 350 |
footer { display: none !important; }
|
| 351 |
.gradio-container { background: #faf8f5 !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
#send-btn { background: linear-gradient(135deg, #6d28d9, #7c3aed) !important; border: none !important; border-radius: 12px !important; color: white !important; font-size: 18px !important; min-width: 48px !important; }
|
| 353 |
+
#chatbot { border: 1.5px solid #e4dfd8 !important; border-radius: 14px !important; background: rgba(255,255,255,.65) !important; }
|
| 354 |
+
.model-info-box { padding: 10px 14px; border-radius: 10px; border: 1.5px solid rgba(109,40,217,.2); background: linear-gradient(135deg, rgba(109,40,217,.04), rgba(16,185,129,.03)); font-size: 12px; line-height: 1.6; }
|
| 355 |
+
.model-info-box b { color: #6d28d9; }
|
| 356 |
+
.model-info-box .stats { font-size: 10px; color: #78716c; margin-top: 4px; }
|
| 357 |
"""
|
| 358 |
|
| 359 |
+
# Model info display (updates when dropdown changes)
|
| 360 |
+
def _model_info_html(name):
|
| 361 |
+
m = MODELS.get(name, MODELS[DEFAULT_MODEL])
|
| 362 |
+
return (
|
| 363 |
+
f'<div class="model-info-box">'
|
| 364 |
+
f'<b>{"β‘" if m["arch"]=="MoE" else "π"} {name}</b> '
|
| 365 |
+
f'<span style="font-size:9px;padding:2px 6px;border-radius:6px;background:rgba(109,40,217,.08);color:#6d28d9;font-weight:700">{m["arch"]}</span><br>'
|
| 366 |
+
f'<div class="stats">{m["active"]} active / {m["total"]} total Β· ποΈ Vision Β· {m["ctx"]} context<br>{m["desc"]}</div>'
|
| 367 |
+
f'</div>'
|
| 368 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
|
| 370 |
with gr.Blocks(title="Gemma 4 Playground") as demo:
|
| 371 |
|
| 372 |
+
gr.Markdown("## π Gemma 4 Playground\nGoogle DeepMind Β· Dense 31B or MoE 26B-A4B Β· Vision Β· Thinking Β· Apache 2.0")
|
| 373 |
|
| 374 |
with gr.Row():
|
| 375 |
+
# ββ Sidebar ββ
|
| 376 |
+
with gr.Column(scale=0, min_width=300):
|
| 377 |
+
|
| 378 |
+
gr.Markdown("#### Select Model")
|
| 379 |
+
model_dd = gr.Dropdown(
|
| 380 |
+
choices=list(MODELS.keys()), value=DEFAULT_MODEL,
|
| 381 |
+
label="Model", elem_id="model-dd",
|
| 382 |
+
info="MoE=Fast inference | Dense=Best quality",
|
| 383 |
+
)
|
| 384 |
+
model_info = gr.HTML(value=_model_info_html(DEFAULT_MODEL))
|
| 385 |
+
|
| 386 |
+
gr.Markdown("---")
|
| 387 |
+
gr.Markdown("#### ποΈ Vision")
|
| 388 |
+
image_input = gr.Image(label="Upload image", type="filepath", height=150)
|
| 389 |
+
|
| 390 |
+
gr.Markdown("---")
|
| 391 |
+
gr.Markdown("#### Settings")
|
| 392 |
+
thinking_radio = gr.Radio(
|
| 393 |
+
["β‘ Fast", "π§ Thinking"], value="β‘ Fast", label="Mode",
|
| 394 |
+
)
|
| 395 |
+
sys_prompt = gr.Textbox(
|
| 396 |
+
value=PRESETS["general"], label="System Prompt", lines=2,
|
| 397 |
+
)
|
| 398 |
+
preset_dd = gr.Dropdown(
|
| 399 |
+
choices=list(PRESETS.keys()), value="general", label="Preset",
|
| 400 |
+
)
|
| 401 |
max_tok = gr.Slider(64, 8192, value=4096, step=64, label="Max Tokens")
|
| 402 |
temp = gr.Slider(0.0, 1.5, value=0.6, step=0.05, label="Temperature")
|
| 403 |
topp = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-P")
|
| 404 |
+
clear_btn = gr.Button("ποΈ Clear conversation", size="sm")
|
| 405 |
|
| 406 |
+
# ββ Chat ββ
|
| 407 |
with gr.Column(scale=3):
|
| 408 |
+
chatbot = gr.Chatbot(elem_id="chatbot", show_label=False, height=600)
|
|
|
|
| 409 |
with gr.Row():
|
| 410 |
+
chat_input = gr.Textbox(
|
| 411 |
+
placeholder="Message Gemma 4β¦", show_label=False,
|
| 412 |
+
scale=7, autofocus=True, lines=1, max_lines=4,
|
| 413 |
+
)
|
| 414 |
send_btn = gr.Button("β", variant="primary", scale=0, min_width=48, elem_id="send-btn")
|
| 415 |
|
| 416 |
+
# ββ Events: model info update ββ
|
| 417 |
+
model_dd.change(
|
| 418 |
+
fn=_model_info_html,
|
| 419 |
+
inputs=[model_dd],
|
| 420 |
+
outputs=[model_info],
|
| 421 |
+
)
|
| 422 |
|
| 423 |
+
# ββ Events: preset β system prompt ββ
|
| 424 |
+
preset_dd.change(
|
| 425 |
+
fn=lambda k: PRESETS.get(k, PRESETS["general"]),
|
| 426 |
+
inputs=[preset_dd],
|
| 427 |
+
outputs=[sys_prompt],
|
| 428 |
+
)
|
| 429 |
+
|
| 430 |
+
# ββ Chat logic ββ
|
| 431 |
def user_msg(msg, hist):
|
| 432 |
+
if not msg.strip():
|
| 433 |
+
return "", hist
|
| 434 |
return "", hist + [{"role": "user", "content": msg}]
|
| 435 |
|
| 436 |
def bot_reply(hist, think, img, sysp, maxt, tmp, tp, model):
|
| 437 |
+
if not hist or hist[-1]["role"] != "user":
|
| 438 |
+
return hist
|
| 439 |
txt, past = hist[-1]["content"], hist[:-1]
|
| 440 |
hist = hist + [{"role": "assistant", "content": ""}]
|
| 441 |
for chunk in generate_reply(txt, past, think, img, sysp, maxt, tmp, tp, model):
|
|
|
|
| 443 |
yield hist
|
| 444 |
|
| 445 |
ins = [chatbot, thinking_radio, image_input, sys_prompt, max_tok, temp, topp, model_dd]
|
| 446 |
+
|
| 447 |
+
send_btn.click(
|
| 448 |
+
user_msg, [chat_input, chatbot], [chat_input, chatbot], queue=False
|
| 449 |
+
).then(
|
| 450 |
+
bot_reply, ins, chatbot
|
| 451 |
+
)
|
| 452 |
+
chat_input.submit(
|
| 453 |
+
user_msg, [chat_input, chatbot], [chat_input, chatbot], queue=False
|
| 454 |
+
).then(
|
| 455 |
+
bot_reply, ins, chatbot
|
| 456 |
+
)
|
| 457 |
clear_btn.click(lambda: [], None, chatbot, queue=False)
|
| 458 |
|
| 459 |
+
|
| 460 |
+
# ββββββββοΏ½οΏ½βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 461 |
+
# 7. LAUNCH
|
| 462 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 463 |
if __name__ == "__main__":
|
| 464 |
print(f"[BOOT] Gemma 4 Playground Β· Default: {DEFAULT_MODEL}", flush=True)
|
| 465 |
demo.launch(server_name="0.0.0.0", server_port=7860, css=CSS)
|