Ilyasch2 commited on
Commit
130e454
Β·
1 Parent(s): f9f9e2c
Files changed (1) hide show
  1. app.py +138 -131
app.py CHANGED
@@ -1,192 +1,199 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- """
4
- Private multi-backend playground (Falcon-H1 family).
5
-
6
- Visual refresh + collapsible β€œβš™οΈ Parameters” panel toggled by a gear button.
7
- All secrets stay server-side.
8
- """
9
  import os
10
  from datetime import date
11
  import gradio as gr
12
  import openai
13
 
14
-
15
- # ─────────────────────────── CONFIG ────────────────────────────
16
  MODEL_CONFIGS = {
17
  "Falcon-H1-34B-Instruct": {
18
  "model_id": "tiiuae/Falcon-H1-34B-Instruct",
19
  "api_key_env": "XXL_API_KEY",
20
  "base_url_env": "XXL_URL",
 
21
  },
22
  "Falcon-H1-7B-Instruct": {
23
  "model_id": "tiiuae/Falcon-H1-7B-Instruct",
24
  "api_key_env": "L_API_KEY",
25
  "base_url_env": "L_URL",
 
26
  },
27
  "Falcon-H1-3B-Instruct": {
28
  "model_id": "tiiuae/Falcon-H1-3B-Instruct",
29
  "api_key_env": "M_API_KEY",
30
  "base_url_env": "M_URL",
 
31
  },
32
  "Falcon-H1-1.5B-Deep-Instruct": {
33
  "model_id": "tiiuae/Falcon-H1-1.5B-Deep-Instruct",
34
  "api_key_env": "S_API_KEY",
35
  "base_url_env": "S_URL",
 
36
  },
37
  "Falcon-H1-1.5B-Instruct": {
38
  "model_id": "tiiuae/Falcon-H1-1.5B-Instruct",
39
  "api_key_env": "XS_API_KEY",
40
  "base_url_env": "XS_URL",
 
41
  },
42
  "Falcon-H1-0.5B-Instruct": {
43
  "model_id": "tiiuae/Falcon-H1-0.5B-Instruct",
44
  "api_key_env": "XXS_API_KEY",
45
  "base_url_env": "XXS_URL",
 
46
  },
47
  }
48
 
49
- # ─────────────────────────── STYLING ────────────────────────────
50
- TITLE = "<h1><center>Private multi-backend playground</center></h1>"
51
- SUBTITLE = "<center>Keys &amp; endpoints stay <em>server-side</em>; the browser never sees them.</center>"
52
 
 
53
  CSS = """
54
- body{font-family:'Inter',system-ui,sans-serif;background:linear-gradient(135deg,#eef2f8 0%,#f5f9fd 100%) fixed;}
55
- .gradio-container{max-width:900px;margin:0 auto;padding-bottom:48px;}
56
- h1{font-weight:700;font-size:2.4rem;margin:0.6em 0;color:#111;}
57
- #dup-btn{margin:auto!important;border-radius:1.5rem!important;background:#1f1f1f!important;color:#fff!important}
58
- #settings-btn{position:absolute;top:14px;right:14px;border:none;background:transparent;font-size:1.55rem;cursor:pointer;transition:transform .15s}
59
- #settings-btn:hover{transform:scale(1.18);}
60
- .gr-chat-message.user{background:#e5f2ff;border-radius:1.25rem!important}
61
- .gr-chat-message.assistant{background:#ffffff;border-radius:1.25rem!important}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  """
63
 
64
- # ──────────────────────── CHAT FUNCTION ────────────────────────
65
  def stream_chat(
66
  message: str,
67
  history: list,
68
- model_label: str,
69
  temperature: float = 0.7,
70
  max_new_tokens: int = 1024,
71
  top_p: float = 1.0,
72
- penalty: float = 1.2,
73
  ):
74
- cfg = MODEL_CONFIGS[model_label]
 
 
75
  api_key = os.getenv(cfg["api_key_env"])
76
- base_url = os.getenv(cfg["base_url_env"], None)
77
-
78
  if not api_key:
79
- yield f"❌ Env-var {cfg['api_key_env']} not set."
80
  return
 
