MMOON commited on
Commit
72532b7
·
verified ·
1 Parent(s): 02f9aa6

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +180 -45
src/streamlit_app.py CHANGED
@@ -1,87 +1,191 @@
1
  import streamlit as st
2
  import torch
3
- from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
4
  from huggingface_hub import login
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  # ==============================================================================
7
- # --- CONFIGURATION DE LA PAGE ---
 
 
 
 
 
8
  # Définit le titre, l'icône et la mise en page de l'application.
9
  # ==============================================================================
10
  st.set_page_config(
11
- page_title="Chat Avancé avec Apertus",
 
 
 
12
  page_icon="🚀",
13
  layout="wide",
14
- initial_sidebar_state="expanded",
 
 
15
  )
16
 
17
  # ==============================================================================
18
- # --- BARRE LATÉRALE (SIDEBAR) ---
 
 
 
19
  # Contient toutes les options de configuration pour l'utilisateur.
 
 
 
 
 
 
 
20
  # ==============================================================================
 
21
  with st.sidebar:
22
  st.title("🚀 Paramètres")
23
  st.markdown("Configurez l'assistant et le modèle de langage.")
24
 
25
  # --- Section d'Authentification Hugging Face ---
26
- st.subheader("Authentification Hugging Face")
27
- hf_token = st.text_input("Votre Token Hugging Face (hf_...)", type="password")
 
 
 
 
28
  if st.button("Se Connecter"):
29
- if hf_token:
 
 
 
30
  try:
31
  login(token=hf_token)
32
- st.success("Connecté à Hugging Face Hub !")
 
33
  st.session_state.hf_logged_in = True
34
  except Exception as e:
35
- st.error(f"Échec de la connexion : {e}")
 
 
 
36
  else:
37
  st.warning("Veuillez entrer un token Hugging Face.")
38
 
39
  # --- Section de Sélection du Modèle ---
40
- st.subheader("Sélection du Modèle")
 
 
41
  model_options = {
42
- "Apertus 8B (Rapide)": "swiss-ai/Apertus-8B-Instruct-2509",
43
- "Apertus 70B (Puissant)": "swiss-ai/Apertus-70B-2509"
 
 
 
 
 
 
 
 
44
  }
45
- selected_model_name = st.selectbox("Choisissez un modèle :", options=list(model_options.keys()))
46
- model_id = model_options[selected_model_name]
 
 
 
47
  st.caption(f"ID du modèle : `{model_id}`")
48
 
49
- # --- Section des Paramètres de Génération ---
 
50
  st.subheader("Paramètres de Génération")
51
- temperature = st.slider(
 
 
52
  "Température",
53
- min_value=0.1, max_value=1.5, value=0.7, step=0.05,
54
- help="Plus la valeur est élevée, plus la réponse est créative et aléatoire."
 
 
55
  )
56
  max_new_tokens = st.slider(
 
 
 
57
  "Tokens Max",
58
- min_value=64, max_value=1024, value=256, step=64,
 
 
59
  help="Longueur maximale de la réponse générée."
60
- )
 
61
  top_p = st.slider(
62
  "Top-p (Nucleus Sampling)",
63
- min_value=0.1, max_value=1.0, value=0.95, step=0.05,
64
- help="Contrôle la diversité en sélectionnant les mots les plus probables."
65
  )
 
 
 
 
 
66
 
67
  # --- Bouton pour effacer l'historique ---
68
- st.subheader("Gestion du Chat")
 
 
 
69
  if st.button("🗑️ Effacer l'historique"):
70
- st.session_state.messages = []
 
 
71
  st.experimental_rerun()
72
 
73
  # ==============================================================================
74
- # --- FONCTION DE CHARGEMENT DU MODÈLE ---
 
 
 
 
75
  # Mise en cache pour ne charger le modèle qu'une seule fois.
 
 
 
 
 
 
 
 
 
 
 
 
76
  # ==============================================================================
77
  @st.cache_resource(show_spinner=False)
78
- def load_model(model_identifier):
 
79
  """Charge le tokenizer et le modèle avec quantification 4-bit."""
