Rafs-an09002 commited on
Commit
8eb6a05
Β·
verified Β·
1 Parent(s): d2274c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -50
app.py CHANGED
@@ -18,18 +18,15 @@ class NexusNanoEngine:
18
  def __init__(self, model_path: str):
19
  if not os.path.exists(model_path):
20
  raise FileNotFoundError(f"Model not found: {model_path}")
21
-
22
- logger.info(f"Loading: {model_path} ({os.path.getsize(model_path)/(1024*1024):.2f} MB)")
23
-
24
  sess_options = ort.SessionOptions()
25
  sess_options.intra_op_num_threads = 2
26
  sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
27
-
28
  self.session = ort.InferenceSession(model_path, sess_options=sess_options, providers=['CPUExecutionProvider'])
29
  self.input_name = self.session.get_inputs()[0].name
30
  self.output_name = self.session.get_outputs()[0].name
31
  self.nodes = 0
32
- logger.info("βœ… Engine ready")
33
 
34
  def fen_to_tensor(self, fen: str) -> np.ndarray:
35
  board = chess.Board(fen)
@@ -54,18 +51,15 @@ class NexusNanoEngine:
54
  s = 0
55
  if board.is_capture(m):
56
  v, a = board.piece_at(m.to_square), board.piece_at(m.from_square)
57
- if v and a:
58
- s = self.PIECE_VALUES.get(v.piece_type, 0) * 10 - self.PIECE_VALUES.get(a.piece_type, 0)
59
  if m.promotion == chess.QUEEN: s += 90
60
  scored.append((s, m))
61
  scored.sort(key=lambda x: x[0], reverse=True)
62
  return [m for _, m in scored]
63
 
64
- def alpha_beta(self, board, depth, alpha, beta) -> Tuple[float, Optional[chess.Move]]:
65
- if board.is_game_over():
66
- return (-10000 if board.is_checkmate() else 0), None
67
- if depth == 0:
68
- return self.evaluate(board), None
69
  moves = list(board.legal_moves)
70
  if not moves: return 0, None
71
  moves = self.order_moves(board, moves)
@@ -75,8 +69,7 @@ class NexusNanoEngine:
75
  score, _ = self.alpha_beta(board, depth - 1, -beta, -alpha)
76
  score = -score
77
  board.pop()
78
- if score > best_score:
79
- best_score, best_move = score, move
80
  alpha = max(alpha, score)
81
  if alpha >= beta: break
82
  return best_score, best_move
@@ -85,16 +78,13 @@ class NexusNanoEngine:
85
  board = chess.Board(fen)
86
  self.nodes = 0
87
  moves = list(board.legal_moves)
88
- if len(moves) == 0:
89
- return {'best_move': '0000', 'evaluation': 0.0, 'nodes': 0, 'depth': 0}
90
- if len(moves) == 1:
91
- return {'best_move': moves[0].uci(), 'evaluation': round(self.evaluate(board)/100, 2), 'nodes': 1, 'depth': 0}
92
  best_move, best_score, current_depth = moves[0], float('-inf'), 1
93
  for d in range(1, depth + 1):
94
  try:
95
  score, move = self.alpha_beta(board, d, float('-inf'), float('inf'))
96
- if move:
97
- best_move, best_score, current_depth = move, score, d
98
  except: break
99
  return {'best_move': best_move.uci(), 'evaluation': round(best_score/100, 2), 'depth': current_depth, 'nodes': self.nodes}
100
 
@@ -117,55 +107,33 @@ class MoveResponse(BaseModel):
117
  @app.on_event("startup")
118
  async def startup():
119
  global engine
120
- logger.info("πŸš€ Starting Nexus-Nano...")
121
-
122
- # FIXED: Check both possible paths
123
- possible_paths = [
124
- "/app/app/models/nexus-nano.onnx", # When uploaded to app/models/
125
- "/app/models/nexus-nano.onnx" # When uploaded to models/
126
- ]
127
-
128
- model_path = None
129
- for path in possible_paths:
130
- if os.path.exists(path):
131
- model_path = path
132
- logger.info(f"βœ… Found model at: {path}")
133
- break
134
-
135
- if not model_path:
136
- logger.error("❌ Model not found in any expected location")
137
- logger.error(f"Checked paths: {possible_paths}")
138
- # List all files
139
- for root, dirs, files in os.walk("/app"):
140
- for file in files:
141
- if file.endswith('.onnx'):
142
- logger.error(f"Found .onnx at: {os.path.join(root, file)}")
143
- raise FileNotFoundError("Model not found")
144
-
145
  try:
146
  engine = NexusNanoEngine(model_path)
 
147
  except Exception as e:
148
- logger.error(f"❌ Load failed: {e}", exc_info=True)
149
  raise
150
 
151
  @app.get("/health")
152
  async def health():
153
- return {"status": "healthy" if engine else "unhealthy", "model": "nexus-nano", "version": "1.0.0"}
154
 
155
  @app.post("/get-move", response_model=MoveResponse)
156
  async def get_move(req: MoveRequest):
157
- if not engine: raise HTTPException(503, "Not loaded")
158
  try: chess.Board(req.fen)
