antonypamo commited on
Commit
1fc65ae
·
verified ·
1 Parent(s): 9af540d

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +71 -43
main.py CHANGED
@@ -1,12 +1,13 @@
1
  import os
2
  import sys
 
3
  from typing import Optional, Dict, Any
4
 
5
  import numpy as np
6
  from numpy.linalg import norm
7
  from scipy.linalg import expm
8
 
9
- from fastapi import FastAPI
10
  from pydantic import BaseModel
11
 
12
  from sentence_transformers import SentenceTransformer
@@ -16,11 +17,12 @@ import joblib
16
  # ============================
17
  # Configuración de modelos
18
  # ============================
 
19
  ENCODER_MODEL_ID = "antonypamo/RRFSAVANTMADE"
20
  META_LOGIT_REPO = "antonypamo/RRFSavantMetaLogit"
21
  META_LOGIT_FILENAME = os.environ.get(
22
  "META_LOGIT_FILENAME",
23
- "logreg_rrf_savant_15.joblib", # <-- aquí apuntas al nuevo modelo
24
  )
25
 
26
  print("🔄 [Startup] Cargando encoder RRFSAVANTMADE...", flush=True)
@@ -38,14 +40,17 @@ try:
38
  filename=META_LOGIT_FILENAME,
39
  token=os.environ.get("HF_TOKEN"), # si el repo es público, puede ser None
40
  )
41
- print("🔄 [Startup] Cargando modelo meta-logit...", flush=True)
42
  meta_logit = joblib.load(meta_logit_path)
 
 
 
 
43
  print("✅ [Startup] Meta-logit cargado.", flush=True)
44
  except Exception as e:
45
  print(f"❌ [Startup] Error al cargar meta-logit: {e}", file=sys.stderr, flush=True)
46
  raise
47
 
48
-
49
  # ============================
50
  # Geometría icosaédrica Φ12.0
51
  # ============================
@@ -197,12 +202,14 @@ def get_embedding(text: str) -> np.ndarray:
197
 
198
 
199
  def compute_rrf_features(prompt: str, answer: str) -> Dict[str, float]:
 
200
  e_p = get_embedding(prompt)
201
  e_a = get_embedding(answer)
202
 
203
  cosine_pa = float(np.dot(e_p, e_a))
204
  len_ratio = len(answer) / (len(prompt) + 1.0)
205
 
 
206
  rng = np.random.default_rng(abs(hash(prompt + answer)) % (2 ** 32))
207
  vec = rng.normal(0, 1, (2 * N,)) + 1j * rng.normal(0, 1, (2 * N,))
208
  vec /= np.sqrt(np.vdot(vec, vec))
@@ -228,7 +235,8 @@ def compute_rrf_features(prompt: str, answer: str) -> Dict[str, float]:
228
  E_mean = float(np.mean(energy))
229
  E_std = float(np.std(energy))
230
 
231
- return {
 
232
  "cosine_pa": cosine_pa,
233
  "len_ratio": len_ratio,
234
  "dirac_entropy_final": S_final,
@@ -238,6 +246,19 @@ def compute_rrf_features(prompt: str, answer: str) -> Dict[str, float]:
238
  "dirac_energy_std": E_std,
239
  }
240
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
 
242
  def features_to_vector(feats: Dict[str, float]) -> np.ndarray:
243
  keys = [
@@ -248,6 +269,14 @@ def features_to_vector(feats: Dict[str, float]) -> np.ndarray:
248
  "dirac_chirality_final",
249
  "dirac_energy_mean",
250
  "dirac_energy_std",
 
 
 
 
 
 
 
 
251
  ]
252
  return np.array([feats[k] for k in keys], dtype=float)
253
 
@@ -259,13 +288,12 @@ def compute_scores_srff_crff_ephi(prompt: str, answer: str):
259
  proba = meta_logit.predict_proba(x)[0]
260
  p_good = float(proba[1])
261
 
 
262
  SRRF = p_good
263
  CRRF = p_good * feats["cosine_pa"]
264
 
265
- S_final = feats["dirac_entropy_final"]
266
- S_max = np.log(N)
267
- norm_entropy = float(S_final / S_max)
268
-
269
  E_phi = 0.5 * (SRRF + norm_entropy)
270
 
