Sacof commited on
Commit
a1614de
·
verified ·
1 Parent(s): 3f39afe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -31
app.py CHANGED
@@ -2,45 +2,58 @@ import gradio as gr
2
  from transformers import AutoModelForCausalLM, AutoTokenizer
3
  import torch
4
  import os
5
- import csv
6
- from datetime import datetime
7
  import spaces
 
 
 
 
8
  # === CONFIGURATION ===
9
- MODEL_NAME = "facebook/MobileLLM-Pro" # ✅ Léger et rapide sur CPU
10
  INFO_FILE = "infos_medicaux.txt"
11
- LOG_FILE = "historique_questions.csv"
12
- MAX_TOKENS = 800
13
  TEMPERATURE = 0.6
 
 
14
 
15
  # === CHARGEMENT DU MODÈLE ===
16
  print("⏳ Chargement du modèle...")
17
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
18
  model = AutoModelForCausalLM.from_pretrained(
19
  MODEL_NAME,
20
- torch_dtype=torch.float32
 
 
21
  )
22
  model.eval()
23
- print("✅ Modèle chargé avec succès")
24
 
25
- # === CHARGEMENT DU CONTEXTE MÉDICAL ===
 
26
  if os.path.exists(INFO_FILE):
27
  with open(INFO_FILE, "r", encoding="utf-8") as f:
28
  medical_context = f.read()
29
- print(f"📘 Contexte médical chargé ({len(medical_context)} caractères)")
 
30
  else:
31
- medical_context = ""
32
  print("⚠️ Aucun fichier infos_medicaux.txt trouvé.")
33
 
34
- # === FONCTION DE LOG DES QUESTIONS ===
35
- def log_question(user_message, response):
36
- file_exists = os.path.exists(LOG_FILE)
37
- with open(LOG_FILE, "a", encoding="utf-8", newline="") as csvfile:
38
- writer = csv.writer(csvfile)
39
- if not file_exists:
40
- writer.writerow(["Timestamp", "Question", "Réponse"])
41
- writer.writerow([datetime.now().isoformat(), user_message, response])
 
 
 
 
 
 
 
42
 
43
- # === FONCTION DE CHAT ===
44
  @spaces.GPU()
45
  def chat_with_finanfa(message, history=None):
46
  if history is None:
@@ -48,22 +61,25 @@ def chat_with_finanfa(message, history=None):
48
 
49
  system_prompt = (
50
  "Tu es FINANFA, un assistant médical béninois, professionnel et empathique. "
51
- "Tu t'appuies sur les connaissances médicales fournies ci-dessous. "
52
  "Tu ne réponds qu’aux questions liées à la santé, aux maladies ou aux médicaments. "
53
  "Si la question n’est pas médicale, dis poliment que tu ne peux pas répondre. "
54
  "Donne des réponses claires, détaillées et adaptées au Bénin."
55
  )
56
 
57
- # Construction du contexte complet
 
 
58
  conversation = f"Système : {system_prompt}\n"
59
- if medical_context:
60
- conversation += f"Connaissances médicales : {medical_context}\n"
61
- for user_msg, bot_msg in history:
 
62
  conversation += f"Utilisateur : {user_msg}\nAssistant : {bot_msg}\n"
 
63
  conversation += f"Utilisateur : {message}\nAssistant :"
64
 
65
- # Génération de la réponse
66
- inputs = tokenizer(conversation, return_tensors="pt", truncation=True)
67
  with torch.no_grad():
68
  outputs = model.generate(
69
  **inputs,
@@ -75,10 +91,6 @@ def chat_with_finanfa(message, history=None):
75
 
76
  response = tokenizer.decode(outputs[0], skip_special_tokens=True)
77
  response = response.split("Assistant :")[-1].strip()
78
-
79
- # Enregistrement automatique dans le CSV
80
- log_question(message, response)
81
-
82
  return response
83
 
84
  # === INTERFACE GRADIO ===
@@ -102,4 +114,4 @@ with gr.Blocks(title="FINANFA — Chatbot Médical") as demo:
102
  ]
103
  )
104
 
105
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  from transformers import AutoModelForCausalLM, AutoTokenizer
3
  import torch
4
  import os
 
 
5
  import spaces
