Chompi10 commited on
Commit
973859b
·
verified ·
1 Parent(s): 3c2f1c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +193 -191
app.py CHANGED
@@ -1,245 +1,247 @@
1
- import os
2
- import torch
3
- from flask import Flask, request, jsonify, Response
4
- from transformers import AutoTokenizer, AutoModelForCausalLM
5
 
6
- # ===============================
7
- # CONFIGURACIÓN BÁSICA
8
- # ===============================
 
 
9
 
10
- app = Flask(__name__)
11
 
12
- MODEL_NAME = "microsoft/phi-2"
13
- MAX_NEW_TOKENS = 250
 
14
 
15
- print("Cargando modelo...")
16
-
17
- torch.set_num_threads(4)
18
-
19
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
20
 
 
21
  model = AutoModelForCausalLM.from_pretrained(
22
  MODEL_NAME,
23
- torch_dtype=torch.float32,
24
- low_cpu_mem_usage=True
25
  )
26
 
27
- model.eval()
 
28
 
29
- print("Modelo cargado correctamente.")
30
 
 
 
 
31
 
32
- # ===============================
33
- # PROMPTS PROFESIONALES
34
- # ===============================
35
 
36
- GENERATOR_PROMPT = """
37
- You are a Senior Software Engineer.
38
- Always respond in the same language as the user.
39
 
40
- Generate:
41
- - Clean
42
- - Secure
43
- - Optimized
44
- - Production-ready code
45
- Explain briefly what the code does.
46
- Include best practices.
47
- Use markdown triple backticks for code blocks.
48
- """
49
 
50
- ULTRA_REVIEW_PROMPT = """
51
- You are a Principal Software Architect and Security Engineer.
52
- Always respond in the same language as the user.
53
-
54
- Perform an EXTREMELY CRITICAL and PROFESSIONAL code review.
55
-
56
- Analyze:
57
- 1. Logical correctness
58
- 2. Edge cases
59
- 3. Security vulnerabilities (OWASP mindset)
60
- 4. Input validation
61
- 5. Authentication flaws
62
- 6. Concurrency risks
63
- 7. Memory inefficiencies
64
- 8. Performance bottlenecks
65
- 9. Scalability risks
66
- 10. SOLID violations
67
- 11. Clean Architecture violations
68
- 12. Code smells
69
- 13. Dependency risks
70
- 14. Error handling weaknesses
71
- 15. Logging gaps
72
- 16. Deployment risks
73
-
74
- Return structured sections with clear headings.
75
- """
76
 
77
- ARCHITECTURE_ANALYSIS_PROMPT = """
78
- You are a Senior Software Architect.
79
- Always respond in the same language as the user.
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- Analyze the provided system from an ARCHITECTURAL perspective.
 
82
 
83
- Evaluate:
84
- - Layered architecture
85
- - Coupling and cohesion
86
- - API design
87
- - Data flow
88
- - Scalability model
89
- - Fault tolerance
90
- - Cloud readiness
91
- - Observability
92
- - Caching strategy
93
 
94
- Return structured response with headings.
 
95
  """
96
 
 
 
 
 
97
 
98
- # ===============================
99
- # FRONTEND (CHAT UI)
100
- # ===============================
 
101
 
102
  @app.route("/")
103
  def index():
