Spaces:
Sleeping
Sleeping
File size: 3,924 Bytes
cfad8ea 43786a1 9e45e2f 7977dd9 9e45e2f 43786a1 c3ec6b8 bc04226 cfad8ea 2b163ef c3ec6b8 cfad8ea c3ec6b8 a56b6e1 cfad8ea 7977dd9 c3ec6b8 43786a1 1e68c9d 43786a1 c3ec6b8 43786a1 cfad8ea bc04226 5d9d076 43786a1 9e45e2f c3ec6b8 cf8cdc7 43786a1 cfad8ea c3ec6b8 7977dd9 75062ee cfad8ea c3ec6b8 d524d40 1e68c9d c3ec6b8 43786a1 c3ec6b8 43786a1 9e45e2f 43786a1 9e45e2f 43786a1 c3ec6b8 43786a1 cfad8ea c3ec6b8 7977dd9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
import gradio as gr
import pickle
import os
import json
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'.")
# Cargar diccionario de sinónimos
with open("sinonimos.json", "r", encoding="utf-8") as f:
diccionario_sinonimos = json.load(f)
# Función para expandir palabras clave con sinónimos
def expandir_con_sinonimos(palabras, diccionario):
resultado = set(palabras)
for palabra in palabras:
for clave, sinonimos in diccionario.items():
if palabra == clave or palabra in sinonimos:
resultado.update([clave] + sinonimos)
return list(resultado)
# 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=50)
result_chunks = [chunks[i] for i in indices[0]]
palabras_clave = pregunta.lower().split()
palabras_expandidas = expandir_con_sinonimos(palabras_clave, diccionario_sinonimos)
filtrados = [c for c in result_chunks if any(p in c.lower() for p in palabras_expandidas)]
contexto_final = "\n\n".join(filtrados[:15]) if filtrados else "\n\n".join(result_chunks[:15])
prompt = prompt = f"""
Eres un abogado colombiano especializado en el Código de Tránsito, Código de Policía y Código Penal.
Tu tarea es analizar el siguiente contexto legal y responder a la pregunta de forma clara y precisa.
Instrucciones:
- Usa únicamente el contexto legal proporcionado para fundamentar tu respuesta.
- Si encuentras artículos relevantes, cítalos de forma clara.
- Si el texto no contiene una respuesta exacta, intenta dar una explicación general basada en el contexto.
- Sé directo, claro y utiliza un lenguaje accesible.
- Finaliza con una breve recomendación si es pertinente.
CONTEXTO LEGAL:
{contexto_final}
PREGUNTA:
{pregunta}
RESPUESTA:
"""
resultado = llm(
prompt,
max_new_tokens=500,
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()
|