81
  if cfg.get("base_url_env") and not base_url:
82
- yield f"❌ Env-var {cfg['base_url_env']} not set."
83
  return
84
-
85
  client = openai.OpenAI(api_key=api_key, base_url=base_url)
86
-
87
- # Build message list from history
88
  msgs = []
89
- for user_msg, bot_msg in history:
90
- msgs.append({"role": "user", "content": user_msg})
91
- msgs.append({"role": "assistant", "content": bot_msg})
92
  msgs.append({"role": "user", "content": message})
93
-
94
- stream = client.chat.completions.create(
95
- model=cfg["model_id"],
96
- messages=msgs,
97
- temperature=temperature,
98
- top_p=top_p,
99
- max_tokens=max_new_tokens,
100
- presence_penalty=penalty,
101
- stream=True,
102
- )
103
-
104
- partial = ""
105
- for chunk in stream:
106
- delta = chunk.choices[0].delta
107
- if delta and delta.content:
108
- partial += delta.content
109
- yield partial
110
-
111
-
112
- # ──────────────────────────── UI ───────────────────────────────
113
- with gr.Blocks(css=CSS, theme="soft") as demo:
114
- gr.HTML(TITLE)
115
- gr.HTML(SUBTITLE)
116
-
117
- # Duplicate-space helper
118
- gr.DuplicateButton(value="Duplicate Space", elem_id="dup-btn")
119
-
120
- # Gear button (absolute-positioned)
121
- gear_btn = gr.Button("βš™οΈ", elem_id="settings-btn", variant="secondary")
122
-
123
- # Hidden/visible state for the parameter panel
124
- params_open = gr.State(False)
125
-
126
- # Collapsible parameter section (starts closed & invisible)
127
- with gr.Accordion("Parameters", open=False, visible=False, elem_id="param-panel") as param_panel:
128
- model_dd = gr.Dropdown(
129
- choices=list(MODEL_CONFIGS.keys()),
130
- value=list(MODEL_CONFIGS.keys())[0],
131
- label="Model",
132
- )
133
- temp = gr.Slider(0, 1, value=0.7, step=0.1, label="Temperature")
134
- max_tok = gr.Slider(64, 4096 * 8, value=1024, step=64, label="Max new tokens")
135
- top_p = gr.Slider(0, 1, value=1.0, step=0.01, label="Top-p")
136
- penalty = gr.Slider(0, 2, value=1.2, step=0.1, label="Presence penalty")
137
-
138
- # Toggle logic: gear button ↔ parameter accordion
139
- def _toggle_panel(open_now: bool):
140
- """Flip visibility + open/close state."""
141
- new_state = not open_now
142
- return (
143
- new_state, # update hidden state
144
- gr.update(visible=True, open=new_state), # accordion update
145
  )
146
-
147
- gear_btn.click(
148
- _toggle_panel,
149
- inputs=params_open,
150
- outputs=[params_open, param_panel],
151
- queue=False,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  )
153
-
154
- # Chatbot component
155
- chatbot = gr.Chatbot(height=560)
156
-
157
- # Textbox & interaction handled by ChatInterface-like row
158
- with gr.Row():
159
- txt = gr.Textbox(
160
- scale=8,
161
- placeholder="Ask anything…",
162
- show_label=False
163
- )
164
- submit = gr.Button("Send", scale=1)
165
-
166
- def _proxy_send(user_message, chat_hist, mdl, t, mx_toks, tp, pp):
167
- return stream_chat(
168
- user_message,
169
- chat_hist,
170
- model_label=mdl,
171
- temperature=t,
172
- max_new_tokens=int(mx_toks),
173
- top_p=tp,
174
- penalty=pp,
175
- )
176
-
177
- # Wiring
178
- submit.click(
179
- _proxy_send,
180
- inputs=[txt, chatbot, model_dd, temp, max_tok, top_p, penalty],
181
- outputs=chatbot,
182
- ).then(lambda: "", None, txt) # clear textbox afterwards
183
-
184
- txt.submit(
185
- _proxy_send,
186
- inputs=[txt, chatbot, model_dd, temp, max_tok, top_p, penalty],
187
- outputs=chatbot,
188
- ).then(lambda: "", None, txt)
189
-
190
 
