File size: 3,601 Bytes
7e493b0 324a12a f3200bb 7e493b0 f3200bb 7e493b0 324a12a 7e493b0 324a12a 7e493b0 e39c34b 324a12a e39c34b 7e493b0 | 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 | import os
import sys
# === Compatibilidade Hugging Face Hub (HfFolder foi depreciado nas versoes novas do huggingface_hub) ===
try:
import huggingface_hub
if not hasattr(huggingface_hub, "HfFolder"):
class _HfFolderShim:
@staticmethod
def get_token():
import os
try:
from huggingface_hub import get_token
return get_token()
except Exception:
return os.getenv("HF_TOKEN") or os.getenv("HUGGING_FACE_HUB_TOKEN")
@staticmethod
def save_token(token):
pass
@staticmethod
def delete_token():
pass
huggingface_hub.HfFolder = _HfFolderShim
except Exception as _shim_err:
print(f"[boot] HfFolder shim error (non-fatal): {_shim_err}", flush=True)
import gradio as gr
import uvicorn
try:
import spaces
print(f"[boot] spaces real: {getattr(spaces, '__file__', '?')}", flush=True)
except ImportError: # fora do ZeroGPU (dev local)
print("[boot] AVISO: pacote 'spaces' ausente, fallback local (ZeroGPU desligado)", flush=True)
class _SpacesFallback:
@staticmethod
def GPU(task=None, **kwargs):
if task is None:
return lambda fn: fn
return task
spaces = _SpacesFallback()
from ai_engine import AIEngine
from config import Config
from main import app as api_app
PORT = int(os.getenv("PORT") or os.getenv("GRADIO_SERVER_PORT") or 7860)
_engine = AIEngine()
def _demo_reply(pergunta: str) -> str:
pergunta = (pergunta or "").strip()
if not pergunta:
return "Escreve uma pergunta sobre a pastelaria Negra Plena."
return _engine.generate_reply("demo", pergunta, "Visitante")
@spaces.GPU(duration=120)
def _zerogpu_status() -> str:
return "ZeroGPU activo neste Space."
api_app.router.routes = [r for r in api_app.router.routes if getattr(r, "path", None) != "/"]
with gr.Blocks(title=f"{Config.ASSISTANT_NAME} - {Config.COMPANY_NAME}") as demo:
gr.Markdown(
f"# {Config.ASSISTANT_NAME} - cérebro da {Config.COMPANY_NAME}\n"
"API de atendimento usada pelo bot WhatsApp. \n"
"`POST /api/escutar` · `GET /health` · `GET /docs`"
)
entrada = gr.Textbox(label="Pergunta de teste", placeholder="Qual é o preço do bolo no pote?")
btn = gr.Button("Enviar", variant="primary")
saida = gr.Markdown()
btn.click(_demo_reply, inputs=entrada, outputs=saida)
entrada.submit(_demo_reply, inputs=entrada, outputs=saida)
gr.Button("Estado ZeroGPU").click(_zerogpu_status, inputs=None, outputs=saida)
# SSR desligado: o proxy Node do Gradio fica com a 7860 e o uvicorn precisa dela.
app = gr.mount_gradio_app(api_app, demo, path="/", ssr_mode=False)
# ZeroGPU: o demo TEM de ser lançado para o scan de startup detectar o @spaces.GPU.
try:
demo.launch(prevent_thread_lock=True, server_name="127.0.0.1", server_port=8000)
demo.close()
print("[boot] demo lançado e fechado para o scan ZeroGPU", flush=True)
except Exception as exc:
print(f"[boot] lançamento interno do demo falhou: {exc!r}", flush=True)
# Pré-aquecimento do Llama local: baixa os pesos UMA vez (depois usa o cache
# do disco) para a primeira resposta não pagar o download.
try:
from local_llm import _ensure_loaded as _warm_llama
_warm_llama()
except Exception as exc:
print(f"[boot] warmup Llama ignorado: {exc!r}", flush=True)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=PORT, log_level="info")
|