rag-demo / app.py
jamalinu's picture
Update app.py
13d3e7f verified
Raw
History Blame Contribute Delete
4.13 kB
import spaces # debe importarse antes que cualquier paquete relacionado con CUDA
import gradio as gr
import fitz # PyMuPDF para leer PDFs
import os
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from groq import Groq
# 1. Configuraci贸n de embeddings (Modelo ligero y r谩pido)
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# 2. Funci贸n para cargar y procesar el PDF
def load_and_index_pdf(pdf_file):
if pdf_file is None:
return "Por favor, sube un archivo PDF."
# Gradio entrega una ruta de archivo (string) directamente,
# no hace falta guardar una copia manual.
doc = fitz.open(pdf_file)
text = ""
for page in doc:
text += page.get_text()
# Dividir en trozos (Chunking)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_text(text)
# Crear la base de datos vectorial FAISS
vectorstore = FAISS.from_texts(chunks, embeddings)
return vectorstore
# Funci贸n "dummy" solo para satisfacer el requisito de arranque de ZeroGPU
# (Hugging Face exige que exista al menos una funci贸n @spaces.GPU, pero
# esta funci贸n real de RAG no necesita GPU: FAISS corre en CPU y el LLM
# se llama por API remota, no localmente).
@spaces.GPU
def _zerogpu_startup_check():
return True
# 3. Funci贸n de respuesta (RAG)
def respond(vectorstore, user_query):
if not user_query:
return "Hazme una pregunta sobre el documento."
# Buscar los trozos m谩s relevantes
docs = vectorstore.similarity_search(user_query, k=2)
# Construir el contexto
context = "\n\n".join([d.page_content for d in docs])
prompt = f"""
Basado en el siguiente contexto, responde a la pregunta.
Si la respuesta no est谩 en el contexto, di "No tengo esa informaci贸n en el documento".
Contexto: {context}
Pregunta: {user_query}
Respuesta:
"""
groq_client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
completion = groq_client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="llama-3.3-70b-versatile",
temperature=0.7,
)
return completion.choices[0].message.content
# 4. Interfaz Gradio
def main():
# Estado global para la base de datos
vectorstore_state = None
def process_upload(pdf_file):
nonlocal vectorstore_state
if pdf_file:
vectorstore_state = load_and_index_pdf(pdf_file)
return "Documento procesado con 茅xito. 隆Pregunta lo que quieras!", gr.update(interactive=True)
return "Sube un PDF primero.", gr.update(interactive=False)
def process_query(query):
if vectorstore_state is None:
return "Por favor, sube un PDF primero."
return respond(vectorstore_state, query)
with gr.Blocks(title="RAG Demo - Dow Jones Style") as demo:
gr.Markdown("# 馃摎 Chat con tus Documentos (RAG + FAISS)")
gr.Markdown("Sube un PDF y pregunta sobre su contenido. 隆Sin alucinaciones!")
with gr.Row():
with gr.Column():
pdf_input = gr.File(label="Sube tu PDF aqu铆", file_types=[".pdf"])
upload_btn = gr.Button("Procesar Documento", variant="primary")
status_msg = gr.Textbox(label="Estado", interactive=False)
with gr.Column():
query_input = gr.Textbox(label="Tu pregunta", placeholder="驴De qu茅 trata este documento?")
submit_btn = gr.Button("Enviar Pregunta", interactive=False)
output_msg = gr.Textbox(label="Respuesta de la IA")
# L贸gica de interacci贸n
upload_btn.click(
fn=process_upload,
inputs=pdf_input,
outputs=[status_msg, submit_btn],
)
submit_btn.click(
fn=process_query,
inputs=query_input,
outputs=output_msg,
)
demo.launch()
if __name__ == "__main__":
main()