Ilyasch2 commited on
Commit
2e91549
·
1 Parent(s): c7a6dc8
Files changed (1) hide show
  1. app.py +81 -169
app.py CHANGED
@@ -9,126 +9,68 @@ MODEL_CONFIGS = {
9
  "model_id": "tiiuae/Falcon-H1-34B-Instruct",
10
  "api_key_env": "XXL_API_KEY",
11
  "base_url_env": "XXL_URL",
12
- "badge_color": "red",
13
- "description": "Largest model (34B parameters)"
14
  },
15
  "Falcon-H1-7B-Instruct": {
16
  "model_id": "tiiuae/Falcon-H1-7B-Instruct",
17
  "api_key_env": "L_API_KEY",
18
  "base_url_env": "L_URL",
19
- "badge_color": "orange",
20
- "description": "Large model (7B parameters)"
21
  },
22
  "Falcon-H1-3B-Instruct": {
23
  "model_id": "tiiuae/Falcon-H1-3B-Instruct",
24
  "api_key_env": "M_API_KEY",
25
  "base_url_env": "M_URL",
26
- "badge_color": "yellow",
27
- "description": "Medium model (3B parameters)"
28
  },
29
  "Falcon-H1-1.5B-Deep-Instruct": {
30
  "model_id": "tiiuae/Falcon-H1-1.5B-Deep-Instruct",
31
  "api_key_env": "S_API_KEY",
32
  "base_url_env": "S_URL",
33
- "badge_color": "green",
34
- "description": "Small model with deeper training (1.5B parameters)"
35
  },
36
  "Falcon-H1-1.5B-Instruct": {
37
  "model_id": "tiiuae/Falcon-H1-1.5B-Instruct",
38
  "api_key_env": "XS_API_KEY",
39
  "base_url_env": "XS_URL",
40
- "badge_color": "blue",
41
- "description": "Extra small model (1.5B parameters)"
42
  },
43
  "Falcon-H1-0.5B-Instruct": {
44
  "model_id": "tiiuae/Falcon-H1-0.5B-Instruct",
45
  "api_key_env": "XXS_API_KEY",
46
  "base_url_env": "XXS_URL",
47
- "badge_color": "indigo",
48
- "description": "Extra-extra small model (0.5B parameters)"
49
  },
50
  }
51
 
52
- # Hex colors for badges (matching the CSS)
53
- BADGE_HEX_COLORS = {
54
- "red": "#e53e3e",
55
- "orange": "#ed8936",
56
- "yellow": "#d69e2e",
57
- "green": "#38a169",
58
- "blue": "#3182ce",
59
- "indigo": "#5a67d8",
60
- }
61
-
62
  today = date.today()
63
- # Enhanced styling with modern, clean look
 
