JMAA00 commited on
Commit
cc4027d
·
1 Parent(s): 9dfbce3

DeepseekV1

Browse files
Files changed (1) hide show
  1. app.py +68 -143
app.py CHANGED
@@ -1,138 +1,87 @@
1
  import os
 
2
  import gradio as gr
3
- import requests
4
- from huggingface_hub import InferenceClient
5
-
6
- """
7
- For more information on `huggingface_hub` Inference API support,
8
- please check the docs:
9
- https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
10
- """
11
-
12
- # ----------------------------------------------------------------
13
- # CONFIGURACIÓN DE SERPER (búsqueda web)
14
- # ----------------------------------------------------------------
15
- SERPER_API_KEY = os.getenv("SERPER_API_KEY")
16
-
17
- def do_websearch(query: str) -> str:
18
- """
19
- Llama a serper.dev para hacer la búsqueda en Google y devolver
20
- un texto resumido de los resultados.
21
- """
22
- if not SERPER_API_KEY:
23
- return "(SERPER_API_KEY no está configurado)"
24
-
25
- url = "https://google.serper.dev/search"
26
- headers = {
27
- "X-API-KEY": SERPER_API_KEY,
28
- "Content-Type": "application/json",
29
- }
30
- payload = {"q": query}
31
-
32
- try:
33
- resp = requests.post(url, json=payload, headers=headers, timeout=10)
34
- data = resp.json()
35
- except Exception as e:
36
- return f"(Error al llamar a serper.dev: {e})"
37
-
38
- # Se espera un campo 'organic' con resultados
39
- if "organic" not in data:
40
- return "No se encontraron resultados en serper.dev."
41
-
42
- results = data["organic"]
43
- if not results:
44
- return "No hay resultados relevantes."
45
-
46
- text = []
47
- for i, item in enumerate(results, start=1):
48
- title = item.get("title", "Sin título")
49
- link = item.get("link", "Sin enlace")
50
- text.append(f"{i}. {title}\n {link}")
51
-
52
- return "\n".join(text)
53
 
 
 
 
54
 
55
- # ----------------------------------------------------------------
56
- # CONFIGURACIÓN DEL MODELO
57
- # ----------------------------------------------------------------
58
- client = InferenceClient("meta-llama/Llama-3.1-8B-Instruct")
 
 
 
59
 
60
  def respond(
61
  message,
62
  history: list[tuple[str, str]],
63
- system_message,
64
- max_tokens,
65
- temperature,
66
- top_p,
67
- use_search # <-- Nuevo parámetro: si está "activado" el botón
68
  ):
69
  """
70
  - system_message: Texto del rol "system"
71
- - history: lista de (user_msg, assistant_msg)
72
  - message: Mensaje actual del usuario
73
- - use_search: booleano que indica si se habilita la búsqueda en serper
74
  """
75
 
