isanders commited on
Commit
b2c0464
Β·
1 Parent(s): f62d8b1

πŸŽ‰ Gradio chatbot on via Deeploy

Browse files
Files changed (3) hide show
  1. .gitignore +2 -0
  2. app.py +219 -54
  3. requirements.txt +1 -1
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ env
2
+ .gradio
app.py CHANGED
@@ -1,64 +1,229 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
  ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  if __name__ == "__main__":
64
  demo.launch()
 
1
  import gradio as gr
2
+ import requests
3
 
4
+ DEFAULT_DEPLOYMENT_URL = "https://api.app.deeploy.ml/workspaces/708b5808-27af-461a-8ee5-80add68384c7/deployments/a0a5d36d-ede6-4c53-8705-e4a8727bb0b7/predict"
5
+
6
+ DEFAULT_PROMPTS = [
7
+ ["What are requirements for a high-risk AI system?"],
8
+ ["Can you help me understand AI content moderation guidelines and limitations?"],
9
+ ]
10
+
11
+ MAX_TOKENS = 800
12
+ TEMPERATURE = 0.7
13
+ TOP_P = 0.95
14
+
15
+ ERROR_401 = "Error: Invalid Deployment token"
16
+ ERROR_403 = "Error: No valid permissions for this Deployment token"
17
+ ERROR_404 = "Error: Deployment not found. Check the API URL."
18
+
19
+ indexed_prediction_log_ids = {}
20
 
21
 
22
  def respond(
23
+ message: str,
24
+ history: list,
25
+ api_url: str,
26
+ deployment_token: str,
 
 
27
  ):