64
  CSS = """
65
- /* Overall theming */
66
- body {
67
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
 
 
68
  }
69
- /* Header and title styling */
70
- .header-container {
71
- margin-bottom: 1.5rem;
72
- text-align: center;
73
- }
74
- h1.main-title {
75
- font-size: 2.5rem !important;
76
- font-weight: 700 !important;
77
  background: linear-gradient(90deg, #4776E6 0%, #8E54E9 100%);
78
  -webkit-background-clip: text;
79
  -webkit-text-fill-color: transparent;
 
 
80
  margin-bottom: 0.5rem !important;
81
  }
 
82
  .subtitle {
83
- font-size: 1.1rem;
84
  color: #666;
85
  margin-bottom: 1rem;
86
  }
87
- /* Model selection styling */
88
- .model-dropdown label span:first-of-type {
89
- font-weight: 600 !important;
90
- font-size: 1.1rem !important;
91
- }
92
- /* Parameter styling */
93
- .parameters-container {
94
- border-radius: 12px !important;
95
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05) !important;
96
- margin-top: 1rem !important;
97
- overflow: hidden !important;
98
- }
99
- .parameters-header {
100
- font-weight: 600 !important;
101
- font-size: 1.1rem !important;
102
- }
103
- /* Slider styling */
104
- .gradio-slider {
105
- margin: 1rem 0 !important;
106
- }
107
- .gradio-slider label span:first-of-type {
108
- font-weight: 500 !important;
109
- }
110
- /* Chatbot container */
111
- .chatbot-container {
112
- border-radius: 12px !important;
113
- border: 1px solid #eaeaea !important;
114
- }
115
- /* Badge styling */
116
- .model-badge {
117
- display: inline-block;
118
- padding: 2px 8px;
119
- border-radius: 12px;
120
- font-size: 0.8rem;
121
- font-weight: 500;
122
- margin-left: 8px;
123
- color: white;
124
- }
125
- .badge-red { background-color: #e53e3e; }
126
- .badge-orange { background-color: #ed8936; }
127
- .badge-yellow { background-color: #d69e2e; }
128
- .badge-green { background-color: #38a169; }
129
- .badge-blue { background-color: #3182ce; }
130
- .badge-indigo { background-color: #5a67d8; }
131
- /* Duplicate button styling */
132
  .duplicate-button {
133
  margin: 1rem auto !important;
134
  display: block !important;
@@ -138,72 +80,67 @@ h1.main-title {
138
  padding: 0.5rem 1.5rem !important;
139
  font-weight: 600 !important;
140
  border: none !important;
141
- transition: all 0.3s ease !important;
142
  box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08) !important;
143
  }
144
- .duplicate-button:hover {
145
- transform: translateY(-2px) !important;
146
- box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08) !important;
 
 
 
 
147
  }
148
- /* Mode color indicators */
149
- .mode-info {
150
- display: flex;
151
- justify-content: center;
152
- gap: 20px;
153
- margin: 1rem 0;
154
  }
155
- .mode-item {
156
- display: flex;
157
- align-items: center;
158
- font-size: 0.85rem;
 
 
159
  }
160
- .mode-color {
161
- width: 12px;
162
- height: 12px;
163
- border-radius: 50%;
164
- margin-right: 6px;
165
  }
166
  """
167
 
168
- def format_model_option(model_name: str) -> str:
169
- """Format the model dropdown options with colored badges."""
170
- config = MODEL_CONFIGS[model_name]
171
- color = config["badge_color"]
172
- description = config["description"]
173
- # This creates a string with HTML that will be rendered in the dropdown label
174
- return f"{model_name} <span class='model-badge badge-{color}'>{description}</span>"
175
-
176
  def stream_chat(
177
  message: str,
178
  history: list,
179
- model_name: str, # Changed: This will now be the plain model name
180
  temperature: float = 0.7,
181
  max_new_tokens: int = 1024,
182
  top_p: float = 1.0,
183
  presence_penalty: float = 1.2,
184
  ):
185
- # Removed: model_name extraction from HTML, as model_name is now passed directly.
186
- # model_name = model_label.split(" <span")[0] if "<span" in model_label else model_label
187
 
188
  cfg = MODEL_CONFIGS[model_name]
189
  api_key = os.getenv(cfg["api_key_env"])
190
  base_url = os.getenv(cfg.get("base_url_env", ""), None)
191
-
192
  if not api_key:
193
  yield f"❌ Env-var `{cfg['api_key_env']}` not set."
194
  return
 
195
  if cfg.get("base_url_env") and not base_url:
196
  yield f"❌ Env-var `{cfg['base_url_env']}` not set."
197
  return
198
-
199
  client = openai.OpenAI(api_key=api_key, base_url=base_url)
200
 
201
  msgs = []
202
  for u, a in history:
203
- msgs.append({"role": "user", "content": u})
204
- msgs.append({"role": "assistant", "content": a})
205
  msgs.append({"role": "user", "content": message})
206
-
207
  try:
