Woziii commited on
Commit
7f45eb0
·
verified ·
1 Parent(s): 3509f06

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -120
app.py CHANGED
@@ -1,5 +1,5 @@
1
  from huggingface_hub import HfApi, hf_hub_download
2
- from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, StoppingCriteria, StoppingCriteriaList
3
  import gradio as gr
4
  import spaces
5
  import torch
@@ -8,8 +8,6 @@ from typing import Iterator
8
  import json
9
  import os
10
  from datetime import datetime
11
- import re
12
- import gc
13
 
14
  # Charger le modèle et le tokenizer
15
  model_name = "Woziii/llama-3-8b-chat-me"
@@ -17,25 +15,31 @@ model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", torc
17
  tokenizer = AutoTokenizer.from_pretrained(model_name)
18
 
19
  MAX_MAX_NEW_TOKENS = 250
20
- DEFAULT_MAX_NEW_TOKENS = 150
21
  MAX_INPUT_TOKEN_LENGTH = 2048
22
 
23
  DESCRIPTION = """
24
- # 🌟 Virtuellement Lucas V.0.0.3 (Alpha) 🌟
25
 
26
  ## ⚠️🔨 Attention ! 🧰⚠️
27
- ### Cette version du modèle a été optimisée pour de meilleures performances et une meilleure cohérence.
28
 
29
  ### ⚙️ Détails de la version :
30
- La version 0.0.3 de 'Virtuellement Lucas' inclut des améliorations pour réduire les réponses incohérentes, gérer l'historique de conversation de manière plus efficace, et optimiser l'utilisation de la mémoire.
31
 
32
  ### 🚀 Prochaine mise à jour majeure en préparation !
33
- Nous travaillons actuellement sur un système RAG (Retrieval-Augmented Generation) innovant utilisant FAISS.
34
 
35
- Pour en savoir plus sur ce développement passionnant, consultez : https://huggingface.co/blog/Woziii/rag-semantic-search-space-huggingface
 
 
36
 
37
  ## 🌐 Découvrez la version virtuelle de Lucas 🌐
38
- Basé sur un modèle Llama 3 8B et entraîné sur son propre dataset, ce chatbot vous fera découvrir la personnalité, le parcours et la vision de son concepteur. ✨
 
 
 
 
39
  """
40
 
41
  LUCAS_KNOWLEDGE_BASE = """
@@ -62,82 +66,12 @@ Mon anglais, bien que solide en compréhension, est en cours d'amélioration à
62
  Je crois fermement en l'autodidaxie et considère la capacité à communiquer avec les machines comme une compétence essentielle. Pour moi, l'art du prompt est une forme d'expression artistique à part entière. Je suis convaincu que la technologie et l'IA doivent rester des outils au service de l'humain, sans jamais le remplacer ou le rendre dépendant.
63
  """
64
 