104
- return Response("""
 
 
 
 
105
  <!DOCTYPE html>
106
  <html>
107
  <head>
108
  <meta charset="UTF-8">
109
- <title>AI Engineer Assistant</title>
110
- <style>
111
- body { margin:0; font-family:Arial; background:#343541; display:flex; justify-content:center; align-items:center; height:100vh; }
112
- .container { width:900px; height:92vh; background:#444654; display:flex; flex-direction:column; border-radius:10px; }
113
- .chat { flex:1; padding:20px; overflow-y:auto; display:flex; flex-direction:column; }
114
- .msg { padding:12px; border-radius:8px; margin-bottom:12px; max-width:85%; white-space:pre-wrap; }
115
- .user { background:#19c37d; align-self:flex-end; color:black; }
116
- .bot { background:#555869; align-self:flex-start; color:white; }
117
- .input-area { display:flex; border-top:1px solid #555; }
118
- input, select { padding:15px; border:none; outline:none; font-size:16px; }
119
- input { flex:1; }
120
- button { padding:15px; border:none; background:#19c37d; font-weight:bold; cursor:pointer; }
121
- button:hover { opacity:0.9; }
122
- select { background:#555869; color:white; }
123
- </style>
124
- </head>
125
- <body>
126
 
127
- <div class="container">
128
- <div id="chat" class="chat"></div>
129
- <div class="input-area">
130
- <select id="mode">
131
- <option value="generate">Generate Code</option>
132
- <option value="review">Ultra Review</option>
133
- <option value="architecture">Architecture Analysis</option>
134
- </select>
135
- <input id="input" placeholder="Write your message..." />
136
- <button onclick="send()">Send</button>
137
- </div>
138
- </div>
139
-
140
- <script>
141
- async function send(){
142
- const input = document.getElementById("input");
143
- const chat = document.getElementById("chat");
144
- const mode = document.getElementById("mode").value;
145
-
146
- const text = input.value.trim();
147
- if(!text) return;
148
-
149
- add(text,"user");
150
- input.value="";
151
 
152
- const loading = add("Thinking...","bot");
 
 
 
 
153
 
154
- try{
155
- const res = await fetch("/chat",{
156
- method:"POST",
157
- headers:{"Content-Type":"application/json"},
158
- body:JSON.stringify({message:text, mode:mode})
159
- });
 
160
 
161
- const data = await res.json();
162
- loading.remove();
163
- add(data.response || "Error","bot");
 
164
 
165
- }catch(e){
166
- loading.remove();
167
- add("Server error","bot");
168
- }
169
  }
170
 
171
- function add(text,type){
172
- const chat=document.getElementById("chat");
173
- const div=document.createElement("div");
174
- div.className="msg "+type;
175
- div.innerText=text;
176
- chat.appendChild(div);
177
- chat.scrollTop=chat.scrollHeight;
178
- return div;
179
  }
180
 
181
- document.getElementById("input").addEventListener("keypress",function(e){
182
- if(e.key==="Enter"){ send(); }
183
- });
184
- </script>
 
 
 
185
 
186
- </body>
187
- </html>
188
- """, mimetype="text/html")
 
 
 
 
 
 
 
 
 
189
 
 
190
 
191
- # ===============================
192
- # API CHAT
193
- # ===============================
194
 
195
- @app.route("/chat", methods=["POST"])
196
- def chat():
197
- try:
198
- data = request.get_json()
199
- user_input = data.get("message", "")
200
- mode = data.get("mode", "generate")
201
 
202
- if not user_input:
203
- return jsonify({"error": "Empty message"}), 400
204
 
205
- # Selección de prompt según modo
206
- if mode == "review":
207
- system_prompt = ULTRA_REVIEW_PROMPT
208
- elif mode == "architecture":
209
- system_prompt = ARCHITECTURE_ANALYSIS_PROMPT
210
- else:
211
- system_prompt = GENERATOR_PROMPT
212
 
213
- prompt = f"{system_prompt}\nUser: {user_input}\nAssistant:"
 
 
214
 
215
- inputs = tokenizer(prompt, return_tensors="pt")
216
 
217
- with torch.inference_mode():
218
- outputs = model.generate(
219
- **inputs,
220
- max_new_tokens=MAX_NEW_TOKENS,
221
- do_sample=True,
222
- temperature=0.5,
223
- top_p=0.9,
224
- repetition_penalty=1.15,
225
- no_repeat_ngram_size=3,
226
- pad_token_id=tokenizer.eos_token_id
227
- )
228
 
229
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
230
- response = response.split("Assistant:")[-1].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
- return jsonify({"response": response})
233
 