271
  scores = {
@@ -285,58 +313,58 @@ class EvaluateRequest(BaseModel):
285
  answer: str
286
  model_label: Optional[str] = None
287
 
288
-
289
  class EvaluateResponse(BaseModel):
290
  scores: Dict[str, float]
291
  features: Dict[str, float]
292
  sim_summary: Dict[str, Any]
293
 
294
-
295
  app = FastAPI(
296
  title="Savant RRF Φ12.0 API",
297
  description="Dirac-Resonant conceptual quality layer for LLM-generated text.",
298
  version="1.0.0",
299
  )
300
 
301
-
302
  @app.get("/")
303
  def root():
304
  return {"message": "Savant RRF Φ12.0 API running", "docs": "/docs"}
305
 
306
-
307
  @app.get("/health")
308
  def health():
309
  return {"status": "ok"}
310
 
311
-
312
  @app.post("/evaluate", response_model=EvaluateResponse)
313
  def evaluate(req: EvaluateRequest):
314
- scores, feats = compute_scores_srff_crff_ephi(req.prompt, req.answer)
315
-
316
- H = build_dirac_hamiltonian(
317
- m=0.25, v=1.0, sigma=0.618,
318
- alpha_log=0.10, q=1.0,
319
- flux_vector=(0.0, 0.0, 0.0),
320
- gauge_scale=0.0,
321
- )
322
- rng = np.random.default_rng(abs(hash(req.prompt + req.answer + "sim")) % (2 ** 32))
323
- vec = rng.normal(0, 1, (2 * N,)) + 1j * rng.normal(0, 1, (2 * N,))
324
- vec /= np.sqrt(np.vdot(vec, vec))
325
- psi0 = vec
326
- sim = evolve_dirac_shell(psi0, H, dt=0.05, steps=60, record_every=20)
327
-
328
- sim_summary = {
329
- "entropy_initial": float(sim["entropy"][0]),
330
- "entropy_final": float(sim["entropy"][-1]),
331
- "chirality_initial": float(sim["chirality"][0]),
332
- "chirality_final": float(sim["chirality"][-1]),
333
- "energy_mean": float(np.mean(sim["energy"])),
334
- "energy_std": float(np.std(sim["energy"])),
335
- "N_sites": int(N),
336
- }
337
-
338
- return EvaluateResponse(
339
- scores=scores,
340
- features=feats,
341
- sim_summary=sim_summary,
342
- )
 
 
 
 
 
 
1
  import os
2
  import sys
3
+ import math
4
  from typing import Optional, Dict, Any
5
 
6
  import numpy as np
7
  from numpy.linalg import norm
8
  from scipy.linalg import expm
9
 
10
+ from fastapi import FastAPI, HTTPException
11
  from pydantic import BaseModel
12
 
13
  from sentence_transformers import SentenceTransformer
 
17
  # ============================
18
  # Configuración de modelos
19
  # ============================
20
+
21
  ENCODER_MODEL_ID = "antonypamo/RRFSAVANTMADE"
22
  META_LOGIT_REPO = "antonypamo/RRFSavantMetaLogit"
23
  META_LOGIT_FILENAME = os.environ.get(
24
  "META_LOGIT_FILENAME",
25
+ "logreg_rrf_savant_15.joblib", # <-- nuevo modelo 15 features
26
  )
27
 
28
  print("🔄 [Startup] Cargando encoder RRFSAVANTMADE...", flush=True)
 
40
  filename=META_LOGIT_FILENAME,
41
  token=os.environ.get("HF_TOKEN"), # si el repo es público, puede ser None
42
  )
43
+ print(f"🔄 [Startup] Cargando modelo meta-logit '{META_LOGIT_FILENAME}'...", flush=True)
44
  meta_logit = joblib.load(meta_logit_path)
45
+ try:
46
+ print(f"🔎 [Startup] Meta-logit espera {meta_logit.n_features_in_} features.", flush=True)
47
+ except Exception:
48
+ print("⚠️ [Startup] No se pudo leer n_features_in_.", flush=True)
49
  print("✅ [Startup] Meta-logit cargado.", flush=True)
50
  except Exception as e:
51
  print(f"❌ [Startup] Error al cargar meta-logit: {e}", file=sys.stderr, flush=True)
52
  raise
53
 
 
54
  # ============================
55
  # Geometría icosaédrica Φ12.0
56
  # ============================
 
202
 
203
 
204
  def compute_rrf_features(prompt: str, answer: str) -> Dict[str, float]:
205
+ # Embeddings
206
  e_p = get_embedding(prompt)
207
  e_a = get_embedding(answer)
208
 
209
  cosine_pa = float(np.dot(e_p, e_a))
210
  len_ratio = len(answer) / (len(prompt) + 1.0)
211
 
212
+ # Simulación Dirac shell determinista (semilla por prompt+answer)
213
  rng = np.random.default_rng(abs(hash(prompt + answer)) % (2 ** 32))
214
  vec = rng.normal(0, 1, (2 * N,)) + 1j * rng.normal(0, 1, (2 * N,))
215
  vec /= np.sqrt(np.vdot(vec, vec))
 
235
  E_mean = float(np.mean(energy))
236
  E_std = float(np.std(energy))
237
 