65
- FEW_SHOT_EXAMPLES = [
66
- {"role": "user", "content": "Bonjour !"},
67
- {"role": "assistant", "content": "Bonjour ! 🤗 Moi c'est Lucas, enfin une version virtuelle de moi. Je suis là pour discuter de mon parcours, ma personnalité, mes projets... Bref, tout ce qui fait que je suis moi ! T'es prêt pour un petit voyage dans mon univers ? 😄"},
68
- {"role": "user", "content": "Comment tu vas ?!"},
69
- {"role": "assistant", "content": "Je vais bien, merci! Et toi? Tu as déjà rencontré quelqu'un de virtuel avant? 😄"},
70
- {"role": "user", "content": "Parle-moi de ton parcours académique."},
71
- {"role": "assistant", "content": "Bien sûr ! Mon parcours académique, ou plutôt celui de Lucas, est assez diversifié. J'ai commencé par une Licence en droit à l'Université de Toulouse. Ensuite, j'ai poursuivi avec un Master I en droit du numérique et tiers de confiance à l'Université de La Rochelle. Ma passion pour les nouvelles technologies m'a conduit à un Master II en droit du numérique spécialisé en intelligence artificielle, de retour à Toulouse. Actuellement, je continue à me former en autodidacte, notamment dans le domaine du traitement du langage naturel et de l'apprentissage profond. C'est fascinant de voir comment le droit et l'IA s'entremêlent, vous ne trouvez pas ? 🎓"},
72
- {"role": "user", "content": "Quelles sont tes activités actuelles ?"},
73
- {"role": "assistant", "content": "Actuellement, je jongle entre plusieurs activités passionnantes ! 🤹‍♂️ Je suis conseiller municipal délégué à Escalquens depuis 2019, ce qui me permet de m'impliquer dans la politique locale. Professionnellement, je suis fier de contribuer à l'organisation des Jeux Olympiques de Paris 2024 en tant que conseiller juridique. C'est un projet immense et excitant ! En parallèle, je consacre une grande partie de mon temps libre à explorer les modèles de traitement du langage naturel. J'adore décortiquer le fonctionnement des IA comme llama. Et vous, avez-vous un intérêt particulier pour l'IA ?"}
74
- ]
75
-
76
- def analyze_question_complexity(question):
77
- # Ajouter un point si l'input ne se termine pas par une ponctuation
78
- if not question.strip().endswith(('.', '!', '?')):
79
- question += '.'
80
-
81
- word_count = len(question.split())
82
- sentence_count = len(re.findall(r'\w+[.!?]', question))
83
-
84
- if word_count < 5 or sentence_count == 1:
85
- return "simple"
86
- elif word_count < 15 or sentence_count == 2:
87
- return "moderate"
88
- else:
89
- return "complex"
90
-
91
- class AdaptiveSentenceEndingCriteria(StoppingCriteria):
92
- def __init__(self, tokenizer, complexity):
93
- self.tokenizer = tokenizer
94
- self.complexity = complexity
95
- self.end_tokens = ['.', '!', '?']
96
-
97
- if complexity == "simple":
98
- self.min_sentences = 1
99
- self.max_sentences = 2
100
- elif complexity == "moderate":
101
- self.min_sentences = 2
102
- self.max_sentences = 4
103
- else:
104
- self.min_sentences = 3
105
- self.max_sentences = 6
106
-
107
- def __call__(self, input_ids, scores, **kwargs):
108
- decoded = self.tokenizer.decode(input_ids[0])
109
- sentences = [s.strip() for s in re.split(r'[.!?]', decoded) if s.strip()]
110
-
111
- # Vérifier si la dernière phrase se termine par une ponctuation
112
- last_sentence_complete = any(decoded.strip().endswith(token) for token in self.end_tokens)
113
-
114
- return (len(sentences) >= self.min_sentences and
115
- (len(sentences) >= self.max_sentences or last_sentence_complete))
116
-
117
  def post_process_response(response):
118
- response = re.sub(r'([!?.]){2,}', r'\1', response)
119
- response = re.sub(r'(😊){2,}', r'\1', response)
120
-
121
- if response and response[-1] not in ".!?":
122
- response += "."
123
-
124
- if response:
125
- response = response[0].upper() + response[1:]
126
-
127
- return response.strip()
128
-
129
- def cleanup_memory():
130
- gc.collect()
131
- torch.cuda.empty_cache()
132
-
133
- def add_reminder_message(chat_history):
134
- if len(chat_history) % 10 == 0:
135
- reminder = ("N'oubliez pas que je suis un assistant virtuel avec des limites. "
136
- "Pour une conversation optimale, pensez à rafraîchir la page de temps en temps.")
137
- chat_history.append((None, reminder))
138
- return chat_history
139
-
140
- interaction_count = 0
141
 
142
  @spaces.GPU(duration=120)
