Cristobal299 commited on
Commit
ec28fe4
Β·
verified Β·
1 Parent(s): 1bc5373

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +23 -8
  2. app.py +136 -0
  3. requirements.txt +7 -0
README.md CHANGED
@@ -1,13 +1,28 @@
1
  ---
2
- title: Chat
3
- emoji: πŸ‘€
4
- colorFrom: indigo
5
- colorTo: red
6
  sdk: gradio
7
- sdk_version: 6.19.0
8
- python_version: '3.12'
9
  app_file: app.py
10
- pinned: false
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Fenix Brain
3
+ emoji: 🧠
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: "5.29.0"
 
8
  app_file: app.py
9
+ pinned: true
10
+ license: mit
11
  ---
12
 
13
+ # 🧠 Fénix Brain
14
+
15
+ LLM de cΓ³digo para La Forja de FΓ©nix.
16
+ Modelo: **Qwen2.5-Coder-14B-Instruct** Β· GPU: ZeroGPU
17
+
18
+ ## API
19
+
20
+ ```
21
+ POST /ask
22
+ {
23
+ "prompt": "Tu pregunta de cΓ³digo",
24
+ "key": "TU_BRAIN_API_KEY",
25
+ "system": "opcional",
26
+ "max_tokens": 2048
27
+ }
28
+ ```
app.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ FΓ©nix Brain β€” LLM de cΓ³digo para La Forja
4
+ ==========================================
5
+ Space con ZeroGPU + Qwen2.5-Coder-14B-Instruct
6
+ Expone:
7
+ POST /ask {"prompt": "...", "key": "..."} β†’ {"ok": True, "response": "..."}
8
+ GET / β†’ Chat UI con Gradio
9
+ """
10
+
11
+ import os
12
+ import spaces
13
+ import gradio as gr
14
+ from transformers import AutoTokenizer, AutoModelForCausalLM
15
+ import torch
16
+
17
+ MODEL_ID = "Qwen/Qwen2.5-Coder-14B-Instruct"
18
+ API_KEY = os.environ.get("BRAIN_API_KEY", "")
19
+
20
+ # ── Cargar modelo ─────────────────────────────────────────────────────────────
21
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
22
+ model = None # Se carga en primera peticiΓ³n con ZeroGPU
23
+
24
+ def _cargar_modelo():
25
+ global model
26
+ if model is None:
27
+ model = AutoModelForCausalLM.from_pretrained(
28
+ MODEL_ID,
29
+ torch_dtype=torch.bfloat16,
30
+ device_map="auto",
31
+ trust_remote_code=True,
32
+ )
33
+ return model
34
+
35
+ # ── Inferencia ────────────────────────────────────────────────────────────────
36
+ @spaces.GPU(duration=120)
37
+ def _inferir(prompt: str, system: str = "", max_tokens: int = 2048) -> str:
38
+ mdl = _cargar_modelo()
39
+ messages = []
40
+ if system:
41
+ messages.append({"role": "system", "content": system})
42
+ messages.append({"role": "user", "content": prompt})
43
+
44
+ text = tokenizer.apply_chat_template(
45
+ messages, tokenize=False, add_generation_prompt=True
46
+ )
47
+ inputs = tokenizer([text], return_tensors="pt").to(mdl.device)
48
+ with torch.no_grad():
49
+ out = mdl.generate(
50
+ **inputs,
51
+ max_new_tokens=max_tokens,
52
+ temperature=0.2,
53
+ do_sample=True,
54
+ pad_token_id=tokenizer.eos_token_id,
55
+ )
56
+ generated = out[0][inputs["input_ids"].shape[1]:]
57
+ return tokenizer.decode(generated, skip_special_tokens=True)
58
+
59
+ # ── FastAPI endpoints ─────────────────────────────────────────────────────────
60
+ from fastapi import FastAPI, Request
61
+ from fastapi.responses import JSONResponse
62
+
63
+ fapp = FastAPI()
64
+
65
+ @fapp.post("/ask")
66
+ async def ask(request: Request):
67
+ try:
68
+ data = await request.json()
69
+ key = data.get("key", "")
70
+ if API_KEY and key != API_KEY:
71
+ return JSONResponse({"ok": False, "error": "Unauthorized"}, status_code=401)
72
+ prompt = data.get("prompt", "")
73
+ system = data.get("system", "Eres un experto programador Python y Gradio. Responde siempre en espaΓ±ol con cΓ³digo limpio y funcional.")
74
+ max_t = int(data.get("max_tokens", 2048))
75
+ if not prompt:
76
+ return JSONResponse({"ok": False, "error": "prompt requerido"}, status_code=400)
77
+ respuesta = _inferir(prompt, system, max_t)
78
+ return JSONResponse({"ok": True, "response": respuesta})
79
+ except Exception as e:
80
+ return JSONResponse({"ok": False, "error": str(e)}, status_code=500)
81
+
82
+ @fapp.get("/health")
83
+ async def health():
84
+ return JSONResponse({"ok": True, "model": MODEL_ID})
85
+
86
+ # ── Gradio UI (chat) ──────────────────────────────────────────────────────────
87
+ SYSTEM_DEFAULT = "Eres FΓ©nix Brain, el asistente de cΓ³digo de La Forja de FΓ©nix. Eres experto en Python, Gradio, FastAPI y HuggingFace Spaces. Responde siempre en espaΓ±ol con cΓ³digo limpio."
88
+
89
+ def chat(mensaje, historial, system_prompt):
90
+ if not mensaje.strip():
91
+ return historial, ""
92
+ messages = [{"role": "system", "content": system_prompt or SYSTEM_DEFAULT}]
93
+ for h in historial:
94
+ messages.append({"role": "user", "content": h[0]})
95
+ messages.append({"role": "assistant", "content": h[1]})
96
+ messages.append({"role": "user", "content": mensaje})
97
+
98
+ text = tokenizer.apply_chat_template(
99
+ messages, tokenize=False, add_generation_prompt=True
100
+ )
101
+
102
+ @spaces.GPU(duration=120)
103
+ def _gen():
104
+ mdl = _cargar_modelo()
105
+ inputs = tokenizer([text], return_tensors="pt").to(mdl.device)
106
+ with torch.no_grad():
107
+ out = mdl.generate(
108
+ **inputs, max_new_tokens=2048, temperature=0.2,
109
+ do_sample=True, pad_token_id=tokenizer.eos_token_id,
110
+ )
111
+ gen = out[0][inputs["input_ids"].shape[1]:]
112
+ return tokenizer.decode(gen, skip_special_tokens=True)
113
+
114
+ respuesta = _gen()
115
+ historial = historial + [[mensaje, respuesta]]
116
+ return historial, ""
117
+
118
+ with gr.Blocks(title="🧠 Fénix Brain", theme=gr.themes.Base()) as demo:
119
+ gr.Markdown("# 🧠 Fénix Brain\nAsistente de código para La Forja · Qwen2.5-Coder-14B")
120
+ system_box = gr.Textbox(label="System prompt", value=SYSTEM_DEFAULT, lines=2)
121
+ chatbot = gr.Chatbot(height=500, label="Chat")
122
+ msg_box = gr.Textbox(placeholder="Escribe tu pregunta de cΓ³digo…", label="Mensaje")
123
+ with gr.Row():
124
+ send_btn = gr.Button("Enviar", variant="primary")
125
+ clear_btn = gr.Button("Limpiar")
126
+
127
+ send_btn.click(chat, [msg_box, chatbot, system_box], [chatbot, msg_box])
128
+ msg_box.submit(chat, [msg_box, chatbot, system_box], [chatbot, msg_box])
129
+ clear_btn.click(lambda: ([], ""), outputs=[chatbot, msg_box])
130
+
131
+ # ── Montar Gradio en FastAPI ──────────────────────────────────────────────────
132
+ app = gr.mount_gradio_app(fapp, demo, path="/")
133
+
134
+ if __name__ == "__main__":
135
+ import uvicorn
136
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio==5.29.0
2
+ transformers>=4.45.0
3
+ torch>=2.1.0
4
+ accelerate>=0.26.0
5
+ fastapi
6
+ uvicorn
7
+ spaces