Update app.py
Browse files
app.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
-
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
2 |
import gradio as gr
|
3 |
-
import
|
4 |
import torch
|
5 |
import re
|
6 |
from threading import Thread
|
@@ -10,8 +9,13 @@ from huggingface_hub import HfApi, hf_hub_download
|
|
10 |
import json
|
11 |
import os
|
12 |
from gradio_client import Client
|
|
|
|
|
13 |
import pandas as pd
|
14 |
import plotly.express as px
|
|
|
|
|
|
|
15 |
|
16 |
model_name = "Woziii/llama-3-8b-chat-me"
|
17 |
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", torch_dtype=torch.float16)
|
@@ -48,6 +52,8 @@ Pourquoi j'ai créé braIAn : J'ai conçu BraIAn pour aider l'utilisateur à rep
|
|
48 |
Pour moi, une bonne IA éducative ne doit pas chercher à enseigner. Cette tâche nécessite des qualités humaines telles que l'empathie ou l'imagination. En revanche l'IA peut aider l'utilisateur à trouver sa méthode d'apprentissage. Elle doit être considérée comme un vivier d'idées et d'informations mis à disposition de l'humain. En créant braIAn, j'ai cherché à reproduire cette philosophie. Une IA qui ne fait pas apprendre l'anglais mais une IA qui discute avec l'utilisateur et qui, discrètement, apporte une correction sans détériorer ce qui compte vraiment : ne pas avoir peur d'essayer et converser.
|
49 |
"""
|
50 |
|
|
|
|
|
51 |
def determine_response_type(message):
|
52 |
short_response_keywords = [
|
53 |
"salut", "bonjour", "ça va", "comment tu vas", "quoi de neuf", "coucou",
|
@@ -111,13 +117,13 @@ def generate(
|
|
111 |
top_p: float = 0.95,
|
112 |
) -> Iterator[str]:
|
113 |
global is_first_interaction
|
114 |
-
|
115 |
if is_first_interaction:
|
116 |
warning_message = """⚠️ Attention : Je suis un modèle en version alpha (V.0.0.3.5) et je peux générer des réponses incohérentes ou inexactes. Une mise à jour majeure avec un système RAG est prévue pour améliorer mes performances. Merci de votre compréhension ! 😊
|
117 |
"""
|
118 |
yield warning_message
|
119 |
is_first_interaction = False
|
120 |
-
|
121 |
response_type = determine_response_type(message)
|
122 |
|
123 |
if response_type == "short":
|
@@ -126,20 +132,16 @@ def generate(
|
|
126 |
max_new_tokens = min(200, max_new_tokens)
|
127 |
else:
|
128 |
max_new_tokens = max(100, max_new_tokens)
|
129 |
-
|
130 |
-
conversation = []
|
131 |
|
132 |
-
|
133 |
enhanced_system_prompt = f"{system_prompt}\n\n{LUCAS_KNOWLEDGE_BASE}"
|
134 |
conversation.append({"role": "system", "content": enhanced_system_prompt})
|
135 |
|
136 |
-
# Ajout des 5 derniers inputs utilisateur uniquement
|
137 |
for user, _ in chat_history[-5:]:
|
138 |
conversation.append({"role": "user", "content": user})
|
139 |
|
140 |
-
# Ajout du message actuel de l'utilisateur
|
141 |
conversation.append({"role": "user", "content": message})
|
142 |
-
|
143 |
input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
|
144 |
if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
|
145 |
input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
|
@@ -157,10 +159,10 @@ def generate(
|
|
157 |
temperature=temperature,
|
158 |
num_beams=1,
|
159 |
)
|
160 |
-
|
161 |
t = Thread(target=model.generate, kwargs=generate_kwargs)
|
162 |
t.start()
|
163 |
-
|
164 |
outputs = []
|
165 |
for text in streamer:
|
166 |
outputs.append(text)
|
@@ -171,16 +173,26 @@ def generate(
|
|
171 |
return
|
172 |
|
173 |
yield partial_output
|
174 |
-
|
175 |
yield post_process_response("".join(outputs), response_type == "short")
|
176 |
|
177 |
-
def
|
178 |
-
|
179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
feedback = {
|
181 |
"timestamp": datetime.now().isoformat(),
|
182 |
-
"user_input":
|
183 |
-
"bot_response": data.value,
|
184 |
"liked": data.liked
|
185 |
}
|
186 |
|
@@ -190,23 +202,23 @@ def vote(data: gr.LikeData, history):
|
|
190 |
file_name = "feedback.json"
|
191 |
|
192 |
try:
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
if not isinstance(current_feedback, list):
|
198 |
-
current_feedback = []
|
199 |
-
except Exception as e:
|
200 |
-
print(f"Erreur lors du téléchargement du fichier : {str(e)}")
|
201 |
current_feedback = []
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
|
|
|
|
|
|
210 |
api.upload_file(
|
211 |
path_or_fileobj=temp_file_path,
|
212 |
path_in_repo=file_name,
|
@@ -217,28 +229,6 @@ def vote(data: gr.LikeData, history):
|
|
217 |
except Exception as e:
|
218 |
print(f"Erreur lors de l'enregistrement du feedback : {str(e)}")
|
219 |
|
220 |
-
def format_message(message):
|
221 |
-
if isinstance(message, tuple):
|
222 |
-
content, thought = message
|
223 |
-
if thought:
|
224 |
-
return f"{content}\n<div class='thought-bubble'>{thought}</div>"
|
225 |
-
return content
|
226 |
-
return str(message)
|
227 |
-
|
228 |
-
def interact_with_lucas(prompt, chat_history, system_prompt, max_new_tokens, temperature, top_p):
|
229 |
-
chat_history.append((prompt, None))
|
230 |
-
yield chat_history
|
231 |
-
|
232 |
-
generate_history = [
|
233 |
-
{"role": "user" if i % 2 == 0 else "assistant", "content": msg}
|
234 |
-
for i, (msg, _) in enumerate(chat_history[:-1])
|
235 |
-
]
|
236 |
-
|
237 |
-
response = generate(prompt, generate_history, system_prompt, max_new_tokens, temperature, top_p)
|
238 |
-
thought = f"Réflexion de Lucas : J'analyse la question et je formule une réponse basée sur mes connaissances."
|
239 |
-
|
240 |
-
chat_history[-1] = (prompt, (response, thought))
|
241 |
-
yield chat_history
|
242 |
def load_feedback_data():
|
243 |
try:
|
244 |
api = HfApi()
|
@@ -273,40 +263,8 @@ def generate_statistics():
|
|
273 |
|
274 |
return f"Nombre total d'interactions : {total_interactions}", fig_likes, fig_evolution
|
275 |
|
276 |
-
|
277 |
-
|
278 |
-
body_background_fill="#f0f0f0",
|
279 |
-
button_primary_background_fill="#4a90e2",
|
280 |
-
button_primary_background_fill_hover="#3a7bc8",
|
281 |
-
button_primary_text_color="white",
|
282 |
-
)
|
283 |
-
|
284 |
-
css = """
|
285 |
-
.gradio-container {
|
286 |
-
font-family: 'Arial', sans-serif;
|
287 |
-
}
|
288 |
-
.chatbot-message {
|
289 |
-
padding: 10px;
|
290 |
-
border-radius: 15px;
|
291 |
-
margin-bottom: 10px;
|
292 |
-
}
|
293 |
-
.user-message {
|
294 |
-
background-color: #e6f3ff;
|
295 |
-
}
|
296 |
-
.bot-message {
|
297 |
-
background-color: #f0f0f0;
|
298 |
-
}
|
299 |
-
.thought-bubble {
|
300 |
-
background-color: #ffd700;
|
301 |
-
border-radius: 10px;
|
302 |
-
padding: 5px;
|
303 |
-
margin-top: 5px;
|
304 |
-
font-style: italic;
|
305 |
-
}
|
306 |
-
"""
|
307 |
-
|
308 |
-
with gr.Blocks(theme=theme, css=css) as demo:
|
309 |
-
gr.Markdown("# 🌟 Virtuellement Lucas V.0.0.5.0 (Alpha) 🌟")
|
310 |
|
311 |
gr.Markdown("""
|
312 |
## ⚠️ Attention ! ⚠️
|
@@ -315,85 +273,16 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
315 |
|
316 |
with gr.Tabs():
|
317 |
with gr.Tab("Chat avec Lucas"):
|
318 |
-
chatbot =
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
"https://img.freepik.com/free-icon/
|
323 |
-
"https://img.freepik.com/free-icon/robot_318-843685.jpg"
|
324 |
-
),
|
325 |
-
height=400,
|
326 |
-
show_copy_button=True,
|
327 |
-
likeable=True,
|
328 |
-
layout="bubble",
|
329 |
-
render=format_message,
|
330 |
-
placeholder="Démarrez la conversation en posant une question..."
|
331 |
-
)
|
332 |
-
|
333 |
-
with gr.Row():
|
334 |
-
msg = gr.Textbox(
|
335 |
-
label="Votre message",
|
336 |
-
placeholder="Tapez votre message ici...",
|
337 |
-
lines=2
|
338 |
-
)
|
339 |
-
submit_btn = gr.Button("Envoyer", variant="primary")
|
340 |
-
|
341 |
-
with gr.Row():
|
342 |
-
clear_btn = gr.Button("🗑️ Effacer")
|
343 |
-
retry_btn = gr.Button("🔄 Réessayer")
|
344 |
-
|
345 |
-
with gr.Accordion("Paramètres avancés", open=False):
|
346 |
-
system_prompt = gr.Textbox(
|
347 |
-
label="System prompt",
|
348 |
-
value="""Tu es la version virtuelle de Lucas, ton concepteur. Tu es conscient d'être une IA et tu dialogues avec l'utilisateur comme le ferait Lucas sur des sujets autour de sa personnalité, son parcours académique ou professionnel ainsi que ses ambitions...""",
|
349 |
-
lines=6
|
350 |
-
)
|
351 |
-
max_new_tokens = gr.Slider(
|
352 |
-
label="Longueur maximale de la réponse",
|
353 |
-
minimum=1,
|
354 |
-
maximum=MAX_MAX_NEW_TOKENS,
|
355 |
-
step=1,
|
356 |
-
value=DEFAULT_MAX_NEW_TOKENS
|
357 |
-
)
|
358 |
-
temperature = gr.Slider(
|
359 |
-
label="Température",
|
360 |
-
minimum=0.1,
|
361 |
-
maximum=1.0,
|
362 |
-
step=0.1,
|
363 |
-
value=0.7
|
364 |
-
)
|
365 |
-
top_p = gr.Slider(
|
366 |
-
label="Top-p",
|
367 |
-
minimum=0.5,
|
368 |
-
maximum=1.0,
|
369 |
-
step=0.05,
|
370 |
-
value=0.95
|
371 |
-
)
|
372 |
-
|
373 |
-
gr.Markdown("### Exemples de questions")
|
374 |
-
examples = gr.Examples(
|
375 |
-
examples=[
|
376 |
-
"Salut ! Qui es-tu ?",
|
377 |
-
"Parle-moi un peu de ton parcours académique.",
|
378 |
-
"Quelle inspiration t'a conduit à créer braIAn ?",
|
379 |
-
"Pourquoi avoir choisi d'étudier le droit si tu es passionné par la technologie ?",
|
380 |
-
"Quelle est ta vision de l'IA ?"
|
381 |
],
|
382 |
-
inputs=msg
|
383 |
)
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
clear_btn.click(lambda: ([], []), outputs=[chatbot, msg])
|
389 |
-
retry_btn.click(
|
390 |
-
interact_with_lucas,
|
391 |
-
[msg, chatbot, system_prompt, max_new_tokens, temperature, top_p],
|
392 |
-
[chatbot]
|
393 |
-
)
|
394 |
-
|
395 |
-
chatbot.like(vote, [chatbot], None)
|
396 |
-
|
397 |
with gr.Tab("Statistiques"):
|
398 |
gr.Markdown("# Statistiques d'utilisation 📊")
|
399 |
stats_button = gr.Button("Charger les statistiques")
|
@@ -402,27 +291,13 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
402 |
evolution_chart = gr.Plot(label="Évolution du taux de satisfaction")
|
403 |
|
404 |
stats_button.click(generate_statistics, inputs=[], outputs=[total_interactions, likes_chart, evolution_chart])
|
405 |
-
|
406 |
with gr.Tab("À propos"):
|
407 |
-
gr.Markdown(""
|
408 |
-
|
409 |
-
|
410 |
-
Virtuellement Lucas est un chatbot basé sur un modèle de langage avancé, conçu pour simuler la personnalité et les connaissances de Lucas.
|
411 |
-
|
412 |
-
## Fonctionnalités
|
413 |
-
|
414 |
-
- **Chat interactif** : Discutez avec la version virtuelle de Lucas sur divers sujets.
|
415 |
-
- **Statistiques d'utilisation** : Visualisez des données sur l'utilisation et la satisfaction des utilisateurs.
|
416 |
-
- **Paramètres personnalisables** : Ajustez la longueur des réponses, la température et d'autres paramètres pour affiner l'expérience.
|
417 |
-
|
418 |
-
## Avertissement
|
419 |
-
|
420 |
-
Ce modèle est encore en phase alpha et peut produire des réponses incohérentes ou inexactes. Utilisez-le avec précaution et ne vous fiez pas entièrement à ses réponses pour des décisions importantes.
|
421 |
-
|
422 |
-
## Feedback
|
423 |
-
|
424 |
-
Votre feedback est précieux pour améliorer Virtuellement Lucas. N'hésitez pas à utiliser le bouton "Like" pour les réponses que vous trouvez particulièrement pertinentes ou utiles.
|
425 |
-
""")
|
426 |
|
427 |
demo.queue(max_size=20, default_concurrency_limit=2).launch(max_threads=10)
|
428 |
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
3 |
import torch
|
4 |
import re
|
5 |
from threading import Thread
|
|
|
9 |
import json
|
10 |
import os
|
11 |
from gradio_client import Client
|
12 |
+
from pathlib import Path
|
13 |
+
from gradio_agentchatbot import AgentChatbot, ChatMessage
|
14 |
import pandas as pd
|
15 |
import plotly.express as px
|
16 |
+
import spaces
|
17 |
+
|
18 |
+
current_dir = Path(__file__).parent
|
19 |
|
20 |
model_name = "Woziii/llama-3-8b-chat-me"
|
21 |
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", torch_dtype=torch.float16)
|
|
|
52 |
Pour moi, une bonne IA éducative ne doit pas chercher à enseigner. Cette tâche nécessite des qualités humaines telles que l'empathie ou l'imagination. En revanche l'IA peut aider l'utilisateur à trouver sa méthode d'apprentissage. Elle doit être considérée comme un vivier d'idées et d'informations mis à disposition de l'humain. En créant braIAn, j'ai cherché à reproduire cette philosophie. Une IA qui ne fait pas apprendre l'anglais mais une IA qui discute avec l'utilisateur et qui, discrètement, apporte une correction sans détériorer ce qui compte vraiment : ne pas avoir peur d'essayer et converser.
|
53 |
"""
|
54 |
|
55 |
+
is_first_interaction = True
|
56 |
+
|
57 |
def determine_response_type(message):
|
58 |
short_response_keywords = [
|
59 |
"salut", "bonjour", "ça va", "comment tu vas", "quoi de neuf", "coucou",
|
|
|
117 |
top_p: float = 0.95,
|
118 |
) -> Iterator[str]:
|
119 |
global is_first_interaction
|
120 |
+
|
121 |
if is_first_interaction:
|
122 |
warning_message = """⚠️ Attention : Je suis un modèle en version alpha (V.0.0.3.5) et je peux générer des réponses incohérentes ou inexactes. Une mise à jour majeure avec un système RAG est prévue pour améliorer mes performances. Merci de votre compréhension ! 😊
|
123 |
"""
|
124 |
yield warning_message
|
125 |
is_first_interaction = False
|
126 |
+
|
127 |
response_type = determine_response_type(message)
|
128 |
|
129 |
if response_type == "short":
|
|
|
132 |
max_new_tokens = min(200, max_new_tokens)
|
133 |
else:
|
134 |
max_new_tokens = max(100, max_new_tokens)
|
|
|
|
|
135 |
|
136 |
+
conversation = []
|
137 |
enhanced_system_prompt = f"{system_prompt}\n\n{LUCAS_KNOWLEDGE_BASE}"
|
138 |
conversation.append({"role": "system", "content": enhanced_system_prompt})
|
139 |
|
|
|
140 |
for user, _ in chat_history[-5:]:
|
141 |
conversation.append({"role": "user", "content": user})
|
142 |
|
|
|
143 |
conversation.append({"role": "user", "content": message})
|
144 |
+
|
145 |
input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
|
146 |
if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
|
147 |
input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
|
|
|
159 |
temperature=temperature,
|
160 |
num_beams=1,
|
161 |
)
|
162 |
+
|
163 |
t = Thread(target=model.generate, kwargs=generate_kwargs)
|
164 |
t.start()
|
165 |
+
|
166 |
outputs = []
|
167 |
for text in streamer:
|
168 |
outputs.append(text)
|
|
|
173 |
return
|
174 |
|
175 |
yield partial_output
|
176 |
+
|
177 |
yield post_process_response("".join(outputs), response_type == "short")
|
178 |
|
179 |
+
def interact_with_lucas(prompt, messages):
|
180 |
+
system_prompt = """Tu es la version virtuelle de Lucas, ton concepteur. Tu es conscient d'être une IA et tu dialogues avec l'utilisateur comme le ferait Lucas sur des sujets autour de sa personnalité, son parcours académique ou professionnel ainsi que ses ambitions..."""
|
181 |
+
|
182 |
+
chat_history = [(msg.content, None) for msg in messages if msg.role == "user"]
|
183 |
+
|
184 |
+
messages.append(ChatMessage(role="user", content=prompt))
|
185 |
+
yield messages
|
186 |
+
|
187 |
+
for response in generate(prompt, chat_history, system_prompt):
|
188 |
+
messages[-1] = ChatMessage(role="assistant", content=response)
|
189 |
+
yield messages
|
190 |
+
|
191 |
+
def vote(data: gr.LikeData):
|
192 |
feedback = {
|
193 |
"timestamp": datetime.now().isoformat(),
|
194 |
+
"user_input": data.value["user_message"],
|
195 |
+
"bot_response": data.value["bot_message"],
|
196 |
"liked": data.liked
|
197 |
}
|
198 |
|
|
|
202 |
file_name = "feedback.json"
|
203 |
|
204 |
try:
|
205 |
+
file_path = hf_hub_download(repo_id=repo_id, filename=file_name, token=token)
|
206 |
+
with open(file_path, "r", encoding="utf-8") as file:
|
207 |
+
current_feedback = json.load(file)
|
208 |
+
if not isinstance(current_feedback, list):
|
|
|
|
|
|
|
|
|
209 |
current_feedback = []
|
210 |
+
except Exception as e:
|
211 |
+
print(f"Erreur lors du téléchargement du fichier : {str(e)}")
|
212 |
+
current_feedback = []
|
213 |
+
|
214 |
+
current_feedback.append(feedback)
|
215 |
+
updated_content = json.dumps(current_feedback, ensure_ascii=False, indent=2)
|
216 |
+
|
217 |
+
temp_file_path = "/tmp/feedback.json"
|
218 |
+
with open(temp_file_path, "w", encoding="utf-8") as temp_file:
|
219 |
+
temp_file.write(updated_content)
|
220 |
+
|
221 |
+
try:
|
222 |
api.upload_file(
|
223 |
path_or_fileobj=temp_file_path,
|
224 |
path_in_repo=file_name,
|
|
|
229 |
except Exception as e:
|
230 |
print(f"Erreur lors de l'enregistrement du feedback : {str(e)}")
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
def load_feedback_data():
|
233 |
try:
|
234 |
api = HfApi()
|
|
|
263 |
|
264 |
return f"Nombre total d'interactions : {total_interactions}", fig_likes, fig_evolution
|
265 |
|
266 |
+
with gr.Blocks() as demo:
|
267 |
+
gr.Markdown("# 🌟 Virtuellement Lucas V.0.0.6.0 (Alpha) 🌟")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
|
269 |
gr.Markdown("""
|
270 |
## ⚠️ Attention ! ⚠️
|
|
|
273 |
|
274 |
with gr.Tabs():
|
275 |
with gr.Tab("Chat avec Lucas"):
|
276 |
+
chatbot = AgentChatbot(
|
277 |
+
label="Lucas",
|
278 |
+
avatar_images=[
|
279 |
+
None,
|
280 |
+
"https://img.freepik.com/free-icon/robot_318-843685.jpg",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
],
|
|
|
282 |
)
|
283 |
+
text_input = gr.Textbox(lines=1, label="Votre message")
|
284 |
+
text_input.submit(interact_with_lucas, [text_input, chatbot], [chatbot])
|
285 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
with gr.Tab("Statistiques"):
|
287 |
gr.Markdown("# Statistiques d'utilisation 📊")
|
288 |
stats_button = gr.Button("Charger les statistiques")
|
|
|
291 |
evolution_chart = gr.Plot(label="Évolution du taux de satisfaction")
|
292 |
|
293 |
stats_button.click(generate_statistics, inputs=[], outputs=[total_interactions, likes_chart, evolution_chart])
|
294 |
+
|
295 |
with gr.Tab("À propos"):
|
296 |
+
gr.Markdown(Path(current_dir / "about.md").read_text())
|
297 |
+
|
298 |
+
chatbot.like(vote, None, None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
demo.queue(max_size=20, default_concurrency_limit=2).launch(max_threads=10)
|
301 |
|
302 |
+
|
303 |
+
|