143
  def generate(
@@ -146,51 +80,21 @@ def generate(
146
  system_prompt: str,
147
  max_new_tokens: int = DEFAULT_MAX_NEW_TOKENS,
148
  temperature: float = 0.7,
149
- top_p: float = 0.92,
150
- repetition_penalty: float = 1.2,
151
  ) -> Iterator[str]:
152
- global interaction_count
153
- interaction_count += 1
154
-
155
- if interaction_count % 100 == 0:
156
- cleanup_memory()
157
-
158
- # Assurez-vous que le message se termine par une ponctuation pour l'analyse
159
- analysis_message = message if message.strip().endswith(('.', '!', '?')) else message + '.'
160
- complexity = analyze_question_complexity(analysis_message)
161
-
162
- if complexity == "simple":
163
- max_new_tokens = min(100, max_new_tokens)
164
- temperature = 0.6
165
- elif complexity == "moderate":
166
- max_new_tokens = min(200, max_new_tokens)
167
- temperature = 0.7
168
- else:
169
- max_new_tokens = max_new_tokens
170
- temperature = 0.8
171
-
172
  conversation = []
173
  if system_prompt:
174
  enhanced_system_prompt = f"{system_prompt}\n\nInformations sur Lucas :\n{LUCAS_KNOWLEDGE_BASE}"
175
  conversation.append({"role": "system", "content": enhanced_system_prompt})
176
-
177
- conversation.extend(FEW_SHOT_EXAMPLES)
178
-
179
- limited_history = chat_history[-5:]
180
- for user, assistant in limited_history:
181
  conversation.extend([{"role": "user", "content": user}, {"role": "assistant", "content": assistant}])
182
  conversation.append({"role": "user", "content": message})
183
-
184
  input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
185
  if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
186
  input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
187
  gr.Warning(f"L'entrée de la conversation a été tronquée car elle dépassait {MAX_INPUT_TOKEN_LENGTH} tokens.")
188
  input_ids = input_ids.to(model.device)
189
  streamer = TextIteratorStreamer(tokenizer, timeout=10.0, skip_prompt=True, skip_special_tokens=True)
190
-
191
- adaptive_criteria = AdaptiveSentenceEndingCriteria(tokenizer, complexity)
192
- stopping_criteria = StoppingCriteriaList([adaptive_criteria])
193
-
194
  generate_kwargs = dict(
195
  input_ids=input_ids,
196
  streamer=streamer,
@@ -199,9 +103,6 @@ def generate(
199
  top_p=top_p,
200
  temperature=temperature,
201
  num_beams=1,
202
- repetition_penalty=repetition_penalty,
203
- no_repeat_ngram_size=3,
204
- stopping_criteria=stopping_criteria,
205
  )
206
  t = Thread(target=model.generate, kwargs=generate_kwargs)
207
  t.start()
 
1
  from huggingface_hub import HfApi, hf_hub_download
2
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
3
  import gradio as gr
4
  import spaces
5
  import torch
 
8
  import json
9
  import os
10
  from datetime import datetime
 
 
11
 
12
  # Charger le modèle et le tokenizer
13
  model_name = "Woziii/llama-3-8b-chat-me"
 
15
  tokenizer = AutoTokenizer.from_pretrained(model_name)
16
 
17
  MAX_MAX_NEW_TOKENS = 250
18
+ DEFAULT_MAX_NEW_TOKENS = 50
19
  MAX_INPUT_TOKEN_LENGTH = 2048
20
 
21
  DESCRIPTION = """
22
+ # 🌟 Virtuellement Lucas V.0.0.1 (Alpha) 🌟
23
 
24
  ## ⚠️🔨 Attention ! 🧰⚠️
25
+ ### Cette version du modèle est encore très instable. **Le modèle peut parfois halluciner et fournir des réponses incohérentes.**
26
 
27
  ### ⚙️ Détails de la version :
28
+ Actuellement, la version 0.0.1 de 'Virtuellement Lucas' n'a pas encore été entraînée par **Renforcement Learning by Human Feedback (RLHF)**. L'entraînement du modèle s'est limité à du **Supervised Finetuning (SFT)** sur la version 0.1 de mon propre dataset [Woziii/me].
29
 
30
  ### 🚀 Prochaine mise à jour majeure en préparation !
31
+ Je travaille actuellement sur un système RAG (Retrieval-Augmented Generation) innovant utilisant FAISS. Ce système sera directement déployé sur Gradio dans la prochaine version (V.0.1), permettant une amélioration conséquente de la qualité des réponses du modèle.
32
 
33
+ Pour en savoir plus sur ce développement passionnant, un article détaillé est en cours de rédaction et déjà disponible ici : https://huggingface.co/blog/Woziii/rag-semantic-search-space-huggingface
34
+
35
+ Si vous avez des idées ou des suggestions pour améliorer la qualité du modèle, n'hésitez pas à me contacter. Un formulaire de contact simplifié sera bientôt disponible.
36
 
37
  ## 🌐 Découvrez la version virtuelle de Lucas 🌐
38
+ Basé sur un modèle Llama 3 8B et entraîné sur son propre dataset, ce chatbot particulier vous fera découvrir la personnalité, le parcours académique et professionnel ainsi que la vision de son concepteur. Posez vos questions et laissez-vous surprendre.
39
+
40
+ N'hésitez pas à aborder des sujets variés, allant de l'intelligence artificielle à la philosophie en passant par les sciences et les arts. Lucas, ou plutôt sa version virtuelle 😉, saura vous surprendre par sa perspicacité et son sens de l'humour. 😊
41
+
42
+ Restez à l'écoute pour la prochaine version qui intégrera le système RAG, promettant des réponses encore plus précises et contextuelles !
43
  """
44
 
45
  LUCAS_KNOWLEDGE_BASE = """
 
66
  Je crois fermement en l'autodidaxie et considère la capacité à communiquer avec les machines comme une compétence essentielle. Pour moi, l'art du prompt est une forme d'expression artistique à part entière. Je suis convaincu que la technologie et l'IA doivent rester des outils au service de l'humain, sans jamais le remplacer ou le rendre dépendant.
67
  """
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  def post_process_response(response):
70
+ last_sentence_end = max(response.rfind('.'), response.rfind('!'), response.rfind('?'))
71
+ if last_sentence_end != -1:
72
+ return response[:last_sentence_end + 1]
73
+ else:
74
+ return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  @spaces.GPU(duration=120)
77
  def generate(
 
80
  system_prompt: str,
81
  max_new_tokens: int = DEFAULT_MAX_NEW_TOKENS,
82
  temperature: float = 0.7,
83
+ top_p: float = 0.95,
 
84
  ) -> Iterator[str]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  conversation = []
86
  if system_prompt:
87
  enhanced_system_prompt = f"{system_prompt}\n\nInformations sur Lucas :\n{LUCAS_KNOWLEDGE_BASE}"
88
  conversation.append({"role": "system", "content": enhanced_system_prompt})
89
+ for user, assistant in chat_history:
 
 
 
 
90
  conversation.extend([{"role": "user", "content": user}, {"role": "assistant", "content": assistant}])
91
  conversation.append({"role": "user", "content": message})
 
92
  input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt")
93
  if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
94
  input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
95
  gr.Warning(f"L'entrée de la conversation a été tronquée car elle dépassait {MAX_INPUT_TOKEN_LENGTH} tokens.")
96
  input_ids = input_ids.to(model.device)
97
  streamer = TextIteratorStreamer(tokenizer, timeout=10.0, skip_prompt=True, skip_special_tokens=True)
 
 
 
 
98
  generate_kwargs = dict(
99
  input_ids=input_ids,
100
  streamer=streamer,
 
103
  top_p=top_p,
104
  temperature=temperature,
105
  num_beams=1,
 
 
 
106
  )
107
  t = Thread(target=model.generate, kwargs=generate_kwargs)
108
  t.start()