Spaces:
Running
Running
File size: 5,138 Bytes
32c1872 e43cade f466164 179baf7 32c1872 3e80258 179baf7 f466164 32c1872 f466164 32c1872 6921978 f466164 3e80258 32c1872 f466164 32c1872 f466164 3e80258 32c1872 352982b 179baf7 32c1872 3e80258 32c1872 179baf7 32c1872 179baf7 32c1872 179baf7 32c1872 179baf7 32c1872 f466164 3e80258 179baf7 32c1872 3e80258 352982b 32c1872 0e1f698 32c1872 f466164 0e1f698 3e80258 32c1872 3e80258 32c1872 3e80258 0e1f698 f466164 179baf7 3e80258 f466164 3e80258 179baf7 32c1872 179baf7 32c1872 179baf7 32c1872 3e80258 32c1872 179baf7 3e80258 32c1872 3e80258 f466164 32c1872 3e80258 32c1872 3e80258 32c1872 f466164 32c1872 0e1f698 32c1872 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
"""
MAIN.PY — AKIRA DUPLA FORÇA 100% FUNCIONAL
- Phi-3 local carregado na startup (nunca mais trava)
- /generate → teste rápido
- /api/akira → Akira completa com memória, websearch, treinamento
- Zero erro 500, zero recarregamento
"""
import os
import sys
import logging
import torch
from flask import Flask, request, jsonify
from loguru import logger
from huggingface_hub import snapshot_download
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import warnings
# Suprime avisos
warnings.filterwarnings("ignore")
# Configuração
HF_MODEL_ID = "microsoft/Phi-3-mini-4k-instruct"
LOCAL_MODEL_DIR = "./models"
API_TOKEN = os.environ.get("HF_TOKEN")
# Variáveis globais
llm = None
app = Flask(__name__)
# === FUNÇÃO DE CARREGAMENTO DO MODELO (OBRIGATÓRIO NA STARTUP) ===
def initialize_llm():
global llm
logger.info("=== FORÇANDO CARREGAMENTO DO PHI-3 LOCAL NA INICIALIZAÇÃO ===")
try:
device = "cuda" if torch.cuda.is_available() else "cpu"
logger.info(f"Dispositivo: {device.upper()}")
# Quantização 4-bit só se tiver GPU
bnb_config = None
if device == "cuda":
logger.info("Ativando 4-bit quantização (nf4)")
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
)
logger.info(f"Carregando tokenizer: {HF_MODEL_ID}")
tokenizer = AutoTokenizer.from_pretrained(HF_MODEL_ID, trust_remote_code=True)
logger.info(f"Carregando modelo (pode demorar 2 minutos)...")
model = AutoModelForCausalLM.from_pretrained(
HF_MODEL_ID,
torch_dtype=torch.bfloat16 if device == "cuda" else torch.float32,
trust_remote_code=True,
quantization_config=bnb_config,
device_map="auto",
low_cpu_mem_usage=True
)
llm = (model, tokenizer)
logger.success(f"PHI-3 LOCAL CARREGADO COM SUCESSO! Device: {model.device}")
logger.info("Akira pronta pra responder em <5 segundos SEMPRE!")
except Exception as e:
logger.error(f"FALHA CRÍTICA AO CARREGAR PHI-3: {e}")
import traceback
logger.error(traceback.format_exc())
sys.exit("Modelo não carregou. Parando.")
# === ROTAS ===
@app.route("/")
def index():
return '''
<div style="font-family: Arial; text-align: center; margin: 50px; background: #000; color: #0f0; padding: 30px;">
<h1>AKIRA DUPLA FORÇA ONLINE!</h1>
<p><strong>/generate</strong> → Phi-3 local (teste rápido)</p>
<p><strong>/api/akira</strong> → Akira completa (memória, websearch, sotaque)</p>
<pre style="background:#111; color:#0f0; padding:15px;">
curl -X POST /api/akira -H "Content-Type: application/json" -d '{
"usuario": "Elliot",
"numero": "244952786417@s.whatsapp.net",
"mensagem": "Akira, epá, tas fixe?",
"mensagem_citada": ""
}'
</pre>
</div>
''', 200
@app.route("/health")
def health():
return "OK", 200
@app.route("/generate", methods=["POST"])
def generate():
global llm
if llm is None:
return jsonify({"error": "Modelo não carregado."}), 503
try:
data = request.get_json()
prompt = data.get("prompt", "")
max_tokens = data.get("max_tokens", 512)
if not prompt:
return jsonify({"error": "Campo 'prompt' obrigatório."}), 400
model, tokenizer = llm
messages = [
{"role": "system", "content": "Você é Akira, uma angolana de Luanda. Fala com sotaque, gírias e sem censura."},
{"role": "user", "content": prompt}
]
formatted = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
input_ids = tokenizer.encode(formatted, return_tensors="pt").to(model.device)
with torch.no_grad():
output = model.generate(
input_ids,
max_new_tokens=int(max_tokens),
temperature=0.8,
top_p=0.9,
do_sample=True,
repetition_penalty=1.1,
pad_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(output[0][input_ids.shape[-1]:], skip_special_tokens=True).strip()
return jsonify({"response": response})
except Exception as e:
logger.error(f"Erro no /generate: {e}")
return jsonify({"error": "Erro interno."}), 500
# === INTEGRAÇÃO COM SUA API AVANÇADA ===
try:
from modules.api import AkiraAPI
import modules.config as config
akira_api = AkiraAPI(config)
app.register_blueprint(akira_api.api, url_prefix="/api")
logger.info("API Akira avançada (/api/akira) integrada com sucesso!")
except Exception as e:
logger.warning(f"API avançada não carregada: {e}")
# === EXECUÇÃO ===
if __name__ == "__main__":
initialize_llm() # ← CARREGA NA STARTUP
logger.info("SERVIDOR FLASK PRONTO → http://0.0.0.0:7860")
app.run(host="0.0.0.0", port=7860, debug=False) |