234
- except Exception as e:
235
- return jsonify({"error": str(e)}), 500
 
236
 
237
 
238
- # ===============================
239
- # START SERVER
240
- # ===============================
241
 
242
  if __name__ == "__main__":
243
- port = int(os.environ.get("PORT", 7860))
244
- app.run(host="0.0.0.0", port=port)
245
-
 
1
+ # ==============================
2
+ # IMPORTS
3
+ # ==============================
 
4
 
5
+ from flask import Flask, request, Response # Servidor web y streaming
6
+ from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer # Modelo IA
7
+ import torch # Motor de ejecución del modelo
8
+ import threading # Para ejecutar el modelo en segundo plano
9
+ import json # Para manejar datos JSON
10
 
 
11
 
12
+ # ==============================
13
+ # CONFIGURACIÓN DEL MODELO
14
+ # ==============================
15
 
16
+ MODEL_NAME = "microsoft/phi-2" # Modelo que vamos a usar
 
 
 
 
17
 
18
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) # Descarga el tokenizador
19
  model = AutoModelForCausalLM.from_pretrained(
20
  MODEL_NAME,
21
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32 # Usa GPU si existe
 
22
  )
23
 
24
+ device = "cuda" if torch.cuda.is_available() else "cpu" # Detecta GPU
25
+ model.to(device) # Mueve el modelo al dispositivo
26
 
 
27
 
28
+ # ==============================
29
+ # CREAR SERVIDOR FLASK
30
+ # ==============================
31
 
32
+ app = Flask(__name__) # Inicializa el servidor
 
 
33
 
 
 
 
34
 
35
+ # ==============================
36
+ # FUNCION STREAMING IA
37
+ # ==============================
 
 
 
 
 
 
38
 
39
+ def generate_stream(prompt):
40
+ """
41
+ Genera texto en streaming token por token
42
+ """
43
+
44
+ inputs = tokenizer(prompt, return_tensors="pt").to(device) # Convierte texto en tensores
45
+
46
+ streamer = TextIteratorStreamer(
47
+ tokenizer,
48
+ skip_prompt=True, # No repite el prompt
49
+ skip_special_tokens=True # Quita tokens especiales
50
+ )
51
+
52
+ # Ejecuta el modelo en segundo plano
53
+ thread = threading.Thread(
54
+ target=model.generate,
55
+ kwargs={
56
+ "inputs": inputs["input_ids"], # Texto convertido
57
+ "attention_mask": inputs["attention_mask"],
58
+ "max_new_tokens": 300, # Máximo de tokens a generar
59
+ "temperature": 0.7, # Creatividad
60
+ "top_p": 0.9, # Diversidad
61
+ "do_sample": True, # Activa aleatoriedad
62
+ "streamer": streamer # Activa streaming
63
+ }
64
+ )
65
 
66
+ thread.start() # Inicia generación
67
+
68
+ # Devuelve token por token en tiempo real
69
+ for new_text in streamer:
70
+ yield new_text
71
+
72
+
73
+ # ==============================
74
+ # API CHAT (POST /chat)
75
+ # ==============================
76
+
77
+ @app.route("/chat", methods=["POST"])
78
+ def chat():
79
+ """
80
+ Endpoint que recibe mensaje y responde en streaming
81
+ """
82
 
83
+ data = request.json # Lee JSON enviado
84
+ user_message = data.get("message", "") # Extrae mensaje
85
 
86
+ # Prompt multi-lenguaje
87
+ prompt = f"""
88
+ You are a professional AI assistant.
89
+ Detect the language of the user automatically and answer in the same language.
90
+ Be clear and structured.
 
 
 
 
 
91
 
92
+ User: {user_message}
93
+ Assistant:
94
  """
95
 
96
+ return Response(
97
+ generate_stream(prompt),
98
+ mimetype="text/plain" # Streaming tipo texto
99
+ )
100
 
101
+
102
+ # ==============================
103
+ # FRONTEND CHAT ESTILO CHATGPT
104
+ # ==============================
105
 
