Rafs-an09002 commited on
Commit
cbee027
Β·
verified Β·
1 Parent(s): 073e69f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -32
app.py CHANGED
@@ -1,7 +1,6 @@
1
  """
2
- Nexus-Nano Inference API
3
- Ultra-lightweight single-file engine
4
- No modular architecture - pure speed optimization
5
  """
6
 
7
  from fastapi import FastAPI, HTTPException
@@ -12,19 +11,20 @@ import numpy as np
12
  import chess
13
  import time
14
  import logging
 
15
  from pathlib import Path
16
  from typing import Optional, Tuple
17
 
18
- logging.basicConfig(level=logging.INFO)
 
 
 
19
  logger = logging.getLogger(__name__)
20
 
21
  # ==================== NANO ENGINE (Single File) ====================
22
 
23
  class NexusNanoEngine:
24
- """
25
- Ultra-lightweight chess engine
26
- Pure alpha-beta, no cache, minimal overhead
27
- """
28
 
29
  PIECE_VALUES = {
30
  chess.PAWN: 1, chess.KNIGHT: 3, chess.BISHOP: 3,
@@ -32,6 +32,12 @@ class NexusNanoEngine:
32
  }
33
 
34
  def __init__(self, model_path: str):
 
 
 
 
 
 
35
  sess_options = ort.SessionOptions()
36
  sess_options.intra_op_num_threads = 2
37
  sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
@@ -46,7 +52,7 @@ class NexusNanoEngine:
46
  self.output_name = self.session.get_outputs()[0].name
47
  self.nodes = 0
48
 
49
- logger.info("βœ… Nexus-Nano loaded")
50
 
51
  def fen_to_tensor(self, fen: str) -> np.ndarray:
52
  board = chess.Board(fen)
@@ -196,23 +202,44 @@ class MoveResponse(BaseModel):
196
  @app.on_event("startup")
197
  async def startup():
198
  global engine