191
  if __name__ == "__main__":
192
- demo.launch()
 
 
 
 
 
 
 
 
 
1
  import os
2
  from datetime import date
3
  import gradio as gr
4
  import openai
5
 
6
+ # Model configuration dictionary
 
7
  MODEL_CONFIGS = {
8
  "Falcon-H1-34B-Instruct": {
9
  "model_id": "tiiuae/Falcon-H1-34B-Instruct",
10
  "api_key_env": "XXL_API_KEY",
11
  "base_url_env": "XXL_URL",
12
+ "description": "XXL (34B)"
13
  },
14
  "Falcon-H1-7B-Instruct": {
15
  "model_id": "tiiuae/Falcon-H1-7B-Instruct",
16
  "api_key_env": "L_API_KEY",
17
  "base_url_env": "L_URL",
18
+ "description": "L (7B)"
19
  },
20
  "Falcon-H1-3B-Instruct": {
21
  "model_id": "tiiuae/Falcon-H1-3B-Instruct",
22
  "api_key_env": "M_API_KEY",
23
  "base_url_env": "M_URL",
24
+ "description": "M (3B)"
25
  },
26
  "Falcon-H1-1.5B-Deep-Instruct": {
27
  "model_id": "tiiuae/Falcon-H1-1.5B-Deep-Instruct",
28
  "api_key_env": "S_API_KEY",
29
  "base_url_env": "S_URL",
30
+ "description": "S (1.5B Deep)"
31
  },
32
  "Falcon-H1-1.5B-Instruct": {
33
  "model_id": "tiiuae/Falcon-H1-1.5B-Instruct",
34
  "api_key_env": "XS_API_KEY",
35
  "base_url_env": "XS_URL",
36
+ "description": "XS (1.5B)"
37
  },
38
  "Falcon-H1-0.5B-Instruct": {
39
  "model_id": "tiiuae/Falcon-H1-0.5B-Instruct",
40
  "api_key_env": "XXS_API_KEY",
41
  "base_url_env": "XXS_URL",
42
+ "description": "XXS (0.5B)"
43
  },
44
  }
45
 
46
+ today = date.today()
 
 
47
 
48
+ # Simplified CSS focusing on essential elements
49
  CSS = """
50
+ /* Main style improvements */
51
+ .container {
52
+ max-width: 900px !important;
53
+ margin-left: auto !important;
54
+ margin-right: auto !important;
55
+ }
56
+
57
+ /* Title styling */
58
+ h1 {
59
+ background: linear-gradient(90deg, #4776E6 0%, #8E54E9 100%);
60
+ -webkit-background-clip: text;
61
+ -webkit-text-fill-color: transparent;
62
+ font-weight: 700 !important;
63
+ text-align: center;
64
+ margin-bottom: 0.5rem !important;
65
+ }
66
+
67
+ .subtitle {
68
+ text-align: center;
69
+ color: #666;
70
+ margin-bottom: 1rem;
71
+ }
72
+
73
+ /* Button styling */
74
+ .duplicate-button {
75
+ margin: 1rem auto !important;
76
+ display: block !important;
77
+ color: #fff !important;
78
+ background: linear-gradient(90deg, #4776E6 0%, #8E54E9 100%) !important;
79
+ border-radius: 100vh !important;
80
+ padding: 0.5rem 1.5rem !important;
81
+ font-weight: 600 !important;
82
+ border: none !important;
83
+ box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08) !important;
84
+ }
85
+
86
+ /* Parameter accordion styling */
87
+ .accordion {
88
+ border-radius: 8px !important;
89
+ overflow: hidden !important;
90
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
91
+ margin-bottom: 1rem !important;
92
+ }
93
+
94
+ /* Model dropdown styling */
95
+ .model-dropdown .label-wrap span:first-child {
96
+ font-weight: 600 !important;
97
+ }
98
+
99
+ /* Improve model description display */
100
+ .model-dropdown .wrap .value-wrap span {
101
+ display: flex !important;
102
+ align-items: center !important;
103
+ gap: 6px !important;
104
+ }
105
+
106
+ .model-description {
107
+ font-size: 0.85rem !important;
108
+ opacity: 0.75 !important;
109
+ font-weight: normal !important;
110
+ }
111
  """
