|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
```python |
|
|
import streamlit as st |
|
|
import torch |
|
|
from --- |
|
|
|
|
|
os.environ['HF_HOME'] = './.cache' |
|
|
|
|
|
os.makedirs transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig |
|
|
from huggingface_hub import login |
|
|
import(os.environ['HF_HOME'], exist_ok=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.set_page_config(SIDEBAR) --- |
|
|
|
|
|
|
|
|
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.") |
|
|
|
|
|
|
|
|
st.subheader |
|
|
|
|
|
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.") |
|
|
|
|
|
|
|
|
st.subheader: |
|
|
|
|
|
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}`") |
|
|
|
|
|
|
|
|
"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, |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
|
|
|
help="Contrôle la diversité en sélectionnant les mots les plus probables." |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
|
|
|
"""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 |
|
|
|
|
|
|
|
|
= 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 |
|
|
|
|
|
|
|
|
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. |
|
|
|
|
|
st.stop() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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}**.") |
|
|
|
|
|
|
|
|
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 = [] |
|
|
|
|
|
|
|
|
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}) |
|
|
"]) |
|
|
|
|
|
|
|
|
if prompt := st.chat_input("Posez votre question àwith st.chat_message("user"): |
|
|
st.markdown(prompt) |
|
|
|
|
|
with st.chat_ Apertus..."): |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
with st.chat_message("assistant"): |
|
|
response_placeholder = st.empty() |
|
|
with st.spinner("Réflexion en cours... 🤔"): |
|
|
|
|
|
input_ids = tokenizerdevice) |
|
|
outputs = model.generate( |
|
|
**input_ids, |
|
|
max_new_tokens=max(prompt, return_tensors="pt").to(model.device) |
|
|
|
|
|
|
|
|
_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}) |