159
  except: raise HTTPException(400, "Invalid FEN")
160
  start = time.time()
161
  try:
162
  result = engine.search(req.fen, req.depth)
163
  elapsed = int((time.time() - start) * 1000)
164
- logger.info(f"βœ“ {result['best_move']} | {result['evaluation']:+.2f} | {elapsed}ms")
165
  return MoveResponse(best_move=result['best_move'], evaluation=result['evaluation'],
166
  depth_searched=result['depth'], nodes_evaluated=result['nodes'], time_taken=elapsed)
167
  except Exception as e:
168
- logger.error(f"Error: {e}", exc_info=True)
169
  raise HTTPException(500, str(e))
170
 
171
  @app.get("/")
 
18
  def __init__(self, model_path: str):
19
  if not os.path.exists(model_path):
20
  raise FileNotFoundError(f"Model not found: {model_path}")
21
+ logger.info(f"Loading model from {model_path}...")
 
 
22
  sess_options = ort.SessionOptions()
23
  sess_options.intra_op_num_threads = 2
24
  sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
 
25
  self.session = ort.InferenceSession(model_path, sess_options=sess_options, providers=['CPUExecutionProvider'])
26
  self.input_name = self.session.get_inputs()[0].name
27
  self.output_name = self.session.get_outputs()[0].name
28
  self.nodes = 0
29
+ logger.info("βœ… Nexus-Nano engine loaded")
30
 
31
  def fen_to_tensor(self, fen: str) -> np.ndarray:
32
  board = chess.Board(fen)
 
51
  s = 0
52
  if board.is_capture(m):
53
  v, a = board.piece_at(m.to_square), board.piece_at(m.from_square)
54
+ if v and a: s = self.PIECE_VALUES.get(v.piece_type, 0) * 10 - self.PIECE_VALUES.get(a.piece_type, 0)
 
55
  if m.promotion == chess.QUEEN: s += 90
56
  scored.append((s, m))
57
  scored.sort(key=lambda x: x[0], reverse=True)
58
  return [m for _, m in scored]
59
 
60
+ def alpha_beta(self, board, depth, alpha, beta):
61
+ if board.is_game_over(): return (-10000 if board.is_checkmate() else 0), None
62
+ if depth == 0: return self.evaluate(board), None
 
 
63
  moves = list(board.legal_moves)
64
  if not moves: return 0, None
65
  moves = self.order_moves(board, moves)
 
69
  score, _ = self.alpha_beta(board, depth - 1, -beta, -alpha)
70
  score = -score
71
  board.pop()
72
+ if score > best_score: best_score, best_move = score, move
 
73
  alpha = max(alpha, score)
74
  if alpha >= beta: break
75
  return best_score, best_move
 
78
  board = chess.Board(fen)
79
  self.nodes = 0
80
  moves = list(board.legal_moves)
81
+ if not moves: return {'best_move': '0000', 'evaluation': 0.0, 'nodes': 0, 'depth': 0}
82
+ if len(moves) == 1: return {'best_move': moves[0].uci(), 'evaluation': round(self.evaluate(board)/100, 2), 'nodes': 1, 'depth': 0}
 
 
83
  best_move, best_score, current_depth = moves[0], float('-inf'), 1
84
  for d in range(1, depth + 1):
85
  try:
86
  score, move = self.alpha_beta(board, d, float('-inf'), float('inf'))
87
+ if move: best_move, best_score, current_depth = move, score, d
 
88
  except: break
89
  return {'best_move': best_move.uci(), 'evaluation': round(best_score/100, 2), 'depth': current_depth, 'nodes': self.nodes}
90
 
 
107
  @app.on_event("startup")
108
  async def startup():
109
  global engine
110
+ logger.info("πŸš€ Starting Nexus-Nano API...")
111
+ model_path = "/app/models/nexus-nano.onnx"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  try:
113
  engine = NexusNanoEngine(model_path)
114
+ logger.info("βœ… Engine ready")
115
  except Exception as e:
116
+ logger.error(f"❌ Failed to load engine: {e}")
117
  raise
118
 
119
  @app.get("/health")
120
  async def health():
121
+ return {"status": "healthy" if engine else "unhealthy", "model_loaded": engine is not None, "version": "1.0.0"}
122
 
123
  @app.post("/get-move", response_model=MoveResponse)
124
  async def get_move(req: MoveRequest):
125
+ if not engine: raise HTTPException(503, "Engine not loaded")
126
  try: chess.Board(req.fen)
127
  except: raise HTTPException(400, "Invalid FEN")
128
  start = time.time()
129
  try:
130
  result = engine.search(req.fen, req.depth)
131
  elapsed = int((time.time() - start) * 1000)
132
+ logger.info(f"Move: {result['best_move']} | Eval: {result['evaluation']:+.2f} | Time: {elapsed}ms")
133
  return MoveResponse(best_move=result['best_move'], evaluation=result['evaluation'],
134
  depth_searched=result['depth'], nodes_evaluated=result['nodes'], time_taken=elapsed)
135
  except Exception as e:
136
+ logger.error(f"Error: {e}")
137
  raise HTTPException(500, str(e))
138
 
139
  @app.get("/")