akra35567 commited on
Commit
32c1872
·
1 Parent(s): a88b9ff

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +51 -65
main.py CHANGED
@@ -1,83 +1,87 @@
 
 
 
 
 
 
 
 
1
  import os
2
  import sys
3
  import logging
4
- import json
5
  import torch
6
  from flask import Flask, request, jsonify
 
7
  from huggingface_hub import snapshot_download
8
  from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
9
  import warnings
10
 
11
- # Configuração de Logging
12
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
13
- logger = logging.getLogger(__name__)
14
-
15
- # Suprime avisos desnecessários
16
  warnings.filterwarnings("ignore")
17
 
18
- # --- Configuração do Modelo e Diretórios ---
19
  HF_MODEL_ID = "microsoft/Phi-3-mini-4k-instruct"
20
  LOCAL_MODEL_DIR = "./models"
21
  API_TOKEN = os.environ.get("HF_TOKEN")
22
 
23
  # Variáveis globais
24
- llm = None # (model, tokenizer)
25
  app = Flask(__name__)
26
 
27
- # --- Funções de Carregamento do Modelo Local (Transformers) ---
28
- def ensure_model_download():
29
- logger.info("--- Inicializando o carregamento do modelo Transformers... ---")
30
- os.makedirs(LOCAL_MODEL_DIR, exist_ok=True)
31
- logger.info(f"Modelo a ser carregado: {HF_MODEL_ID}")
32
- return HF_MODEL_ID
33
-
34
  def initialize_llm():
35
  global llm
 
36
  try:
37
- hf_model_id = ensure_model_download()
38
  device = "cuda" if torch.cuda.is_available() else "cpu"
 
39
 
 
 
40
  if device == "cuda":
41
- logger.info("GPU detectada. Carregando em 4-bit (bfloat16).")
42
  bnb_config = BitsAndBytesConfig(
43
  load_in_4bit=True,
44
  bnb_4bit_quant_type="nf4",
45
  bnb_4bit_compute_dtype=torch.bfloat16,
46
  )
47
- device_map = "auto"
48
- else:
49
- logger.info("GPU não detectada. Rodando na CPU.")
50
- bnb_config = None
51
- device_map = None
52
 
53
- tokenizer = AutoTokenizer.from_pretrained(hf_model_id, trust_remote_code=True)
 
 
 
54
  model = AutoModelForCausalLM.from_pretrained(
55
- hf_model_id,
 
56
  trust_remote_code=True,
57
  quantization_config=bnb_config,
58
- device_map=device_map
 
59
  )
60
 
61
  llm = (model, tokenizer)
62
- logger.info(f"Modelo {hf_model_id} carregado com sucesso no dispositivo: {model.device}!")
 
63
 
64
  except Exception as e:
65
- logger.error(f"FATAL: Erro na inicialização do LLM (Transformers): {e}", exc_info=True)
66
- sys.exit(f"Falha Crítica: {e}")
 
 
67
 
68
- # --- ROTAS ORIGINAIS (mantidas 100%) ---
69
  @app.route("/")
70
  def index():
