Ilyasch2 commited on
Commit
f9f9e2c
Β·
1 Parent(s): 2e91549
Files changed (1) hide show
  1. app.py +131 -138
app.py CHANGED
@@ -1,199 +1,192 @@
 
 
 
 
 
 
 
 
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()
 
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()