76
- # ----------------------------------------------------------------
77
- # 1) Si el toggle está activo, hacemos búsqueda y la agregamos al prompt
78
- # ----------------------------------------------------------------
79
- if use_search:
80
- web_info = do_websearch(message)
81
- # Agregamos info al final del texto del usuario
82
- message = f"{message}\nInformación de la web:\n{web_info}"
83
-
84
- # ----------------------------------------------------------------
85
- # 2) Construimos la lista de mensajes para la API de chat
86
- # ----------------------------------------------------------------
87
- messages = [{"role": "system", "content": system_message}]
88
- for val in history:
89
- if val[0]:
90
- messages.append({"role": "user", "content": val[0]})
91
- if val[1]:
92
- messages.append({"role": "assistant", "content": val[1]})
93
-
94
- # Añadimos el mensaje nuevo del usuario (posiblemente complementado con la info web)
95
- messages.append({"role": "user", "content": message})
96
-
97
- # ----------------------------------------------------------------
98
- # 3) Llamamos a la API con streaming de tokens
99
- # ----------------------------------------------------------------
100
- response = ""
101
- for chunk in client.chat_completion(
102
- messages,
103
- max_tokens=max_tokens,
104
- stream=True,
105
  temperature=temperature,
106
  top_p=top_p,
107
- ):
108
- token = chunk.choices[0].delta.get("content", "")
109
- response += token
110
- yield response
111
-
112
-
113
- # ----------------------------------------------------------------
114
- # CONFIGURACIÓN DE LA INTERFAZ
115
- # ----------------------------------------------------------------
116
- # Para usar Tailwind, podemos asignar clases en "elem_classes".
117
- # Ejemplo de clases genéricas (puedes cambiarlas a tu gusto):
118
- tailwind_toggle_classes = [
119
- "inline-flex",
120
- "items-center",
121
- "bg-blue-500",
122
- "hover:bg-blue-700",
123
- "text-white",
124
- "font-bold",
125
- "py-1",
126
- "px-2",
127
- "rounded",
128
- "cursor-pointer"
129
- ]
130
-
131
- # ChatInterface, con un input Checkbox para "🌐 Búsqueda"
132
  demo = gr.ChatInterface(
133
  fn=respond,
134
  additional_inputs=[
135
  gr.Textbox(
 
136
  value=(
137
  "Eres Juan, un asistente virtual en español. "
138
  "Debes responder con mucha paciencia y empatía a usuarios que "
@@ -140,37 +89,13 @@ demo = gr.ChatInterface(
140
  "Provee explicaciones simples, procura entender la intención del usuario "
141
  "aunque la frase esté mal escrita, y mantén siempre un tono amable."
142
  ),
143
- label="Mensaje del sistema",
144
- ),
145
- gr.Slider(
146
- minimum=1,
147
- maximum=2048,
148
- value=512,
149
- step=1,
150
- label="Máxima cantidad de tokens"
151
- ),
152
- gr.Slider(
153
- minimum=0.1,
154
- maximum=4.0,
155
- value=0.7,
156
- step=0.1,
157
- label="Temperatura"
158
- ),
159
- gr.Slider(
160
- minimum=0.1,
161
- maximum=1.0,
162
- value=0.95,
163
- step=0.05,
164
- label="Top-p (muestreo por núcleo)",
165
- ),
166
- # Un checkbox que hace de "toggle" para la búsqueda
167
- gr.Checkbox(
168
- value=False, # Por defecto desactivado
169
- label="🌐 Búsqueda", # Etiqueta
170
- elem_classes=tailwind_toggle_classes
171
  ),
 
 
 
172
  ],
173
  )
174
 
175
  if __name__ == "__main__":
 
176
  demo.launch()
 
1
  import os
2
+ import torch
3
  import gradio as gr
4
+ from transformers import (
5
+ AutoTokenizer,
6
+ AutoModelForCausalLM,
7
+ TextIteratorStreamer,
8
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ # 1) Cargamos el tokenizer y el modelo de deepseek-ai/DeepSeek-R1-Distill-Llama-8B
11
+ print("Cargando tokenizer...")
12
+ tokenizer = AutoTokenizer.from_pretrained("deepseek-ai/DeepSeek-R1-Distill-Llama-8B")
13
 
14
+ print("Cargando modelo (puede tardar varios minutos)...")
15
+ model = AutoModelForCausalLM.from_pretrained(
16
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-8B",
17
+ device_map="auto", # Para usar GPU si está disponible
18
+ torch_dtype=torch.float16 # Usa float16 en GPU; en CPU, cambia a float32
19
+ )
20
+ model.eval()
21
 
22
  def respond(
23
  message,
24
  history: list[tuple[str, str]],
25
+ system_message: str,
26
+ max_tokens: int,
27
+ temperature: float,
28
+ top_p: float,
 
29
  ):
30
  """
31
  - system_message: Texto del rol "system"
32
+ - history: Historial [(user_message, assistant_reply), ...]
33
  - message: Mensaje actual del usuario
34
+ Genera una respuesta en streaming usando transformers.TextIteratorStreamer
35
  """
36
 
37
+ # Construimos un prompt concatenando 'system_message', 'history' y el nuevo 'message'
38
+ # Esto es un ejemplo de formateo sencillo. Ajusta según tu preferencia de estilo chat.
39
+ prompt = f"[SYSTEM] {system_message}\n"
40
+ for (usr, bot) in history:
41
+ if usr:
42
+ prompt += f"[USER] {usr}\n"
43
+ if bot:
44
+ prompt += f"[ASSISTANT] {bot}\n"
45
+ prompt += f"[USER] {message}\n[ASSISTANT]"
46
+
47
+ # Usamos TextIteratorStreamer para obtener tokens a medida que se generan
48
+ streamer = TextIteratorStreamer(
49
+ tokenizer=tokenizer,
50
+ skip_special_tokens=True
51
+ )
52
+
53
+ # Preparamos argumentos para model.generate
54
+ # (similar a pipeline pero de bajo nivel)
55
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
56
+ generation_kwargs = dict(
57
+ **inputs,
58
+ streamer=streamer,
59
+ max_new_tokens=max_tokens,
 
 
 
 
 
 
60
  temperature=temperature,
61
  top_p=top_p,
62
+ do_sample=True, # para permitir sampling
63
+ # repetition_penalty=1.0, # ajusta si lo deseas
64
+ )
65
+
66
+ # Lanzamos la generación en un hilo
67
+ generation_thread = torch.Thread(
68
+ target=model.generate,
69
+ kwargs=generation_kwargs
70
+ )
71
+ generation_thread.start()
72
+
73
+ # Leemos tokens a medida que se generan y yield
74
+ output_text = ""
75
+ for new_token in streamer:
76
+ output_text += new_token
77
+ yield output_text
78
+
79
+ # Interfaz con ChatInterface
 
 
 
 
 
 
 
80
  demo = gr.ChatInterface(
81
  fn=respond,
82
  additional_inputs=[
83
  gr.Textbox(
84
+ label="Mensaje del sistema",
85
  value=(
86
  "Eres Juan, un asistente virtual en español. "
87
  "Debes responder con mucha paciencia y empatía a usuarios que "
 
89
  "Provee explicaciones simples, procura entender la intención del usuario "
90
  "aunque la frase esté mal escrita, y mantén siempre un tono amable."
91
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  ),
93
+ gr.Slider(1, 2048, 512, 1, label="Máxima cantidad de tokens"),
94
+ gr.Slider(0.1, 4.0, 0.7, 0.1, label="Temperatura"),
95
+ gr.Slider(0.1, 1.0, 0.95, 0.05, label="Top-p (muestreo por núcleo)"),
96
  ],
97
  )
98
 
99
  if __name__ == "__main__":
100
+ print("Iniciando servidor Gradio...")
101
  demo.launch()