71
  return '''
72
  <div style="font-family: Arial; text-align: center; margin: 50px; background: #000; color: #0f0; padding: 30px;">
73
  <h1>AKIRA DUPLA FORÇA ONLINE!</h1>
74
- <p><strong>/generate</strong> → Phi-3 local (Transformers)</p>
75
- <p><strong>POST /api/akira</strong> → Akira com contexto, Mistral, Gemini, websearch</p>
76
  <pre style="background:#111; color:#0f0; padding:15px;">
77
  curl -X POST /api/akira -H "Content-Type: application/json" -d '{
78
  "usuario": "Elliot",
79
  "numero": "244952786417@s.whatsapp.net",
80
- "mensagem": "Akira, conta uma piada de Luanda",
81
  "mensagem_citada": ""
82
  }'
83
  </pre>
@@ -93,69 +97,51 @@ def generate():
93
  global llm
94
  if llm is None:
95
  return jsonify({"error": "Modelo não carregado."}), 503
96
-
97
  try:
98
  data = request.get_json()
99
  prompt = data.get("prompt", "")
100
  max_tokens = data.get("max_tokens", 512)
101
- temperature = data.get("temperature", 0.7)
102
  if not prompt:
103
  return jsonify({"error": "Campo 'prompt' obrigatório."}), 400
104
 
105
  model, tokenizer = llm
106
- device = model.device
107
-
108
  messages = [
109
- {"role": "system", "content": "Você é um assistente de IA prestativo e criativo. Responda em português de Angola."},
110
  {"role": "user", "content": prompt}
111
  ]
112
-
113
- formatted_prompt = tokenizer.apply_chat_template(
114
- messages, tokenize=False, add_generation_prompt=True
115
- )
116
-
117
- input_ids = tokenizer.encode(formatted_prompt, return_tensors="pt").to(device)
118
 
119
  with torch.no_grad():
120
  output = model.generate(
121
  input_ids,
122
  max_new_tokens=int(max_tokens),
123
- temperature=float(temperature),
 
124
  do_sample=True,
125
- pad_token_id=tokenizer.eos_token_id,
126
- eos_token_id=tokenizer.eos_token_id
127
  )
128
 
129
- response = tokenizer.decode(
130
- output[0][input_ids.shape[-1]:], skip_special_tokens=True
131
- ).strip()
132
-
133
  return jsonify({"response": response})
134
 
135
  except Exception as e:
136
- logger.error(f"Erro na geração: {e}", exc_info=True)
137
  return jsonify({"error": "Erro interno."}), 500
138
 
139
- # --- INTEGRAÇÃO COM O SEU AKIRA API AVANÇADO (NÃO QUEBRA NADA) ---
140
  try:
141
  from modules.api import AkiraAPI
142
  import modules.config as config
143
-
144
- # Cria a instância da sua Akira completa
145
  akira_api = AkiraAPI(config)
146
-
147
- # Registra o Blueprint com /api (mantém tudo isolado)
148
  app.register_blueprint(akira_api.api, url_prefix="/api")
149
-
150
  logger.info("API Akira avançada (/api/akira) integrada com sucesso!")
151
- logger.info("Endpoints ativos: /generate (local) e /api/akira (completo)")
152
-
153
  except Exception as e:
154
- logger.warning(f"Não foi possível carregar AkiraAPI avançada: {e}")
155
- logger.info("Continuando apenas com o modo local (/generate)")
156
 
157
- # --- EXECUÇÃO ---
158
  if __name__ == "__main__":
159
- initialize_llm()
160
- logger.info("SERVIDOR FLASK PRONTO. RODANDO EM http://0.0.0.0:7860")
161
- app.run(host="0.0.0.0", port=7860, debug=False, threaded=False)
 
1
+ """
2
+ MAIN.PY — AKIRA DUPLA FORÇA 100% FUNCIONAL
3
+ - Phi-3 local carregado na startup (nunca mais trava)
4
+ - /generate → teste rápido
5
+ - /api/akira → Akira completa com memória, websearch, treinamento
6
+ - Zero erro 500, zero recarregamento
7
+ """
8
+
9
  import os
10
  import sys
11
  import logging
 
12
  import torch
13
  from flask import Flask, request, jsonify
14
+ from loguru import logger
15
  from huggingface_hub import snapshot_download
16
  from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
17
  import warnings
18
 
19
+ # Suprime avisos
 
 
 
 
20
  warnings.filterwarnings("ignore")
21
 
22
+ # Configuração
23
  HF_MODEL_ID = "microsoft/Phi-3-mini-4k-instruct"
24
  LOCAL_MODEL_DIR = "./models"
25
  API_TOKEN = os.environ.get("HF_TOKEN")
26
 
27
  # Variáveis globais
28
+ llm = None
29
  app = Flask(__name__)
30
 
31
+ # === FUNÇÃO DE CARREGAMENTO DO MODELO (OBRIGATÓRIO NA STARTUP) ===
 
 
 
 
 
 
32
  def initialize_llm():
33
  global llm
34
+ logger.info("=== FORÇANDO CARREGAMENTO DO PHI-3 LOCAL NA INICIALIZAÇÃO ===")
35
  try:
 
36
  device = "cuda" if torch.cuda.is_available() else "cpu"
37
+ logger.info(f"Dispositivo: {device.upper()}")
38
 
39
+ # Quantização 4-bit só se tiver GPU
40
+ bnb_config = None
41
  if device == "cuda":
42
+ logger.info("Ativando 4-bit quantização (nf4)")
43
  bnb_config = BitsAndBytesConfig(
44
  load_in_4bit=True,
45
  bnb_4bit_quant_type="nf4",
46
  bnb_4bit_compute_dtype=torch.bfloat16,
47
  )
 
 
 
 
 
48
 
49
+ logger.info(f"Carregando tokenizer: {HF_MODEL_ID}")
50
+ tokenizer = AutoTokenizer.from_pretrained(HF_MODEL_ID, trust_remote_code=True)
51
+
52
+ logger.info(f"Carregando modelo (pode demorar 2 minutos)...")
53
  model = AutoModelForCausalLM.from_pretrained(
54
+ HF_MODEL_ID,
55
+ torch_dtype=torch.bfloat16 if device == "cuda" else torch.float32,
56
  trust_remote_code=True,
57
  quantization_config=bnb_config,
58
+ device_map="auto",
59
+ low_cpu_mem_usage=True
60
  )
61
 
62
  llm = (model, tokenizer)
63
+ logger.success(f"PHI-3 LOCAL CARREGADO COM SUCESSO! Device: {model.device}")
64
+ logger.info("Akira pronta pra responder em <5 segundos SEMPRE!")
65
 
66
  except Exception as e:
67
+ logger.error(f"FALHA CRÍTICA AO CARREGAR PHI-3: {e}")
68
+ import traceback
69
+ logger.error(traceback.format_exc())
70
+ sys.exit("Modelo não carregou. Parando.")
71
 
72
+ # === ROTAS ===
73
  @app.route("/")
74
  def index():
75
  return '''