112
 
 
113
  def stream_chat(
114
  message: str,
115
  history: list,
116
+ model_name: str,
117
  temperature: float = 0.7,
118
  max_new_tokens: int = 1024,
119
  top_p: float = 1.0,
120
+ presence_penalty: float = 1.2,
121
  ):
122
+ """Chat function that streams responses from the selected model"""
123
+
124
+ cfg = MODEL_CONFIGS[model_name]
125
  api_key = os.getenv(cfg["api_key_env"])
126
+ base_url = os.getenv(cfg.get("base_url_env", ""), None)
127
+
128
  if not api_key:
129
+ yield f"❌ Env-var `{cfg['api_key_env']}` not set."
130
  return
131
+
132
  if cfg.get("base_url_env") and not base_url:
133
+ yield f"❌ Env-var `{cfg['base_url_env']}` not set."
134
  return
135
+
136
  client = openai.OpenAI(api_key=api_key, base_url=base_url)
137
+
 
138
  msgs = []
139
+ for u, a in history:
140
+ msgs += [{"role": "user", "content": u},
141
+ {"role": "assistant", "content": a}]
142
  msgs.append({"role": "user", "content": message})
143
+
144
+ try:
145
+ stream = client.chat.completions.create(
146
+ model=cfg["model_id"],
147
+ messages=msgs,
148
+ temperature=temperature,
149
+ top_p=top_p,
150
+ max_tokens=max_new_tokens,
151
+ presence_penalty=presence_penalty,
152
+ stream=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  )
154
+
155
+ partial = ""
156
+ for chunk in stream:
157
+ if (delta := chunk.choices[0].delta).content:
158
+ partial += delta.content
159
+ yield partial
160
+ except Exception as e:
161
+ yield f"❌ Error: {str(e)}"
162
+
163
+ # Create the Gradio interface
164
+ with gr.Blocks(css=CSS, theme="soft") as demo:
165
+ # Header section
166
+ gr.HTML("<h1>Private multi-backend playground</h1>")
167
+ gr.HTML("<p class='subtitle'>Keys & endpoints stay server-side; the browser never sees them.</p>")
168
+ gr.HTML(f"<p class='subtitle' style='font-size: 0.9rem; color: #888;'>Today: {today.strftime('%B %d, %Y')}</p>")
169
+
170
+ gr.DuplicateButton(value="Duplicate Space", elem_classes="duplicate-button")
171
+
172
+ # Create chatbot
173
+ chatbot = gr.Chatbot(height=600)
174
+
175
+ # Create model selection with descriptions
176
+ model_options = list(MODEL_CONFIGS.keys())
177
+ model_dropdown = gr.Dropdown(
178
+ choices=model_options,
179
+ value=model_options[0],
180
+ label="Model",
181
+ elem_classes="model-dropdown"
182
+ )
183
+
184
+ # Create ChatInterface with collapsible parameters
185
+ chat_interface = gr.ChatInterface(
186
+ fn=stream_chat,
187
+ chatbot=chatbot,
188
+ additional_inputs=[
189
+ model_dropdown,
190
+ gr.Slider(0, 1, value=0.7, step=0.05, label="Temperature", info="Higher values produce more diverse outputs"),
191
+ gr.Slider(64, 4096*8, value=1024, step=64, label="Max new tokens", info="Maximum length of generated response"),
192
+ gr.Slider(0, 1, value=1.0, step=0.05, label="top_p", info="1.0 means no filtering"),
193
+ gr.Slider(0, 2, value=1.2, step=0.1, label="Presence penalty", info="Penalizes repetition")
194
+ ],
195
+ additional_inputs_accordion=gr.Accordion("βš™οΈ Parameters", open=False, elem_classes="accordion")
196
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
 
198
  if __name__ == "__main__":
199
+ demo.launch()