Spaces:
Sleeping
Sleeping
File size: 4,551 Bytes
8d1f456 d249d53 8d1f456 3c84581 8d1f456 3c84581 8d1f456 3c84581 8d1f456 d249d53 3c84581 d249d53 3c84581 d249d53 3c84581 d249d53 3c84581 d249d53 3c84581 8d1f456 3c84581 8d1f456 d249d53 8d1f456 d249d53 8d1f456 3c84581 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 3c84581 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 8d1f456 d249d53 |
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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
"""
Nexus-Core Inference API - Path Fixed
Model: /app/models/nexus-core.onnx
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
import time
import logging
import os
from typing import Optional
from engine import NexusCoreEngine
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
app = FastAPI(
title="Nexus-Core Inference API",
description="Fast chess engine (13M params)",
version="2.0.0"
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
engine = None
class MoveRequest(BaseModel):
fen: str
depth: Optional[int] = Field(4, ge=1, le=6)
time_limit: Optional[int] = Field(3000, ge=1000, le=10000)
class MoveResponse(BaseModel):
best_move: str
evaluation: float
depth_searched: int
nodes_evaluated: int
time_taken: int
class HealthResponse(BaseModel):
status: str
model_loaded: bool
version: str
model_path: Optional[str] = None
@app.on_event("startup")
async def startup_event():
global engine
logger.info("🚀 Starting Nexus-Core API...")
# FIXED: Correct model path with hyphen
model_path = "/app/models/nexus-core.onnx"
# Debug logging
logger.info(f"Looking for model at: {model_path}")
if os.path.exists("/app/models"):
logger.info("📂 Files in /app/models/:")
for f in os.listdir("/app/models"):
full_path = os.path.join("/app/models", f)
if os.path.isfile(full_path):
size = os.path.getsize(full_path) / (1024*1024)
logger.info(f" ✓ {f} ({size:.2f} MB)")
else:
logger.error("❌ /app/models/ directory does not exist!")
raise FileNotFoundError("/app/models/ not found")
if not os.path.exists(model_path):
logger.error(f"❌ Model not found at: {model_path}")
logger.error("💡 Available files:", os.listdir("/app/models"))
raise FileNotFoundError(f"Model file missing: {model_path}")
logger.info(f"✅ Model found: {os.path.getsize(model_path)/(1024*1024):.2f} MB")
try:
engine = NexusCoreEngine(
model_path=model_path,
num_threads=2
)
logger.info("✅ Nexus-Core engine loaded successfully!")
except Exception as e:
logger.error(f"❌ Engine load failed: {e}", exc_info=True)
raise
@app.get("/health", response_model=HealthResponse)
async def health_check():
return {
"status": "healthy" if engine else "unhealthy",
"model_loaded": engine is not None,
"version": "2.0.0",
"model_path": "/app/models/nexus-core.onnx"
}
@app.post("/get-move", response_model=MoveResponse)
async def get_move(request: MoveRequest):
if not engine:
raise HTTPException(status_code=503, detail="Engine not loaded")
if not engine.validate_fen(request.fen):
raise HTTPException(status_code=400, detail="Invalid FEN string")
start = time.time()
try:
result = engine.get_best_move(
fen=request.fen,
depth=request.depth,
time_limit=request.time_limit
)
logger.info(
f"✓ Move: {result['best_move']} | "
f"Eval: {result['evaluation']:+.2f} | "
f"Depth: {result['depth_searched']} | "
f"Nodes: {result['nodes_evaluated']} | "
f"Time: {result['time_taken']}ms"
)
return MoveResponse(**result)
except Exception as e:
logger.error(f"❌ Search error: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@app.get("/")
async def root():
return {
"name": "Nexus-Core Inference API",
"version": "2.0.0",
"model": "13M parameters",
"architecture": "ResNet CNN",
"speed": "0.5-1s per move @ depth 4",
"status": "online" if engine else "starting",
"endpoints": {
"POST /get-move": "Get best chess move",
"GET /health": "API health check",
"GET /docs": "Interactive API documentation"
}
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
app,
host="0.0.0.0",
port=7860,
log_level="info",
access_log=True
) |