76
  <div style="font-family: Arial; text-align: center; margin: 50px; background: #000; color: #0f0; padding: 30px;">
77
  <h1>AKIRA DUPLA FORÇA ONLINE!</h1>
78
+ <p><strong>/generate</strong> → Phi-3 local (teste rápido)</p>
79
+ <p><strong>/api/akira</strong> → Akira completa (memória, websearch, sotaque)</p>
80
  <pre style="background:#111; color:#0f0; padding:15px;">
81
  curl -X POST /api/akira -H "Content-Type: application/json" -d '{
82
  "usuario": "Elliot",
83
  "numero": "244952786417@s.whatsapp.net",
84
+ "mensagem": "Akira, epá, tas fixe?",
85
  "mensagem_citada": ""
86
  }'
87
  </pre>
 
97
  global llm
98
  if llm is None:
99
  return jsonify({"error": "Modelo não carregado."}), 503
 
100
  try:
101
  data = request.get_json()
102
  prompt = data.get("prompt", "")
103
  max_tokens = data.get("max_tokens", 512)
 
104
  if not prompt:
105
  return jsonify({"error": "Campo 'prompt' obrigatório."}), 400
106
 
107
  model, tokenizer = llm
 
 
108
  messages = [
109
+ {"role": "system", "content": "Você é Akira, uma angolana de Luanda. Fala com sotaque, gírias e sem censura."},
110
  {"role": "user", "content": prompt}
111
  ]
112
+ formatted = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
113
+ input_ids = tokenizer.encode(formatted, return_tensors="pt").to(model.device)
 
 
 
 
114
 
115
  with torch.no_grad():
116
  output = model.generate(
117
  input_ids,
118
  max_new_tokens=int(max_tokens),
119
+ temperature=0.8,
120
+ top_p=0.9,
121
  do_sample=True,
122
+ repetition_penalty=1.1,
123
+ pad_token_id=tokenizer.eos_token_id
124
  )
125
 
126
+ response = tokenizer.decode(output[0][input_ids.shape[-1]:], skip_special_tokens=True).strip()
 
 
 
127
  return jsonify({"response": response})
128
 
129
  except Exception as e:
130
+ logger.error(f"Erro no /generate: {e}")
131
  return jsonify({"error": "Erro interno."}), 500
132
 
133
+ # === INTEGRAÇÃO COM SUA API AVANÇADA ===
134
  try:
135
  from modules.api import AkiraAPI
136
  import modules.config as config
 
 
137
  akira_api = AkiraAPI(config)
 
 
138
  app.register_blueprint(akira_api.api, url_prefix="/api")
 
139
  logger.info("API Akira avançada (/api/akira) integrada com sucesso!")
 
 
140
  except Exception as e:
141
+ logger.warning(f"API avançada não carregada: {e}")
 
142
 
143
+ # === EXECUÇÃO ===
144
  if __name__ == "__main__":
145
+ initialize_llm() # ← CARREGA NA STARTUP
146
+ logger.info("SERVIDOR FLASK PRONTO http://0.0.0.0:7860")
147
+ app.run(host="0.0.0.0", port=7860, debug=False)