80
  with st.spinner(f"Chargement du modèle '{model_identifier}'... Cela peut prendre un moment. ⏳"):
81
  bnb_config = BitsAndBytesConfig(
82
  load_in_4bit=True,
83
  bnb_4bit_quant_type="nf4",
84
- bnb_4bit_compute_dtype=torch.bfloat16,
 
 
 
 
 
 
85
  )
86
  tokenizer = AutoTokenizer.from_pretrained(model_identifier)
87
  model = AutoModelForCausalLM.from_pretrained(
@@ -91,59 +195,90 @@ def load_model(model_identifier):
91
  )
92
  return tokenizer, model
93
 
 
 
 
 
 
 
 
 
 
 
 
94
  # Essai de chargement du modèle
95
  try:
96
  tokenizer, model = load_model(model_id)
97
  except Exception as e:
98
- st.error(f"Impossible de charger le modèle. Assurez-vous d'être connecté si le modèle est privé. Erreur : {e}")
99
  st.stop()
100
 
101
  # ==============================================================================
102
  # --- INTERFACE DE CHAT PRINCIPALE ---
103
  # Affiche les messages et gère les entrées de l'utilisateur.
 
 
 
 
 
104
  # ==============================================================================
105
  st.title("🤖 Chat avec Apertus")
106
- st.caption(f"Vous discutez actuellement avec **{selected_model_name}**.")
 
 
 
 
 
 
 
107
 
108
- # Initialisation de l'historique du chat s'il n'existe pas
 
 
109
  if "messages" not in st.session_state:
110
  st.session_state.messages = []
111
 
112
  # Affichage des messages de l'historique
113
- for message in st.session_state.messages:
 
 
114
  with st.chat_message(message["role"]):
115
- st.markdown(message["content"])
 
 
116
 
117
  # Zone de saisie pour l'utilisateur
118
- if prompt := st.chat_input("Posez votre question à Apertus..."):
 
 
 
119
  # Ajout et affichage du message de l'utilisateur
120
- st.session_state.messages.append({"role": "user", "content": prompt})
 
 
121
  with st.chat_message("user"):
122
- st.markdown(prompt)
 
123
 
124
  # --- Génération de la réponse de l'assistant ---
125
  with st.chat_message("assistant"):
126
  response_placeholder = st.empty()
127
  with st.spinner("Réflexion en cours... 🤔"):
128
  # Préparation des entrées pour le modèle
129
- input_ids = tokenizer(prompt, return_tensors="pt").to(model.device)
130
-
131
- # Génération de la réponse
132
  outputs = model.generate(
133
  **input_ids,
134
- max_new_tokens=max_new_tokens,
 
 
 
135
  do_sample=True,
136
  temperature=temperature,
137
  top_p=top_p,
138
  eos_token_id=tokenizer.eos_token_id
139
  )
140
-
141
- # Décodage et nettoyage de la réponse
142
  response_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
143
- # Nettoyage pour retirer le prompt de la réponse générée
144
  cleaned_response = response_text.replace(prompt, "").strip()
145
-
146
  response_placeholder.markdown(cleaned_response)
147
 
148
- # Ajout de la réponse de l'assistant à l'historique
149
  st.session_state.messages.append({"role": "assistant", "content": cleaned_response})
 
1
  import streamlit as st
2
  import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytes deux lignes nécessaires (`import os` et `os.environ[...]`) au début du script. Copiez-collez ce codeConfig
4
  from huggingface_hub import login