28
+ formatted_history = []
29
+
30
+ if history and isinstance(history[0], list):
31
+ for user_msg, assistant_msg in history:
32
+ if user_msg:
33
+ formatted_history.append(message_from_user(user_msg))
34
+ if assistant_msg:
35
+ formatted_history.append(message_from_assistant(assistant_msg))
36
+ else:
37
+ formatted_history = history
38
+
39
+ messages = [message_from_system("Your are a friendly Chatbot.")]
40
+ messages.extend(formatted_history)
41
+
42
+ if message:
43
+ messages.append(message_from_user(message))
44
+
45
+ headers = get_headers(deployment_token)
46
+ payload = get_prediction_payload(messages)
47
+ predict_url = get_predict_url(api_url)
48
+
49
+ response = requests.post(predict_url, json=payload, headers=headers)
50
+
51
+ new_history = formatted_history.copy()
52
+
53
+ if message:
54
+ new_history.append(message_from_user(message))
55
+
56
+ if response.status_code != 201:
57
+ append_error_to_history(new_history, response)
58
+ return new_history
59
+
60
+ try:
61
+ response_data = response.json()
62
+
63
+ if isinstance(response_data, dict) and "choices" in response_data:
64
+ if (
65
+ len(response_data["choices"]) > 0
66
+ and "message" in response_data["choices"][0]
67
+ ):
68
+ content = response_data["choices"][0]["message"].get("content", "")
69
+ prediction_log_id = response_data["predictionLogIds"][0]
70
+ indexed_prediction_log_ids[len(new_history)] = prediction_log_id
71
+ new_history.append(message_from_assistant(content))
72
+ return new_history
73
+ else:
74
+ new_history.append(
75
+ message_from_assistant(
76
+ f"Error: Unexpected response format: {response_data}"
77
+ )
78
+ )
79
+ return new_history
80
+
81
+ except Exception as error:
82
+ new_history.append(
83
+ message_from_assistant(f"Error parsing API response: {str(error)}")
84
+ )
85
+ return new_history
86
+
87
+
88
+ def evaluate(
89
+ like_data: gr.LikeData,
90
+ api_url: str,
91
+ deployment_token: str,
92
+ ) -> str | None:
93
+ prediction_log_id = indexed_prediction_log_ids.get(like_data.index)
94
+
95
+ headers = get_headers(deployment_token)
96
+ evaluate_url = get_evaluation_url(api_url, prediction_log_id)
97
+ evaluation_payload = get_evaluation_payload(like_data.liked)
98
+
99
+ response = requests.post(evaluate_url, json=evaluation_payload, headers=headers)
100
+
101
+ if response.status_code != 201:
102
+ error_msg = "Error: Failed to evaluate the prediction, does your token have the right permissions?"
103
+ return error_msg
104
+
105
+
106
+ def get_prediction_payload(messages: list) -> dict:
107
+ return {
108
+ "messages": messages,
109
+ "max_tokens": MAX_TOKENS,
110
+ "temperature": TEMPERATURE,
111
+ "top_p": TOP_P,
112
+ }
113
+
114
+
115
+ def get_evaluation_payload(liked: bool) -> dict:
116
+ if liked:
117
+ return {"agree": True, "comment": "Clicked thumbs up in the chat"}
118
+ else:
119
+ return {
120
+ "agree": False,
121
+ "comment": "Clicked thumbs down in the chat",
122
+ "desiredOutput": {"predictions": ["A new example output"]},
123
+ }
124
+
125
+
126
+ def get_headers(bearer_token: str) -> dict:
127
+ return {
128
+ "Authorization": f"Bearer {bearer_token}",
129
+ "Content-Type": "application/json",
130
+ }
131
+
132
+
133
+ def append_error_to_history(history: list, response: requests.Response) -> None:
134
+ if response.status_code == 401:
135
+ history.append(message_from_assistant(ERROR_401))
136
+ elif response.status_code == 403:
137
+ history.append(message_from_assistant(ERROR_403))
138
+ elif response.status_code == 404:
139
+ history.append(message_from_assistant(ERROR_404))
140
+ else:
141
+ history.append(
142
+ message_from_assistant(
143
+ f"Error: API returned status code {response.status_code}"
144
+ )
145
+ )
146
+
147
+
148
+ def message_from_assistant(message: str) -> dict:
149
+ return {"role": "assistant", "content": message}
150
+
151
+
152
+ def message_from_user(message: str) -> dict:
153
+ return {"role": "user", "content": message}
154
+
155
+
156
+ def message_from_system(message: str) -> dict:
157
+ return {"role": "system", "content": message}
158
+
159
+
160
+ def get_base_url(url: str) -> str:
161
+ if url.endswith("/predict"):
162
+ return url.split("/predict")[0]
163
+ else:
164
+ if url.endswith("/"):
165
+ return url[:-1]
166
+ else:
167
+ return url
168
+
169
+
170
+ def get_predict_url(url: str) -> str:
171
+ return get_base_url(url) + "/predict"
172
+
173
+
174
+ def get_evaluation_url(url: str, prediction_log_id: str) -> str:
175
+ return (
176
+ get_base_url(url)
177
+ + "/predictionLogs/"
178
+ + prediction_log_id
179
+ + "/evaluatePrediction"
180
+ )
181
+
182
+
183
+ with gr.Blocks() as demo:
184
+ with gr.Column(scale=1):
185
+ api_url = gr.Textbox(
186
+ value=DEFAULT_DEPLOYMENT_URL, label="Deeploy API URL", type="text"
187
+ )
188
+ deployment_token = gr.Textbox(label="Deployment token", type="password")
189
+
190
+ with gr.Column(scale=2):
191
+ chatbot = gr.Chatbot(
192
+ height=1000,
193
+ type="messages",
194
+ render_markdown=True,
195
+ show_copy_button=True,
196
+ )
197
+ msg = gr.Textbox(
198
+ label="Message",
199
+ placeholder="Type your message here...",
200
+ show_label=False,
201
+ submit_btn="Send",
202
+ )
203
+
204
+ gr.Examples(
205
+ examples=DEFAULT_PROMPTS,
206
+ inputs=[msg],
207
+ )
208
+
209
+ msg.submit(
210
+ respond,
211
+ inputs=[msg, chatbot, api_url, deployment_token],
212
+ outputs=chatbot,
213
+ ).then(lambda: "", None, msg, queue=False)
214
+
215
+ error_output = gr.Textbox(visible=False)
216
 
217
+ chatbot.like(
218
+ evaluate,
219
+ inputs=[api_url, deployment_token],
220
+ outputs=[error_output],
221
+ like_user_message=False,
222
+ ).success(
223
+ lambda msg: gr.Info(msg) if msg else None,
224
+ [error_output],
225
+ None,
226
+ )
227
 
228
  if __name__ == "__main__":
229
  demo.launch()
requirements.txt CHANGED
@@ -1 +1 @@
1
- huggingface_hub==0.25.2
 
1
+ gradio==5.30.0