Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1,27 +1,29 @@
|
|
1 |
# ===========================================================
|
2 |
-
# Assistant virtuel
|
3 |
# Auteur : Presley Koyaweda
|
4 |
-
# Description : Application Gradio
|
5 |
# ===========================================================
|
6 |
|
7 |
import os
|
8 |
import torch
|
9 |
import gradio as gr
|
|
|
|
|
|
|
10 |
from PyPDF2 import PdfReader
|
11 |
from huggingface_hub import login, snapshot_download
|
|
|
|
|
12 |
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer
|
13 |
from mistral_inference.transformer import Transformer
|
14 |
from mistral_inference.generate import generate
|
15 |
from mistral_common.protocol.instruct.messages import UserMessage, TextChunk
|
16 |
from mistral_common.protocol.instruct.request import ChatCompletionRequest
|
17 |
-
from sentence_transformers import SentenceTransformer
|
18 |
-
import faiss
|
19 |
-
import numpy as np
|
20 |
|
21 |
-
# === Authentification HF ===
|
22 |
login(os.environ["HUGGINGFACEHUB_API_TOKEN"])
|
23 |
|
24 |
-
# === 1. Chargement et découpage PDF ===
|
25 |
def load_chunks(folder="data", chunk_size=1000, overlap=200):
|
26 |
chunks = []
|
27 |
for fname in os.listdir(folder):
|
@@ -42,36 +44,51 @@ def load_chunks(folder="data", chunk_size=1000, overlap=200):
|
|
42 |
documents = load_chunks()
|
43 |
texts = documents.copy()
|
44 |
|
45 |
-
# === 2.
|
46 |
embedder = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
|
47 |
embeddings = embedder.encode(texts, normalize_embeddings=True)
|
48 |
dimension = embeddings.shape[1]
|
49 |
index = faiss.IndexFlatIP(dimension)
|
50 |
index.add(np.array(embeddings))
|
51 |
|
52 |
-
# === 3.
|
53 |
model_dir = os.path.expanduser("~/pixtral/Pixtral")
|
54 |
-
snapshot_download(
|
|
|
|
|
|
|
|
|
55 |
tokenizer = MistralTokenizer.from_file(f"{model_dir}/tekken.json")
|
56 |
model = Transformer.from_folder(model_dir)
|
57 |
|
58 |
-
# === 4. Fonction de
|
59 |
-
def vovodo_fr(message):
|
|
|
60 |
query_embedding = embedder.encode([message], normalize_embeddings=True)
|
61 |
D, I = index.search(np.array(query_embedding), k=3)
|
62 |
context = "\n".join([texts[i] for i in I[0]])
|
63 |
|
|
|
64 |
prompt = f"Contexte : {context}\n\nQuestion : {message}\nRéponse :"
|
65 |
messages = [UserMessage(content=[TextChunk(text=prompt)])]
|
66 |
req = ChatCompletionRequest(messages=messages)
|
|
|
|
|
67 |
encoded = tokenizer.encode_chat_completion(req)
|
68 |
-
out_tokens, _ = generate(
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
output = tokenizer.decode(out_tokens[0])
|
70 |
return output.split("Réponse :")[-1].strip()
|
71 |
|
72 |
# === 5. Interface Gradio ===
|
73 |
gr.ChatInterface(
|
74 |
fn=vovodo_fr,
|
75 |
-
title="VOVODO – Assistant Chinko (Pixtral + FAISS)",
|
76 |
-
description="Posez vos questions sur les documents de la Réserve de Chinko.",
|
|
|
77 |
).launch(share=True)
|
|
|
1 |
# ===========================================================
|
2 |
+
# VOVODO – Assistant virtuel pour la Réserve de Chinko (RCA)
|
3 |
# Auteur : Presley Koyaweda
|
4 |
+
# Description : Application Gradio avec RAG (Pixtral + FAISS)
|
5 |
# ===========================================================
|
6 |
|
7 |
import os
|
8 |
import torch
|
9 |
import gradio as gr
|
10 |
+
import numpy as np
|
11 |
+
import faiss
|
12 |
+
|
13 |
from PyPDF2 import PdfReader
|
14 |
from huggingface_hub import login, snapshot_download
|
15 |
+
from sentence_transformers import SentenceTransformer
|
16 |
+
|
17 |
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer
|
18 |
from mistral_inference.transformer import Transformer
|
19 |
from mistral_inference.generate import generate
|
20 |
from mistral_common.protocol.instruct.messages import UserMessage, TextChunk
|
21 |
from mistral_common.protocol.instruct.request import ChatCompletionRequest
|
|
|
|
|
|
|
22 |
|
23 |
+
# === Authentification HF (nécessite HUGGINGFACEHUB_API_TOKEN dans .env ou variable env) ===
|
24 |
login(os.environ["HUGGINGFACEHUB_API_TOKEN"])
|
25 |
|
26 |
+
# === 1. Chargement et découpage des documents PDF ===
|
27 |
def load_chunks(folder="data", chunk_size=1000, overlap=200):
|
28 |
chunks = []
|
29 |
for fname in os.listdir(folder):
|
|
|
44 |
documents = load_chunks()
|
45 |
texts = documents.copy()
|
46 |
|
47 |
+
# === 2. Embedding + Indexation FAISS ===
|
48 |
embedder = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
|
49 |
embeddings = embedder.encode(texts, normalize_embeddings=True)
|
50 |
dimension = embeddings.shape[1]
|
51 |
index = faiss.IndexFlatIP(dimension)
|
52 |
index.add(np.array(embeddings))
|
53 |
|
54 |
+
# === 3. Chargement du modèle Pixtral localement ===
|
55 |
model_dir = os.path.expanduser("~/pixtral/Pixtral")
|
56 |
+
snapshot_download(
|
57 |
+
"mistral-community/pixtral-12b-240910",
|
58 |
+
local_dir=model_dir,
|
59 |
+
allow_patterns=["*.json", "*.safetensors"]
|
60 |
+
)
|
61 |
tokenizer = MistralTokenizer.from_file(f"{model_dir}/tekken.json")
|
62 |
model = Transformer.from_folder(model_dir)
|
63 |
|
64 |
+
# === 4. Fonction de génération avec contexte vectoriel ===
|
65 |
+
def vovodo_fr(message: str) -> str:
|
66 |
+
# Recherche dans la base
|
67 |
query_embedding = embedder.encode([message], normalize_embeddings=True)
|
68 |
D, I = index.search(np.array(query_embedding), k=3)
|
69 |
context = "\n".join([texts[i] for i in I[0]])
|
70 |
|
71 |
+
# Création du prompt
|
72 |
prompt = f"Contexte : {context}\n\nQuestion : {message}\nRéponse :"
|
73 |
messages = [UserMessage(content=[TextChunk(text=prompt)])]
|
74 |
req = ChatCompletionRequest(messages=messages)
|
75 |
+
|
76 |
+
# Génération
|
77 |
encoded = tokenizer.encode_chat_completion(req)
|
78 |
+
out_tokens, _ = generate(
|
79 |
+
[encoded.tokens],
|
80 |
+
model,
|
81 |
+
max_tokens=512,
|
82 |
+
temperature=0.3,
|
83 |
+
eos_id=tokenizer.instruct_tokenizer.tokenizer.eos_id
|
84 |
+
)
|
85 |
output = tokenizer.decode(out_tokens[0])
|
86 |
return output.split("Réponse :")[-1].strip()
|
87 |
|
88 |
# === 5. Interface Gradio ===
|
89 |
gr.ChatInterface(
|
90 |
fn=vovodo_fr,
|
91 |
+
title="🌿 VOVODO – Assistant Chinko (Pixtral + FAISS)",
|
92 |
+
description="Posez vos questions sur les documents de la Réserve de Chinko. Modèle : Pixtral 12B + MiniLM.",
|
93 |
+
theme="soft",
|
94 |
).launch(share=True)
|