208
  stream = client.chat.completions.create(
209
  model=cfg["model_id"],
@@ -214,74 +151,49 @@ def stream_chat(
214
  presence_penalty=presence_penalty,
215
  stream=True,
216
  )
 
217
  partial = ""
218
  for chunk in stream:
219
- if (delta := chunk.choices[0].delta) and delta.content: # Ensure delta and delta.content are not None
220
  partial += delta.content
221
  yield partial
222
  except Exception as e:
223
  yield f"❌ Error: {str(e)}"
224
 
225
- # Prepare model choices for the dropdown: list of (display_label, actual_value)
226
- ordered_model_names = list(MODEL_CONFIGS.keys())
227
- model_choices_list = [
228
- (format_model_option(name), name) for name in ordered_model_names
229
- ]
230
-
231
  # Create the Gradio interface
232
  with gr.Blocks(css=CSS, theme="soft") as demo:
233
  # Header section
234
- with gr.Row(elem_classes="header-container"):
235
- with gr.Column():
236
- gr.HTML("<h1 class='main-title'>Falcon Playground</h1>")
237
- gr.HTML("<p class='subtitle'>Private multi-backend interface • Keys & endpoints stay server-side</p>")
238
- gr.HTML(f"<p class='subtitle' style='font-size: 0.9rem; color: #888;'>Today: {today.strftime('%B %d, %Y')}</p>")
239
- gr.DuplicateButton(value="Duplicate Space", elem_classes="duplicate-button")
240
-
241
- # Info section with model size indicators
242
- with gr.Row(elem_classes="mode-info"):
243
- for model_key, config in MODEL_CONFIGS.items():
244
- # Use the hex color from our BADGE_HEX_COLORS map
245
- hex_color = BADGE_HEX_COLORS.get(config["badge_color"], "#ccc") # Default to gray if color not found
246
- gr.HTML(f"""
247
- <div class='mode-item'>
248
- <div class='mode-color' style='background-color: {hex_color};'></div>
249
- <div>{model_key.split('-')[-2]}</div>
250
- </div>
251
- """)
252
-
253
- # Main chat interface
254
- chatbot = gr.Chatbot(height=600, elem_classes="chatbot-container")
255
 
256
- with gr.ChatInterface(
257
- fn=stream_chat,
258
- chatbot=chatbot,
259
- fill_height=True,
260
- additional_inputs_accordion_name="⚙️ Advanced Parameters & Model Selection", # Renamed for clarity
261
- # additional_inputs_accordion="closed", # This was the old way, now part of additional_inputs
262
- ) as chat_interface:
263
-
264
- pass # ChatInterface handles its own input fields. We add ours via additional_inputs.
265
-
266
  model_dropdown = gr.Dropdown(
267
- choices=model_choices_list,
268
- value=ordered_model_names[0] if ordered_model_names else None, # Default to the actual name of the first model
269
- label="Model Selection",
270
  elem_classes="model-dropdown"
271
  )
272
-
273
- temperature_slider = gr.Slider(0, 1, value=0.7, step=0.05, label="Temperature", info="Higher values produce more diverse outputs")
274
- max_new_tokens_slider = gr.Slider(64, 4096*8, value=1024, step=64, label="Max new tokens", info="Maximum length of generated response")
275
- top_p_slider = gr.Slider(0, 1, value=1.0, step=0.05, label="Top-p (nucleus sampling)", info="1.0 means no filtering")
276
- presence_penalty_slider = gr.Slider(0, 2, value=1.2, step=0.1, label="Presence penalty", info="Penalizes repetition")
277
-
278
- chat_interface.additional_inputs = [
279
- model_dropdown,
280
- temperature_slider,
281
- max_new_tokens_slider,
282
- top_p_slider,
283
- presence_penalty_slider
284
- ]
 
285
 
286
  if __name__ == "__main__":
287
  demo.launch()
 
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;
 
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"],
 
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()