6
+ from sklearn.feature_extraction.text import TfidfVectorizer
7
+ from sklearn.metrics.pairwise import cosine_similarity
8
+ import numpy as np
9
+
10
  # === CONFIGURATION ===
11
+ MODEL_NAME = "google/gemma-2b-it"
12
  INFO_FILE = "infos_medicaux.txt"
13
+ MAX_TOKENS = 600
 
14
  TEMPERATURE = 0.6
15
+ CHUNK_SIZE = 1000 # caractères par chunk
16
+ TOP_K_CHUNKS = 3 # Nombre de chunks pertinents à inclure
17
 
18
  # === CHARGEMENT DU MODÈLE ===
19
  print("⏳ Chargement du modèle...")
20
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
21
  model = AutoModelForCausalLM.from_pretrained(
22
  MODEL_NAME,
23
+ torch_dtype=torch.float32,
24
+ device_map=None,
25
+ low_cpu_mem_usage=True
26
  )
27
  model.eval()
28
+ print("✅ Modèle chargé avec succès !")
29
 
30
+ # === CHARGEMENT DU CONTEXTE MÉDICAL ET DÉCOUPAGE EN CHUNKS ===
31
+ medical_context_chunks = []
32
  if os.path.exists(INFO_FILE):
33
  with open(INFO_FILE, "r", encoding="utf-8") as f:
34
  medical_context = f.read()
35
+ medical_context_chunks = [medical_context[i:i+CHUNK_SIZE] for i in range(0, len(medical_context), CHUNK_SIZE)]
36
+ print(f"📘 Contexte médical chargé ({len(medical_context)} caractères, {len(medical_context_chunks)} chunks)")
37
  else:
 
38
  print("⚠️ Aucun fichier infos_medicaux.txt trouvé.")
39
 
40
+ # === TF-IDF pour recherche de chunks pertinents ===
41
+ if medical_context_chunks:
42
+ vectorizer = TfidfVectorizer().fit(medical_context_chunks)
43
+ chunk_vectors = vectorizer.transform(medical_context_chunks)
44
+ else:
45
+ vectorizer = None
46
+ chunk_vectors = None
47
+
48
+ def get_relevant_chunks(question, top_k=TOP_K_CHUNKS):
49
+ if not medical_context_chunks or vectorizer is None:
50
+ return []
51
+ q_vec = vectorizer.transform([question])
52
+ similarities = cosine_similarity(q_vec, chunk_vectors)[0]
53
+ top_indices = np.argsort(similarities)[::-1][:top_k]
54
+ return [medical_context_chunks[i] for i in top_indices]
55
 
56
+ # === FONCTION DE CHAT OPTIMISÉE ===
57
  @spaces.GPU()
58
  def chat_with_finanfa(message, history=None):
59
  if history is None:
 
61
 
62
  system_prompt = (
63
  "Tu es FINANFA, un assistant médical béninois, professionnel et empathique. "
64
+ "Tu t'appuies uniquement sur les connaissances médicales fournies ci-dessous. "
65
  "Tu ne réponds qu’aux questions liées à la santé, aux maladies ou aux médicaments. "
66
  "Si la question n’est pas médicale, dis poliment que tu ne peux pas répondre. "
67
  "Donne des réponses claires, détaillées et adaptées au Bénin."
68
  )
69
 
70
+ # Récupération des chunks pertinents
71
+ relevant_chunks = get_relevant_chunks(message)
72
+
73
  conversation = f"Système : {system_prompt}\n"
74
+ for chunk in relevant_chunks:
75
+ conversation += f"Connaissances médicales : {chunk}\n"
76
+
77
+ for user_msg, bot_msg in history[-5:]:
78
  conversation += f"Utilisateur : {user_msg}\nAssistant : {bot_msg}\n"
79
+
80
  conversation += f"Utilisateur : {message}\nAssistant :"
81
 
82
+ inputs = tokenizer(conversation, return_tensors="pt", truncation=True, max_length=2048)
 
83
  with torch.no_grad():
84
  outputs = model.generate(
85
  **inputs,
 
91
 
92
  response = tokenizer.decode(outputs[0], skip_special_tokens=True)
93
  response = response.split("Assistant :")[-1].strip()
 
 
 
 
94
  return response
95
 
96
  # === INTERFACE GRADIO ===
 
114
  ]
115
  )
116
 
117
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860)