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})