APERTUSMM / src /streamlit_app.py
MMOON's picture
Update src/streamlit_app.py
72532b7 verified
import streamlit as st
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytes deux lignes nécessaires (`import os` et `os.environ[...]`) au début du script. Copiez-collez ce codeConfig
from huggingface_hub import login
import os
# --- CONFIGURATION DU CHEMIN DU CACHE HUGGING FACE complet pour remplacer l'intégralité de votre fichier.
```python
import streamlit as st
import torch
from ---
# On définit un dossier local pour le cache pour éviter les erreurs de permission.
os.environ['HF_HOME'] = './.cache'
# On s'assure que le dossier existe.
os.makedirs transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from huggingface_hub import login
import(os.environ['HF_HOME'], exist_ok=True)
# ==============================================================================
# --- os
# ==============================================================================
# --- CONFIGURATION DU CACHE HUGGING FACE ---
# Définit un répertoire de cache accessible en écriture dans l'environnement cloud.
# CELA DOIT ÊTRE FA CONFIGURATION DE LA PAGE ---
# Définit le titre, l'icône et la mise en page de l'application.
# ==============================================================================
st.set_page_config(
page_title="Chat AvIT AVANT TOUT APPEL À LA BIBLIOTHÈQUE TRANSFORMERS/HUB.
# ==============================================================================
os.environ["HF_HOME"] = "/tmp/huggingface"
os.environ["HFancé avec Apertus",
page_icon="🚀",
layout="wide",
initial_sidebar_HUB_CACHE"] = "/tmp/huggingface" # Double assurance
# ==============================================================================_state="expanded",
)
# ==============================================================================
# --- BARRE LATÉRALE (
# --- CONFIGURATION DE LA PAGE ---
# ==============================================================================
st.set_page_config(SIDEBAR) ---
# Contient toutes les options de configuration pour l'utilisateur.
# =================================================================
page_title="Chat Avancé avec Apertus",
page_icon="🚀",
layout="wide",
initial_sidebar_state="expanded",
)
# ==============================================================================
=============
with st.sidebar:
st.title("🚀 Paramètres")
st.markdown("Configurez l'assistant et le modèle de langage.")
# --- Section d'Authentification Hugging Face ---
st.subheader# --- BARRE LATÉRALE (SIDEBAR) ---
# ==============================================================================
with st.sidebar("Authentification Hugging Face")
hf_token = st.text_input("Votre Token Hugging Face (:
st.title("🚀 Paramètres")
st.markdown("Configurez l'assistant et le modèlehf_...)", type="password")
if st.button("Se Connecter"):
if hf_token: de langage.")
# --- Section d'Authentification Hugging Face ---
st.subheader("Authentification Hugging Face
try:
login(token=hf_token)
st.success("Connecté à Hugging Face Hub")
hf_token = st.text_input("Votre Token Hugging Face (hf_...)", type !")
st.session_state.hf_logged_in = True
except Exception as e:
="password")
if st.button("Se Connecter"):
if hf_token:
try st.error(f"Échec de la connexion : {e}")
else:
st.warning("Veuillez entrer un token Hugging Face.")
# --- Section de Sélection du Modèle ---
st.subheader:
# La bibliothèque utilisera maintenant le dossier défini dans HF_HOME
login(token=hf_token)("Sélection du Modèle")
model_options = {
"Apertus 8B (Rap
st.success("Connecté à Hugging Face Hub !")
st.session_state.hf_loggedide)": "swiss-ai/Apertus-8B-Instruct-2509",
"A_in = True
except Exception as e:
st.error(f"Échec de la connexionpertus 70B (Puissant)": "swiss-ai/Apertus-70B- : {e}")
else:
st.warning("Veuillez entrer un token Hugging Face.")
2509"
}
selected_model_name = st.selectbox("Choisissez un modèle : # --- Section de Sélection du Modèle ---
st.subheader("Sélection du Modèle")
model", options=list(model_options.keys()))
model_id = model_options[selected_model__options = {
"Apertus 8B (Rapide)": "swiss-ai/Aname]
st.caption(f"ID du modèle : `{model_id}`")
# --- Section despertus-8B-Instruct-2509",
"Apertus 70B (Pu Paramètres de Génération ---
st.subheader("Paramètres de Génération")
temperature = st.sliderissant)": "swiss-ai/Apertus-70B-2509"
}
(
"Température",
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,
help="Plus la valeur est élevée, pluskeys()))
model_id = model_options[selected_model_name]
st.caption( la réponse est créative et aléatoire."
)
max_new_tokens = st.slider(
f"ID du modèle : `{model_id}`")
# --- Section des Paramètres de Génération ---
"Tokens Max",
min_value=64, max_value=1024, value st.subheader("Paramètres de Génération")
temperature = st.slider(
"Température", =256, step=64,
help="Longueur maximale de la réponse générée."
min_value=0.1, max_value=1.5, value=0.7, step)
top_p = st.slider(
"Top-p (Nucleus Sampling)",
min_=0.05,
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."
)
max_new_tokens = st.slider(
"Tokens Max",
.05,
help="Contrôle la diversité en sélectionnant les mots les plus probables."
)min_value=64, max_value=1024, value=256, step=64,
# --- Bouton pour effacer l'historique ---
st.subheader("Gestion du Chat
help="Longueur maximale de la réponse générée."
)
top_p = st.slider")
if st.button("🗑️ Effacer l'historique"):
st.session_state.messages(
"Top-p (Nucleus Sampling)",
min_value=0.1, max_ = []
st.experimental_rerun()
# ==============================================================================
# --- FONCTION DE CHARvalue=1.0, value=0.95, step=0.05,
help="Contrôle la diversité en sélectionnant les mots les plus probables."
)
# --- BoutGEMENT DU MODÈLE ---
# Mise en cache pour ne charger le modèle qu'une seule fois.
#on pour effacer l'historique ---
st.subheader("Gestion du Chat")
if st.button("🗑️ Effacer l'historique"):
st.session_state.messages = []
st.experimental ==============================================================================
@st.cache_resource(show_spinner=False)
def load_model(model_rerun()
# ==============================================================================
# --- FONCTION DE CHARGEMENT DU MODÈLE ---_identifier):
"""Charge le tokenizer et le modèle avec quantification 4-bit."""
with st.spinner(f
# ==============================================================================
@st.cache_resource(show_spinner=False)
def load"Chargement du modèle '{model_identifier}'... Cela peut prendre un moment. ⏳"):
bnb_config_model(model_identifier):
"""Charge le tokenizer et le modèle avec quantification 4-bit."""
with st.spinner(f"Chargement du modèle '{model_identifier}'... Cela peut prendre un moment. ⏳"):
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,16,
)
tokenizer = AutoTokenizer.from_pretrained(model_identifier)
model
)
tokenizer = AutoTokenizer.from_pretrained(model_identifier)
model = AutoModelForCausalLM.from_pretrained(
model_identifier,
quantization_config=bnb_config,
device_map="auto",
)
return tokenizer, model
# Essai de chargement du modèle
= AutoModelForCausalLM.from_pretrained(
model_identifier,
quantization_config=bnbtry:
tokenizer, model = load_model(model_id)
except Exception as e:
st._config,
device_map="auto",
)
return tokenizer, model
# Essai de chargement du modèle
try:
tokenizer, model = load_model(model_id)
except Exception as e:
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}")
st.stop()
# ==============================================================================
# --- INTERFACE DE CHAT PRINCIPALE ---
# Affiche les messages et gère les entrées de l'utilisateur.
# Erreur : {e}")
st.stop()
# ==============================================================================
# --- INTERFACE DE CHAT PRINCIPALE ---
# ==============================================================================
st.title("🤖 Chat avec Apertus")
==============================================================================
st.title("🤖 Chat avec Apertus")
st.caption(f"Vous discst.caption(f"Vous discutez actuellement avec **{selected_model_name}**.")
ifutez actuellement avec **{selected_model_name}**.")
# Initialisation de l'historique du chat "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st s'il n'existe pas
if "messages" not in st.session_state:
st.session_state.messages = []
# Affichage des messages de l'historique
for message in st.session_state..markdown(message["content"])
if prompt := st.chat_input("Posez votre question à Apertus..."):messages:
with st.chat_message(message["role"]):
st.markdown(message["content
st.session_state.messages.append({"role": "user", "content": prompt})
"])
# Zone de saisie pour l'utilisateur
if prompt := st.chat_input("Posez votre question àwith st.chat_message("user"):
st.markdown(prompt)
with st.chat_ Apertus..."):
# Ajout et affichage du message de l'utilisateur
st.session_state.messagesmessage("assistant"):
response_placeholder = st.empty()
with st.spinner("Réflexion en.append({"role": "user", "content": prompt})
with st.chat_message("user"):
cours... 🤔"):
input_ids = tokenizer(prompt, return_tensors="pt").to(model.st.markdown(prompt)
# --- Génération de la réponse de l'assistant ---
with st.chat_message("assistant"):
response_placeholder = st.empty()
with st.spinner("Réflexion en cours... 🤔"):
# Préparation des entrées pour le modèle
input_ids = tokenizerdevice)
outputs = model.generate(
**input_ids,
max_new_tokens=max(prompt, return_tensors="pt").to(model.device)
# Génération de la réponse
_new_tokens,
do_sample=True,
temperature=temperature,
top_p=top_p,
eos_token_id=tokenizer.eos_token_id
)
response_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
cleaned_response = response_text.replace(prompt, "").strip()
response_placeholder.markdown(cleaned_response)
st.session_state.messages.append({"role": "assistant", "content": cleaned_response})