news_parser / app.py
DEXTools's picture
Update app.py
565d181 verified
Raw History Blame Contribute Delete
2.91 kB
import gradio as gr
import spaces
from huggingface_hub import login
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import os
# AUTENTICACIÓN CORRECTA PARA GEMMA EN SPACES
hf_token = os.getenv("HF_CLASSIFIER")
if hf_token:
login(token=hf_token)
print("Autenticado con HF_CLASSIFIER")
else:
print("ERROR: HF_CLASSIFIER no encontrado en Secrets")
# Carga modelo y tokenizer
model_id = "google/gemma-3-4b-it"
print(f"Cargando {model_id}...")
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True
)
SYSTEM_PROMPT = """You are an expert assistant that analyzes user messages.
ALWAYS respond ONLY with valid JSON in this EXACT format:
{
"summary": "Brief and clear summary of the user's message (max 1-2 sentences)",
"tags": ["tag1", "tag2", "tag3"],
"sentiment": {
"score": -1.0,
"label": "NEGATIVE | NEUTRAL | POSITIVE",
"explanation": "Brief reason for the analysis"
}
}
RULES:
- summary: Capture the main essence
- tags: 3-5 relevant keywords (themes, emotions, entities)
- sentiment: score (-1.0=negative, 0=neutral, +1.0=positive)
- NEVER add text outside the JSON
- JSON must be valid and parseable"""
@spaces.GPU(duration=120)
def generate_response(message, history):
model.to('cuda')
messages = []
for user_msg, ai_msg in history:
messages.append({"role": "user", "content": user_msg})
if ai_msg:
messages.append({"role": "assistant", "content": ai_msg})
messages.append({"role": "user", "content": "System: "+SYSTEM_PROMPT+" User:"+message})
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=1512, # Aumentado para evitar respuestas cortadas (truncadas)
do_sample=True,
temperature=0.7,
pad_token_id=tokenizer.eos_token_id,
eos_token_id=tokenizer.eos_token_id # Añadido para forzar fin completo y evitar truncado
)
response = tokenizer.decode(
outputs[0][inputs.input_ids.shape[1]:],
skip_special_tokens=True
).strip()
model.to('cpu')
torch.cuda.empty_cache()
return response
# Interfaz estándar genérica con Gradio ChatInterface (sin CSS personalizado ni Blocks, como pide la documentación oficial de Gradio)
demo = gr.ChatInterface(
fn=generate_response,
title="Desxtools Crypto News Text Analyzer",
description="Chatbot estándar con google/gemma-3-4b-it en ZeroGPU. Diseño genérico sin modificaciones.",
cache_examples=True
)
if __name__ == "__main__":
demo.launch()