5
+ import os
6
+
7
+ # --- CONFIGURATION DU CHEMIN DU CACHE HUGGING FACE complet pour remplacer l'intégralité de votre fichier.
8
+
9
+ ```python
10
+ import streamlit as st
11
+ import torch
12
+ from ---
13
+ # On définit un dossier local pour le cache pour éviter les erreurs de permission.
14
+ os.environ['HF_HOME'] = './.cache'
15
+ # On s'assure que le dossier existe.
16
+ os.makedirs transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
17
+ from huggingface_hub import login
18
+ import(os.environ['HF_HOME'], exist_ok=True)
19
+
20
 
21
  # ==============================================================================
22
+ # --- os
23
+
24
+ # ==============================================================================
25
+ # --- CONFIGURATION DU CACHE HUGGING FACE ---
26
+ # Définit un répertoire de cache accessible en écriture dans l'environnement cloud.
27
+ # CELA DOIT ÊTRE FA CONFIGURATION DE LA PAGE ---
28
  # Définit le titre, l'icône et la mise en page de l'application.
29
  # ==============================================================================
30
  st.set_page_config(
31
+ page_title="Chat AvIT AVANT TOUT APPEL À LA BIBLIOTHÈQUE TRANSFORMERS/HUB.
32
+ # ==============================================================================
33
+ os.environ["HF_HOME"] = "/tmp/huggingface"
34
+ os.environ["HFancé avec Apertus",
35
  page_icon="🚀",
36
  layout="wide",
37
+ initial_sidebar_HUB_CACHE"] = "/tmp/huggingface" # Double assurance
38
+
39
+ # ==============================================================================_state="expanded",
40
  )
41
 
42
  # ==============================================================================
43
+ # --- BARRE LATÉRALE (
44
+ # --- CONFIGURATION DE LA PAGE ---
45
+ # ==============================================================================
46
+ st.set_page_config(SIDEBAR) ---
47
  # Contient toutes les options de configuration pour l'utilisateur.
48
+ # =================================================================
49
+ page_title="Chat Avancé avec Apertus",
50
+ page_icon="🚀",
51
+ layout="wide",
52
+ initial_sidebar_state="expanded",
53
+ )
54
+
55
  # ==============================================================================
56
+ =============
57
  with st.sidebar:
58
  st.title("🚀 Paramètres")
59
  st.markdown("Configurez l'assistant et le modèle de langage.")
60
 
61
  # --- Section d'Authentification Hugging Face ---
62
+ st.subheader# --- BARRE LATÉRALE (SIDEBAR) ---
63
+ # ==============================================================================
64
+ with st.sidebar("Authentification Hugging Face")
65
+ hf_token = st.text_input("Votre Token Hugging Face (:
66
+ st.title("🚀 Paramètres")
67
+ st.markdown("Configurez l'assistant et le modèlehf_...)", type="password")
68
  if st.button("Se Connecter"):
69
+ if hf_token: de langage.")
70
+
71
+ # --- Section d'Authentification Hugging Face ---
72
+ st.subheader("Authentification Hugging Face
73
  try:
74
  login(token=hf_token)
75
+ st.success("Connecté à Hugging Face Hub")
76
+ hf_token = st.text_input("Votre Token Hugging Face (hf_...)", type !")
77
  st.session_state.hf_logged_in = True
78
  except Exception as e:
79
+ ="password")
80
+ if st.button("Se Connecter"):
81
+ if hf_token:
82
+ try st.error(f"Échec de la connexion : {e}")
83
  else:
84
  st.warning("Veuillez entrer un token Hugging Face.")
85
 
86
  # --- Section de Sélection du Modèle ---
87
+ st.subheader:
88
+ # La bibliothèque utilisera maintenant le dossier défini dans HF_HOME
89
+ login(token=hf_token)("Sélection du Modèle")
90
  model_options = {
91
+ "Apertus 8B (Rap
92
+ st.success("Connecté à Hugging Face Hub !")
93
+ st.session_state.hf_loggedide)": "swiss-ai/Apertus-8B-Instruct-2509",
94
+ "A_in = True
95
+ except Exception as e:
96
+ st.error(f"Échec de la connexionpertus 70B (Puissant)": "swiss-ai/Apertus-70B- : {e}")
97
+ else:
98
+ st.warning("Veuillez entrer un token Hugging Face.")
99
+
100
+ 2509"
101
  }
102
+ selected_model_name = st.selectbox("Choisissez un modèle : # --- Section de Sélection du Modèle ---
103
+ st.subheader("Sélection du Modèle")
104
+ model", options=list(model_options.keys()))
105
+ model_id = model_options[selected_model__options = {
106
+ "Apertus 8B (Rapide)": "swiss-ai/Aname]
107
  st.caption(f"ID du modèle : `{model_id}`")
108
 
109
+ # --- Section despertus-8B-Instruct-2509",
110
+ "Apertus 70B (Pu Paramètres de Génération ---
111
  st.subheader("Paramètres de Génération")
112
+ temperature = st.sliderissant)": "swiss-ai/Apertus-70B-2509"
113
+ }
114
+ (
115
  "Température",
116
+ min_value=0.1, max_value=1.5, selected_model_name = st.selectbox("Choisissez un modèle :", options=list(model_options. value=0.7, step=0.05,
117
+ help="Plus la valeur est élevée, pluskeys()))
118
+ model_id = model_options[selected_model_name]
119
+ st.caption( la réponse est créative et aléatoire."
120
  )
121
  max_new_tokens = st.slider(
122
+ f"ID du modèle : `{model_id}`")
123
+
124
+ # --- Section des Paramètres de Génération ---
125
  "Tokens Max",
126
+ min_value=64, max_value=1024, value st.subheader("Paramètres de Génération")
127
+ temperature = st.slider(
128
+ "Température", =256, step=64,
129
  help="Longueur maximale de la réponse générée."
130
+
131
+ min_value=0.1, max_value=1.5, value=0.7, step)
132
  top_p = st.slider(
133
  "Top-p (Nucleus Sampling)",
134
+ min_=0.05,
135
+ help="Plus la valeur est élevée, plus la réponse est créative et alévalue=0.1, max_value=1.0, value=0.95, step=0atoire."
136
  )
137
+ max_new_tokens = st.slider(
138
+ "Tokens Max",
139
+ .05,
140
+ help="Contrôle la diversité en sélectionnant les mots les plus probables."
141
+ )min_value=64, max_value=1024, value=256, step=64,
142
 
143
  # --- Bouton pour effacer l'historique ---
144
+ st.subheader("Gestion du Chat
145
+ help="Longueur maximale de la réponse générée."
146
+ )
147
+ top_p = st.slider")
148
  if st.button("🗑️ Effacer l'historique"):
149
+ st.session_state.messages(
150
+ "Top-p (Nucleus Sampling)",
151
+ min_value=0.1, max_ = []
152
  st.experimental_rerun()
153
 
154
  # ==============================================================================
155
+ # --- FONCTION DE CHARvalue=1.0, value=0.95, step=0.05,
156
+ help="Contrôle la diversité en sélectionnant les mots les plus probables."
157
+ )
158
+
159
+ # --- BoutGEMENT DU MODÈLE ---
160
  # Mise en cache pour ne charger le modèle qu'une seule fois.
161
+ #on pour effacer l'historique ---
162
+ st.subheader("Gestion du Chat")
163
+ if st.button("🗑️ Effacer l'historique"):
164
+ st.session_state.messages = []
165
+ st.experimental ==============================================================================
166
+ @st.cache_resource(show_spinner=False)
167
+ def load_model(model_rerun()
168
+
169
+ # ==============================================================================
170
+ # --- FONCTION DE CHARGEMENT DU MODÈLE ---_identifier):
171
+ """Charge le tokenizer et le modèle avec quantification 4-bit."""
172
+ with st.spinner(f
173
  # ==============================================================================
174
  @st.cache_resource(show_spinner=False)
175
+ def load"Chargement du modèle '{model_identifier}'... Cela peut prendre un moment. ⏳"):
176
+ bnb_config_model(model_identifier):
177
  """Charge le tokenizer et le modèle avec quantification 4-bit."""
178
  with st.spinner(f"Chargement du modèle '{model_identifier}'... Cela peut prendre un moment. ⏳"):
179
  bnb_config = BitsAndBytesConfig(
180
  load_in_4bit=True,
181
  bnb_4bit_quant_type="nf4",
182
+ bnb_4bit_compute_dtype=torch.bfloat = BitsAndBytesConfig(
183
+ load_in_4bit=True,
184
+ bnb_4bit_quant_type="nf4",
185
+ bnb_4bit_compute_dtype=torch.bfloat16,16,
186
+ )
187
+ tokenizer = AutoTokenizer.from_pretrained(model_identifier)
188
+ model
189
  )
190
  tokenizer = AutoTokenizer.from_pretrained(model_identifier)
191
  model = AutoModelForCausalLM.from_pretrained(
 
195
  )
196
  return tokenizer, model
197
 
198
+ # Essai de chargement du modèle
199
+ = AutoModelForCausalLM.from_pretrained(
200
+ model_identifier,
201
+ quantization_config=bnbtry:
202
+ tokenizer, model = load_model(model_id)
203
+ except Exception as e:
204
+ st._config,
205
+ device_map="auto",
206
+ )
207
+ return tokenizer, model
208
+
209
  # Essai de chargement du modèle
210
  try:
211
  tokenizer, model = load_model(model_id)
212
  except Exception as e:
213
+ st.error(f"Impossible de charger le modèle. Assurez-vous d'être connecté si le modèle est privé.error(f"Impossible de charger le modèle. Assurez-vous d'être connecté si le modèle est privé. Erreur : {e}")
214
  st.stop()
215
 
216
  # ==============================================================================
217
  # --- INTERFACE DE CHAT PRINCIPALE ---
218
  # Affiche les messages et gère les entrées de l'utilisateur.
219
+ # Erreur : {e}")
220
+ st.stop()
221
+
222
+ # ==============================================================================
223
+ # --- INTERFACE DE CHAT PRINCIPALE ---
224
  # ==============================================================================
225
  st.title("🤖 Chat avec Apertus")
226
+ ==============================================================================
227
+ st.title("🤖 Chat avec Apertus")
228
+ st.caption(f"Vous discst.caption(f"Vous discutez actuellement avec **{selected_model_name}**.")
229
+
230
+ ifutez actuellement avec **{selected_model_name}**.")
231
+
232
+ # Initialisation de l'historique du chat "messages" not in st.session_state:
233
+ st.session_state.messages = []
234
 
235
+ for message in st.session_state.messages:
236
+ with st.chat_message(message["role"]):
237
+ st s'il n'existe pas
238
  if "messages" not in st.session_state:
239
  st.session_state.messages = []
240
 
241
  # Affichage des messages de l'historique
242
+ for message in st.session_state..markdown(message["content"])
243
+
244
+ if prompt := st.chat_input("Posez votre question à Apertus..."):messages:
245
  with st.chat_message(message["role"]):
246
+ st.markdown(message["content
247
+ st.session_state.messages.append({"role": "user", "content": prompt})
248
+ "])
249
 
250
  # Zone de saisie pour l'utilisateur
251
+ if prompt := st.chat_input("Posez votre question àwith st.chat_message("user"):
252
+ st.markdown(prompt)
253
+
254
+ with st.chat_ Apertus..."):
255
  # Ajout et affichage du message de l'utilisateur
256
+ st.session_state.messagesmessage("assistant"):
257
+ response_placeholder = st.empty()
258
+ with st.spinner("Réflexion en.append({"role": "user", "content": prompt})
259
  with st.chat_message("user"):
260
+ cours... 🤔"):
261
+ input_ids = tokenizer(prompt, return_tensors="pt").to(model.st.markdown(prompt)
262
 
263
  # --- Génération de la réponse de l'assistant ---
264
  with st.chat_message("assistant"):
265
  response_placeholder = st.empty()
266
  with st.spinner("Réflexion en cours... 🤔"):
267
  # Préparation des entrées pour le modèle
268
+ input_ids = tokenizerdevice)
 
 
269
  outputs = model.generate(
270
  **input_ids,
271
+ max_new_tokens=max(prompt, return_tensors="pt").to(model.device)
272
+
273
+ # Génération de la réponse
274
+ _new_tokens,
275
  do_sample=True,
276
  temperature=temperature,
277
  top_p=top_p,
278
  eos_token_id=tokenizer.eos_token_id
279
  )
 
 
280
  response_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
 
281
  cleaned_response = response_text.replace(prompt, "").strip()
 
282
  response_placeholder.markdown(cleaned_response)
283
 
 
284
  st.session_state.messages.append({"role": "assistant", "content": cleaned_response})