AshenClock commited on
Commit
b6960a0
·
verified ·
1 Parent(s): f59396d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -27
app.py CHANGED
@@ -5,12 +5,12 @@ from pydantic import BaseModel
5
  from fastapi import FastAPI, HTTPException
6
  import rdflib
7
  from rdflib import RDF, RDFS, OWL
8
- from huggingface_hub import InferenceClient
9
  from sentence_transformers import SentenceTransformer
10
  import faiss
11
  import json
12
  import numpy as np
13
  from dotenv import load_dotenv
 
14
 
15
  # Carica le variabili d'ambiente
16
  load_dotenv()
@@ -29,9 +29,6 @@ if not API_KEY:
29
  logger.error("HF_API_KEY non impostata.")
30
  raise EnvironmentError("HF_API_KEY non impostata.")
31
 
32
- # Inizializza InferenceClient
33
- client = InferenceClient(token=API_KEY)
34
-
35
  # Definisci i percorsi dei file
36
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
37
  RDF_FILE = os.path.join(BASE_DIR, "Ontologia.rdf")
@@ -136,7 +133,7 @@ def create_faiss_index(documents_file: str, index_file: str, embedding_model: st
136
  with open(documents_file, "r", encoding="utf-8") as f:
137
  document = json.load(f)
138
  logger.info(f"Documento caricato da {documents_file}.")
139
-
140
  # Genera embedding
141
  model = SentenceTransformer(embedding_model)
142
  # Concatenazione delle classi, proprietà e entità per l'embedding
@@ -145,13 +142,13 @@ def create_faiss_index(documents_file: str, index_file: str, embedding_model: st
145
  texts += [f"Entità: {entity['label']}. Descrizione: {entity['description']}. Proprietà: {entity['properties']}" for entity in document.get('entities', [])]
146
  embeddings = model.encode(texts, convert_to_numpy=True)
147
  logger.info("Embedding generati con SentenceTransformer.")
148
-
149
  # Crea l'indice FAISS
150
  dimension = embeddings.shape[1]
151
  index = faiss.IndexFlatL2(dimension)
152
  index.add(embeddings)
153
  logger.info(f"Indice FAISS creato con dimensione: {dimension}.")
154
-
155
  # Salva l'indice
156
  faiss.write_index(index, index_file)
157
  logger.info(f"Indice FAISS salvato in {index_file}.")
@@ -257,25 +254,25 @@ def retrieve_relevant_documents(query: str, top_k: int = 5):
257
  with open(DOCUMENTS_FILE, "r", encoding="utf-8") as f:
258
  document = json.load(f)
259
  logger.info(f"Documento caricato da {DOCUMENTS_FILE}.")
260
-
261
  # Carica l'indice FAISS
262
  index = faiss.read_index(FAISS_INDEX_FILE)
263
  logger.info(f"Indice FAISS caricato da {FAISS_INDEX_FILE}.")
264
-
265
  # Genera embedding della query
266
  model = SentenceTransformer('all-MiniLM-L6-v2')
267
  query_embedding = model.encode([query], convert_to_numpy=True)
268
  logger.info("Embedding della query generati.")
269
-
270
  # Ricerca nell'indice
271
  distances, indices = index.search(query_embedding, top_k)
272
  logger.info(f"Ricerca FAISS completata. Risultati ottenuti: {len(indices[0])}")
273
-
274
  # Concatenazione delle descrizioni per la ricerca
275
  texts = [f"Classe: {cls['label']}. Descrizione: {cls['description']}" for cls in document['classes']]
276
  texts += [f"Proprietà: {prop['label']}. Descrizione: {prop['description']}" for prop in document['properties']]
277
  texts += [f"Entità: {entity['label']}. Descrizione: {entity['description']}. Proprietà: {entity['properties']}" for entity in document.get('entities', [])]
278
-
279
  # Recupera i testi rilevanti
280
  relevant_texts = [texts[idx] for idx in indices[0] if idx < len(texts)]
281
  retrieved_docs = "\n".join(relevant_texts)
@@ -291,7 +288,7 @@ def create_system_message(ont_text: str, retrieved_docs: str) -> str:
291
  informazioni recuperate tramite RAG.
292
  """
293
  return f"""
294
- Sei un assistente museale esperto in ontologie RDF. Utilizza le informazioni fornite per generare query SPARQL precise e pertinenti. Ecco un estratto di CLASSI, PROPRIETÀ ed ENTITÀ dell'ontologia (senza NamedIndividuals):
295
  --- ONTOLOGIA ---
296
  {ont_text}
297
  --- FINE ---
@@ -325,30 +322,47 @@ Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare
325
  """
326
 
327
  async def call_hf_model(prompt: str, temperature: float = 0.5, max_tokens: int = 1024) -> str:
328
- """Chiama il modello Hugging Face e gestisce la risposta."""
329
  logger.debug("Chiamo HF con il seguente prompt:")
330
  content_preview = (prompt[:300] + '...') if len(prompt) > 300 else prompt
331
  logger.debug(f"PROMPT => {content_preview}")
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  try:
333
- resp = client.text_generation(
334
- HF_MODEL, # Argomento posizionale: modello
335
- prompt, # Argomento posizionale: input
336
- parameters={
337
- "temperature": temperature,
338
- "max_new_tokens": max_tokens,
339
- "top_p": 0.9
340
- }
341
  )
342
- logger.debug(f"Risposta completa dal modello: {resp}")
343
- raw = resp.get("generated_text", "")
344
- if not raw:
345
- raise ValueError("Nessun testo generato dal modello.")
 
 
 
 
 
 
 
 
346
  # Forza la risposta su una singola linea se multilinea
347
  single_line = " ".join(raw.splitlines())
348
  logger.debug(f"Risposta HF single-line: {single_line}")
349
  return single_line.strip()
350
  except Exception as e:
351
- logger.error(f"HuggingFace error: {e}")
352
  raise HTTPException(status_code=500, detail=str(e))
353
 
354
  # Prepara i file necessari per RAG
 
5
  from fastapi import FastAPI, HTTPException
6
  import rdflib
7
  from rdflib import RDF, RDFS, OWL
 
8
  from sentence_transformers import SentenceTransformer
9
  import faiss
10
  import json
11
  import numpy as np
12
  from dotenv import load_dotenv
13
+ import requests
14
 
15
  # Carica le variabili d'ambiente
16
  load_dotenv()
 
29
  logger.error("HF_API_KEY non impostata.")
30
  raise EnvironmentError("HF_API_KEY non impostata.")
31
 
 
 
 
32
  # Definisci i percorsi dei file
33
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
34
  RDF_FILE = os.path.join(BASE_DIR, "Ontologia.rdf")
 
133
  with open(documents_file, "r", encoding="utf-8") as f:
134
  document = json.load(f)
135
  logger.info(f"Documento caricato da {documents_file}.")
136
+
137
  # Genera embedding
138
  model = SentenceTransformer(embedding_model)
139
  # Concatenazione delle classi, proprietà e entità per l'embedding
 
142
  texts += [f"Entità: {entity['label']}. Descrizione: {entity['description']}. Proprietà: {entity['properties']}" for entity in document.get('entities', [])]
143
  embeddings = model.encode(texts, convert_to_numpy=True)
144
  logger.info("Embedding generati con SentenceTransformer.")
145
+
146
  # Crea l'indice FAISS
147
  dimension = embeddings.shape[1]
148
  index = faiss.IndexFlatL2(dimension)
149
  index.add(embeddings)
150
  logger.info(f"Indice FAISS creato con dimensione: {dimension}.")
151
+
152
  # Salva l'indice
153
  faiss.write_index(index, index_file)
154
  logger.info(f"Indice FAISS salvato in {index_file}.")
 
254
  with open(DOCUMENTS_FILE, "r", encoding="utf-8") as f:
255
  document = json.load(f)
256
  logger.info(f"Documento caricato da {DOCUMENTS_FILE}.")
257
+
258
  # Carica l'indice FAISS
259
  index = faiss.read_index(FAISS_INDEX_FILE)
260
  logger.info(f"Indice FAISS caricato da {FAISS_INDEX_FILE}.")
261
+
262
  # Genera embedding della query
263
  model = SentenceTransformer('all-MiniLM-L6-v2')
264
  query_embedding = model.encode([query], convert_to_numpy=True)
265
  logger.info("Embedding della query generati.")
266
+
267
  # Ricerca nell'indice
268
  distances, indices = index.search(query_embedding, top_k)
269
  logger.info(f"Ricerca FAISS completata. Risultati ottenuti: {len(indices[0])}")
270
+
271
  # Concatenazione delle descrizioni per la ricerca
272
  texts = [f"Classe: {cls['label']}. Descrizione: {cls['description']}" for cls in document['classes']]
273
  texts += [f"Proprietà: {prop['label']}. Descrizione: {prop['description']}" for prop in document['properties']]
274
  texts += [f"Entità: {entity['label']}. Descrizione: {entity['description']}. Proprietà: {entity['properties']}" for entity in document.get('entities', [])]
275
+
276
  # Recupera i testi rilevanti
277
  relevant_texts = [texts[idx] for idx in indices[0] if idx < len(texts)]
278
  retrieved_docs = "\n".join(relevant_texts)
 
288
  informazioni recuperate tramite RAG.
289
  """
290
  return f"""
291
+ Sei un assistente museale esperto in ontologie RDF. Utilizza le informazioni fornite per generare query SPARQL precise e pertinenti. Ecco un estratto di CLASSI, PROPRIETÀ ed ENTità dell'ontologia (senza NamedIndividuals):
292
  --- ONTOLOGIA ---
293
  {ont_text}
294
  --- FINE ---
 
322
  """
323
 
324
  async def call_hf_model(prompt: str, temperature: float = 0.5, max_tokens: int = 1024) -> str:
325
+ """Chiama il modello Hugging Face tramite l'API REST e gestisce la risposta."""
326
  logger.debug("Chiamo HF con il seguente prompt:")
327
  content_preview = (prompt[:300] + '...') if len(prompt) > 300 else prompt
328
  logger.debug(f"PROMPT => {content_preview}")
329
+
330
+ headers = {
331
+ "Authorization": f"Bearer {API_KEY}"
332
+ }
333
+ payload = {
334
+ "inputs": prompt,
335
+ "parameters": {
336
+ "temperature": temperature,
337
+ "max_new_tokens": max_tokens,
338
+ "top_p": 0.9
339
+ }
340
+ }
341
+
342
  try:
343
+ response = requests.post(
344
+ f"https://api-inference.huggingface.co/models/{HF_MODEL}",
345
+ headers=headers,
346
+ json=payload
 
 
 
 
347
  )
348
+ if response.status_code != 200:
349
+ logger.error(f"Errore nella chiamata all'API Hugging Face: {response.status_code} - {response.text}")
350
+ raise HTTPException(status_code=500, detail=f"Errore nell'API Hugging Face: {response.text}")
351
+ data = response.json()
352
+ logger.debug(f"Risposta completa dal modello: {data}")
353
+ if isinstance(data, list) and len(data) > 0 and "generated_text" in data[0]:
354
+ raw = data[0]["generated_text"]
355
+ elif "generated_text" in data:
356
+ raw = data["generated_text"]
357
+ else:
358
+ raise ValueError("Nessun campo 'generated_text' nella risposta.")
359
+
360
  # Forza la risposta su una singola linea se multilinea
361
  single_line = " ".join(raw.splitlines())
362
  logger.debug(f"Risposta HF single-line: {single_line}")
363
  return single_line.strip()
364
  except Exception as e:
365
+ logger.error(f"Errore nella chiamata all'API Hugging Face tramite requests: {e}")
366
  raise HTTPException(status_code=500, detail=str(e))
367
 
368
  # Prepara i file necessari per RAG