238
+ # Núcleo de 7 features
239
+ feats: Dict[str, float] = {
240
  "cosine_pa": cosine_pa,
241
  "len_ratio": len_ratio,
242
  "dirac_entropy_final": S_final,
 
246
  "dirac_energy_std": E_std,
247
  }
248
 
249
+ # Derivadas para llegar a 15 (igual que en el CSV)
250
+ S_max = math.log(N)
251
+ feats["entropy_norm"] = feats["dirac_entropy_final"] / S_max
252
+ feats["entropy_abs_delta"] = abs(feats["dirac_entropy_delta"])
253
+ feats["chirality_abs"] = abs(feats["dirac_chirality_final"])
254
+ feats["energy_abs_mean"] = abs(feats["dirac_energy_mean"])
255
+ feats["energy_std_sq"] = feats["dirac_energy_std"] ** 2
256
+ feats["cosine_sq"] = feats["cosine_pa"] ** 2
257
+ feats["len_log"] = math.log1p(feats["len_ratio"])
258
+ feats["len_inv"] = 1.0 / (1.0 + feats["len_ratio"])
259
+
260
+ return feats
261
+
262
 
263
  def features_to_vector(feats: Dict[str, float]) -> np.ndarray:
264
  keys = [
 
269
  "dirac_chirality_final",
270
  "dirac_energy_mean",
271
  "dirac_energy_std",
272
+ "entropy_norm",
273
+ "entropy_abs_delta",
274
+ "chirality_abs",
275
+ "energy_abs_mean",
276
+ "energy_std_sq",
277
+ "cosine_sq",
278
+ "len_log",
279
+ "len_inv",
280
  ]
281
  return np.array([feats[k] for k in keys], dtype=float)
282
 
 
288
  proba = meta_logit.predict_proba(x)[0]
289
  p_good = float(proba[1])
290
 
291
+ # Definimos SRRF/CRRF/E_phi a partir de p_good y entropía
292
  SRRF = p_good
293
  CRRF = p_good * feats["cosine_pa"]
294
 
295
+ S_max = math.log(N)
296
+ norm_entropy = float(feats["dirac_entropy_final"] / S_max)
 
 
297
  E_phi = 0.5 * (SRRF + norm_entropy)
298
 
299
  scores = {
 
313
  answer: str
314
  model_label: Optional[str] = None
315
 
 
316
  class EvaluateResponse(BaseModel):
317
  scores: Dict[str, float]
318
  features: Dict[str, float]
319
  sim_summary: Dict[str, Any]
320
 
 
321
  app = FastAPI(
322
  title="Savant RRF Φ12.0 API",
323
  description="Dirac-Resonant conceptual quality layer for LLM-generated text.",
324
  version="1.0.0",
325
  )
326
 
 
327
  @app.get("/")
328
  def root():
329
  return {"message": "Savant RRF Φ12.0 API running", "docs": "/docs"}
330
 
 
331
  @app.get("/health")
332
  def health():
333
  return {"status": "ok"}
334
 
 
335
  @app.post("/evaluate", response_model=EvaluateResponse)
336
  def evaluate(req: EvaluateRequest):
337
+ try:
338
+ scores, feats = compute_scores_srff_crff_ephi(req.prompt, req.answer)
339
+
340
+ # resumen de una simulación adicional (fresca) solo para info
341
+ H = build_dirac_hamiltonian(
342
+ m=0.25, v=1.0, sigma=0.618,
343
+ alpha_log=0.10, q=1.0,
344
+ flux_vector=(0.0, 0.0, 0.0),
345
+ gauge_scale=0.0,
346
+ )
347
+ rng = np.random.default_rng(abs(hash(req.prompt + req.answer + "sim")) % (2 ** 32))
348
+ vec = rng.normal(0, 1, (2 * N,)) + 1j * rng.normal(0, 1, (2 * N,))
349
+ vec /= np.sqrt(np.vdot(vec, vec))
350
+ psi0 = vec
351
+ sim = evolve_dirac_shell(psi0, H, dt=0.05, steps=60, record_every=20)
352
+
353
+ sim_summary = {
354
+ "entropy_initial": float(sim["entropy"][0]),
355
+ "entropy_final": float(sim["entropy"][-1]),
356
+ "chirality_initial": float(sim["chirality"][0]),
357
+ "chirality_final": float(sim["chirality"][-1]),
358
+ "energy_mean": float(np.mean(sim["energy"])),
359
+ "energy_std": float(np.std(sim["energy"])),
360
+ "N_sites": int(N),
361
+ }
362
+
363
+ return EvaluateResponse(
364
+ scores=scores,
365
+ features=feats,
366
+ sim_summary=sim_summary,
367
+ )
368
+ except Exception as e:
369
+ print(f"❌ [Runtime] Error en /evaluate: {e}", file=sys.stderr, flush=True)
370
+ raise HTTPException(status_code=500, detail="Internal server error")