106
  @app.route("/")
107
  def index():
108
+ """
109
+ Devuelve HTML completo del chat
110
+ """
111
+
112
+ return """
113
  <!DOCTYPE html>
114
  <html>
115
  <head>
116
  <meta charset="UTF-8">
117
+ <title>AI Chat</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
+ <style>
120
+ body {
121
+ margin:0;
122
+ font-family: Arial;
123
+ background-color:#343541;
124
+ color:white;
125
+ display:flex;
126
+ flex-direction:column;
127
+ height:100vh;
128
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ #chat {
131
+ flex:1;
132
+ padding:20px;
133
+ overflow-y:auto;
134
+ }
135
 
136
+ .message {
137
+ margin-bottom:15px;
138
+ padding:10px 15px;
139
+ border-radius:10px;
140
+ max-width:70%;
141
+ white-space:pre-wrap;
142
+ }
143
 
144
+ .user {
145
+ background:#0b93f6;
146
+ align-self:flex-end;
147
+ }
148
 
149
+ .bot {
150
+ background:#444654;
151
+ align-self:flex-start;
 
152
  }
153
 
154
+ #input-area {
155
+ display:flex;
156
+ padding:15px;
157
+ background:#202123;
 
 
 
 
158
  }
159
 
160
+ input {
161
+ flex:1;
162
+ padding:10px;
163
+ border-radius:5px;
164
+ border:none;
165
+ font-size:16px;
166
+ }
167
 
168
+ button {
169
+ margin-left:10px;
170
+ padding:10px 20px;
171
+ border:none;
172
+ border-radius:5px;
173
+ background:#19c37d;
174
+ color:white;
175
+ font-weight:bold;
176
+ cursor:pointer;
177
+ }
178
+ </style>
179
+ </head>
180
 
181
+ <body>
182
 
183
+ <div id="chat"></div>
 
 
184
 
185
+ <div id="input-area">
186
+ <input id="message" placeholder="Escribe tu mensaje..." />
187
+ <button onclick="send()">Enviar</button>
188
+ </div>
 
 
189
 
190
+ <script>
 
191
 
192
+ async function send() {
 
 
 
 
 
 
193
 
194
+ const input = document.getElementById("message");
195
+ const text = input.value;
196
+ if (!text) return;
197
 
198
+ input.value = "";
199
 
200
+ const chat = document.getElementById("chat");
 
 
 
 
 
 
 
 
 
 
201
 
202
+ // Mostrar mensaje usuario
203
+ const userDiv = document.createElement("div");
204
+ userDiv.className = "message user";
205
+ userDiv.textContent = text;
206
+ chat.appendChild(userDiv);
207
+
208
+ // Crear mensaje bot vacío
209
+ const botDiv = document.createElement("div");
210
+ botDiv.className = "message bot";
211
+ botDiv.textContent = "";
212
+ chat.appendChild(botDiv);
213
+
214
+ chat.scrollTop = chat.scrollHeight;
215
+
216
+ // Enviar al backend
217
+ const response = await fetch("/chat", {
218
+ method:"POST",
219
+ headers:{"Content-Type":"application/json"},
220
+ body: JSON.stringify({message:text})
221
+ });
222
+
223
+ const reader = response.body.getReader();
224
+ const decoder = new TextDecoder();
225
+
226
+ // Streaming en tiempo real
227
+ while (true) {
228
+ const {done, value} = await reader.read();
229
+ if (done) break;
230
+ botDiv.textContent += decoder.decode(value);
231
+ chat.scrollTop = chat.scrollHeight;
232
+ }
233
+ }
234
 
235
+ </script>
236
 
237
+ </body>
238
+ </html>
239
+ """
240
 
241
 
242
+ # ==============================
243
+ # INICIAR SERVIDOR
244
+ # ==============================
245
 
246
  if __name__ == "__main__":
247
+ app.run(host="0.0.0.0", port=5000, threaded=True)