TALLER_1_3 / app.py
thejarll's picture
Update app.py
bc04226 verified
raw
history blame
3.39 kB
import gradio as gr
import pickle
import os
from transformers import AutoTokenizer, AutoModel, pipeline
import torch
import faiss
import numpy as np
from spaces import GPU # IMPORTANTE para ZeroGPU
# Token para modelos privados si se requiere
hf_token = os.getenv("HF_KEY")
# Cargar índice FAISS y los chunks
if os.path.exists("index.pkl"):
with open("index.pkl", "rb") as f:
index, chunks = pickle.load(f)
else:
raise FileNotFoundError("No se encontró el archivo 'index.pkl'.")
# Modelo de embeddings
model_id = "jinaai/jina-embeddings-v2-base-es"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModel.from_pretrained(model_id)
def generar_embedding(texto):
inputs = tokenizer(texto, return_tensors="pt", padding=True, truncation=True)
with torch.no_grad():
outputs = model(**inputs)
last_hidden = outputs.last_hidden_state
mask = inputs["attention_mask"].unsqueeze(-1).expand(last_hidden.size()).float()
summed = torch.sum(last_hidden * mask, 1)
counted = torch.clamp(mask.sum(1), min=1e-9)
mean_pooled = summed / counted
return mean_pooled.numpy()
# LLM para generar respuesta final
llm = pipeline(
"text-generation",
model="meta-llama/Llama-3.2-3B-Instruct",
token=hf_token,
trust_remote_code=True
)
@GPU # DECORADOR para que ZeroGPU ejecute esta función en CPU/GPU remota
def responder(pregunta):
if not pregunta:
return "Por favor ingresa una pregunta."
pregunta_embedding = generar_embedding(pregunta)
distances, indices = index.search(pregunta_embedding.reshape(1, -1), k=20)
result_chunks = [chunks[i] for i in indices[0]]
palabras_clave = pregunta.lower().split()
filtrados = [c for c in result_chunks if any(p in c.lower() for p in palabras_clave)]
contexto_final = "\n\n".join(filtrados[:3]) if filtrados else "\n\n".join(result_chunks[:3])
prompt = f"""
Actúa como un asesor legal colombiano, especializado en el Código de Tránsito, Código de Policía y Código Penal.
Analiza el siguiente contexto legal y responde la pregunta de forma clara, completa y profesional.
Instrucciones:
- Usa un lenguaje formal y preciso.
- Fundamenta tu respuesta solo en el contexto proporcionado.
- Cita artículos, normas o sanciones si están presentes en el texto.
- Finaliza con una recomendación preventiva si aplica.
- Si no encuentras información suficiente, responde:
**"No encontré información suficiente en la ley para responder a esta pregunta."**
- No inventes información ni cites leyes que no estén en el contexto.
CONTEXTO LEGAL:
{contexto_final}
PREGUNTA:
{pregunta}
RESPUESTA:
"""
resultado = llm(
prompt,
max_new_tokens=350,
temperature=0.4,
top_p=0.9,
repetition_penalty=1.2
)[0]["generated_text"]
if "RESPUESTA:" in resultado:
solo_respuesta = resultado.split("RESPUESTA:")[-1].strip()
else:
solo_respuesta = resultado.strip()
return solo_respuesta
# Interfaz de usuario con Gradio
demo = gr.Interface(
fn=responder,
inputs=gr.Textbox(label="Escribe tu pregunta"),
outputs=gr.Textbox(label="Respuesta generada"),
title="Asistente Legal Colombiano",
description="Consulta el Código de Tránsito, Código de Policía y Código Penal colombiano."
)
if __name__ == "__main__":
demo.launch()