199
- logger.info("πŸš€ Starting Nexus-Nano...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  try:
201
- engine = NexusNanoEngine("/app/models/nexus_nano.onnx")
 
202
  except Exception as e:
203
- logger.error(f"❌ Failed: {e}")
204
  raise
205
 
206
 
207
  @app.get("/health")
208
  async def health():
209
- return {"status": "healthy", "model": "nexus-nano", "version": "1.0.0"}
 
 
 
 
 
210
 
211
 
212
  @app.post("/get-move", response_model=MoveResponse)
213
  async def get_move(req: MoveRequest):
214
  if not engine:
215
- raise HTTPException(503, "Not loaded")
216
 
217
  try:
218
  chess.Board(req.fen)
@@ -220,23 +247,28 @@ async def get_move(req: MoveRequest):
220
  raise HTTPException(400, "Invalid FEN")
221
 
222
  start = time.time()
223
- result = engine.search(req.fen, req.depth)
224
- elapsed = int((time.time() - start) * 1000)
225
-
226
- logger.info(
227
- f"Move: {result['best_move']} | "
228
- f"Eval: {result['evaluation']:+.2f} | "
229
- f"Nodes: {result['nodes']} | "
230
- f"Time: {elapsed}ms"
231
- )
232
 
233
- return MoveResponse(
234
- best_move=result['best_move'],
235
- evaluation=result['evaluation'],
236
- depth_searched=result['depth'],
237
- nodes_evaluated=result['nodes'],
238
- time_taken=elapsed
239
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
 
242
  @app.get("/")
@@ -245,10 +277,11 @@ async def root():
245
  "name": "Nexus-Nano API",
246
  "version": "1.0.0",
247
  "model": "2.8M parameters",
248
- "speed": "Lightning-fast"
 
249
  }
250
 
251
 
252
  if __name__ == "__main__":
253
  import uvicorn
254
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  """
2
+ Nexus-Nano Inference API (Fixed)
3
+ Ultra-lightweight single-file engine with proper error handling
 
4
  """
5
 
6
  from fastapi import FastAPI, HTTPException
 
11
  import chess
12
  import time
13
  import logging
14
+ import os
15
  from pathlib import Path
16
  from typing import Optional, Tuple
17
 
18
+ logging.basicConfig(
19
+ level=logging.INFO,
20
+ format='%(asctime)s - %(levelname)s - %(message)s'
21
+ )
22
  logger = logging.getLogger(__name__)
23
 
24
  # ==================== NANO ENGINE (Single File) ====================
25
 
26
  class NexusNanoEngine:
27
+ """Ultra-lightweight chess engine"""
 
 
 
28
 
29
  PIECE_VALUES = {
30
  chess.PAWN: 1, chess.KNIGHT: 3, chess.BISHOP: 3,
 
32
  }
33
 
34
  def __init__(self, model_path: str):
35
+ if not os.path.exists(model_path):
36
+ raise FileNotFoundError(f"Model not found: {model_path}")
37
+
38
+ logger.info(f"Loading model from {model_path}...")
39
+ logger.info(f"Model size: {os.path.getsize(model_path)/(1024*1024):.2f} MB")
40
+
41
  sess_options = ort.SessionOptions()
42
  sess_options.intra_op_num_threads = 2
43
  sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
 
52
  self.output_name = self.session.get_outputs()[0].name
53
  self.nodes = 0
54
 
55
+ logger.info("βœ… Nexus-Nano engine loaded")
56
 
57
  def fen_to_tensor(self, fen: str) -> np.ndarray:
58
  board = chess.Board(fen)
 
202
  @app.on_event("startup")
203
  async def startup():
204
  global engine
205
+ logger.info("πŸš€ Starting Nexus-Nano API...")
206
+
207
+ model_path = "/app/models/nexus_nano.onnx"
208
+
209
+ # Debug: Check models directory
210
+ if os.path.exists("/app/models"):
211
+ logger.info(f"πŸ“‚ Files in /app/models/:")
212
+ for f in os.listdir("/app/models"):
213
+ full_path = os.path.join("/app/models", f)
214
+ size = os.path.getsize(full_path) / (1024*1024)
215
+ logger.info(f" - {f} ({size:.2f} MB)")
216
+ else:
217
+ logger.error("❌ /app/models/ directory not found!")
218
+ raise FileNotFoundError("/app/models/ not found")
219
+
220
+ # Load engine
221
  try:
222
+ engine = NexusNanoEngine(model_path)
223
+ logger.info("βœ… Engine ready")
224
  except Exception as e:
225
+ logger.error(f"❌ Failed to load: {e}", exc_info=True)
226
  raise
227
 
228
 
229
  @app.get("/health")
230
  async def health():
231
+ return {
232
+ "status": "healthy" if engine else "unhealthy",
233
+ "model": "nexus-nano",
234
+ "version": "1.0.0",
235
+ "model_loaded": engine is not None
236
+ }
237
 
238
 
239
  @app.post("/get-move", response_model=MoveResponse)
240
  async def get_move(req: MoveRequest):
241
  if not engine:
242
+ raise HTTPException(503, "Engine not loaded")
243
 
244
  try:
245
  chess.Board(req.fen)
 
247
  raise HTTPException(400, "Invalid FEN")
248
 
249
  start = time.time()
 
 
 
 
 
 
 
 
 
250
 
251
+ try:
252
+ result = engine.search(req.fen, req.depth)
253
+ elapsed = int((time.time() - start) * 1000)
254
+
255
+ logger.info(
256
+ f"Move: {result['best_move']} | "
257
+ f"Eval: {result['evaluation']:+.2f} | "
258
+ f"Nodes: {result['nodes']} | "
259
+ f"Time: {elapsed}ms"
260
+ )
261
+
262
+ return MoveResponse(
263
+ best_move=result['best_move'],
264
+ evaluation=result['evaluation'],
265
+ depth_searched=result['depth'],
266
+ nodes_evaluated=result['nodes'],
267
+ time_taken=elapsed
268
+ )
269
+ except Exception as e:
270
+ logger.error(f"Search error: {e}", exc_info=True)
271
+ raise HTTPException(500, str(e))
272
 
273
 
274
  @app.get("/")
 
277
  "name": "Nexus-Nano API",
278
  "version": "1.0.0",
279
  "model": "2.8M parameters",
280
+ "speed": "Lightning-fast (0.2-0.5s)",
281
+ "status": "healthy" if engine else "loading"
282
  }
283
 
284
 
285
  if __name__ == "__main__":
286
  import uvicorn
287
+ uvicorn.run(app, host="0.0.0.0", port=7860, log_level="info")