Files changed (1) hide show
  1. app.py +7 -11
app.py CHANGED
@@ -3,6 +3,7 @@ import torch
3
  import torch.nn as nn
4
  import sys
5
  import os
 
6
 
7
  from fastapi import FastAPI, UploadFile, File
8
  from fastapi.middleware.cors import CORSMiddleware
@@ -37,7 +38,6 @@ REG_HEADS = 8
37
  REG_DROPOUT = 0.1
38
  PROJ_DROPOUT = 0.1
39
 
40
- # ── Checkpoint loader helper ───────────────────────────────────────────────────
41
  def _unwrap_ckpt(ckpt):
42
  if not isinstance(ckpt, dict):
43
  return ckpt
@@ -52,14 +52,12 @@ def _load_ckpt(model, path):
52
  model.load_state_dict(state)
53
  return model
54
 
55
- # ── Visual model ───────────────────────────────────────────────────────────────
56
  print("⏳ Loading visual model...")
57
  visual_model = VisualPersonalityModel(VISUAL_CFG).to(DEVICE)
58
  visual_model = _load_ckpt(visual_model, "checkpoints/best_model.pt")
59
  visual_model.eval()
60
  print("βœ“ Visual model ready")
61
 
62
- # ── Fusion model ───────────────────────────────────────────────────────────────
63
  print("⏳ Loading fusion model...")
64
  fusion_model = FusionMLP(
65
  in_dim=1024, hidden_dims=[512, 256], num_traits=5, dropout=0.3
@@ -68,7 +66,6 @@ fusion_model = _load_ckpt(fusion_model, "checkpoints/best_fusion_model.pt")
68
  fusion_model.eval()
69
  print("βœ“ Fusion model ready")
70
 
71
- # ── Audio model ────────────────────────────────────────────────────────────────
72
  print("⏳ Loading audio model...")
73
  frozen_ext = FrozenExtractor("facebook/wav2vec2-base", n_shallow=N_SHALLOW).to(DEVICE)
74
  frozen_ext.eval()
@@ -112,13 +109,11 @@ for m in [deep_transformer, proj, agru, regressor]:
112
  m.eval()
113
  print("βœ“ Audio model ready")
114
 
115
- # ── Face detector ──────────────────────────────────────────────────────────────
116
  print("⏳ Loading face detector...")
117
  face_detector = _load_face_detector()
118
  print("βœ“ Face detector ready")
119
 
120
 
121
- # ── CORE LOGIC HELPER ──────────────────────────────────────────────────────────
122
  def process_video_bytes(video_bytes):
123
  visual_preds, visual_emb = get_visual_embedding(video_bytes, visual_model, DEVICE, face_detector)
124
  audio_preds, audio_emb = get_audio_embedding(video_bytes, frozen_ext, deep_transformer, proj, agru, regressor, DEVICE)
@@ -127,10 +122,9 @@ def process_video_bytes(video_bytes):
127
  return results
128
 
129
 
130
- # ── FASTAPI SETUP (FOR REACT) ──────────────────────────────────────────────────
131
  app = FastAPI()
132
 
133
- # THE MAGIC BULLET FOR CORS: allow_origins=["*"] MUST HAVE allow_credentials=False
134
  app.add_middleware(
135
  CORSMiddleware,
136
  allow_origins=["*"],
@@ -151,7 +145,6 @@ async def api_predict(video: UploadFile = File(...)):
151
  return JSONResponse(content={"error": str(e), "trace": traceback.format_exc()}, status_code=500)
152
 
153
 
154
- # ── GRADIO UI SETUP (FOR MANUAL TESTING) ───────────────────────────────────────
155
  def gradio_predict(video_path):
156
  if video_path is None:
157
  return None, "⚠️ Please upload a video first."
@@ -160,8 +153,8 @@ def gradio_predict(video_path):
160
  video_bytes = f.read()
161
 
162
  results = process_video_bytes(video_bytes)
163
-
164
  fusion = results["fusion"]
 
165
  md = "## 🧠 Fusion Results (Main)\n\n"
166
  for trait, score in fusion.items():
167
  bar = "β–ˆ" * int(score / 5) + "β–‘" * (20 - int(score / 5))
@@ -189,4 +182,7 @@ with gr.Blocks(title="Personality Prediction API") as demo:
189
  )
190
 
191
  # Mount Gradio over the FastAPI app
192
- app = gr.mount_gradio_app(app, demo, path="/")
 
 
 
 
3
  import torch.nn as nn
4
  import sys
5
  import os
6
+ import uvicorn
7
 
8
  from fastapi import FastAPI, UploadFile, File
9
  from fastapi.middleware.cors import CORSMiddleware
 
38
  REG_DROPOUT = 0.1
39
  PROJ_DROPOUT = 0.1
40
 
 
41
  def _unwrap_ckpt(ckpt):
42
  if not isinstance(ckpt, dict):
43
  return ckpt
 
52
  model.load_state_dict(state)
53
  return model
54
 
 
55
  print("⏳ Loading visual model...")
56
  visual_model = VisualPersonalityModel(VISUAL_CFG).to(DEVICE)
57
  visual_model = _load_ckpt(visual_model, "checkpoints/best_model.pt")
58
  visual_model.eval()
59
  print("βœ“ Visual model ready")
60
 
 
61
  print("⏳ Loading fusion model...")
62
  fusion_model = FusionMLP(
63
  in_dim=1024, hidden_dims=[512, 256], num_traits=5, dropout=0.3
 
66
  fusion_model.eval()
67
  print("βœ“ Fusion model ready")
68
 
 
69
  print("⏳ Loading audio model...")
70
  frozen_ext = FrozenExtractor("facebook/wav2vec2-base", n_shallow=N_SHALLOW).to(DEVICE)
71
  frozen_ext.eval()
 
109
  m.eval()
110
  print("βœ“ Audio model ready")
111
 
 
112
  print("⏳ Loading face detector...")
113
  face_detector = _load_face_detector()
114
  print("βœ“ Face detector ready")
115
 
116
 
 
117
  def process_video_bytes(video_bytes):
118
  visual_preds, visual_emb = get_visual_embedding(video_bytes, visual_model, DEVICE, face_detector)
119
  audio_preds, audio_emb = get_audio_embedding(video_bytes, frozen_ext, deep_transformer, proj, agru, regressor, DEVICE)
 
122
  return results
123
 
124
 
 
125
  app = FastAPI()
126
 
127
+ # Wide open CORS to completely eliminate React local testing errors
128
  app.add_middleware(
129
  CORSMiddleware,
130
  allow_origins=["*"],
 
145
  return JSONResponse(content={"error": str(e), "trace": traceback.format_exc()}, status_code=500)
146
 
147
 
 
148
  def gradio_predict(video_path):
149
  if video_path is None:
150
  return None, "⚠️ Please upload a video first."
 
153
  video_bytes = f.read()
154
 
155
  results = process_video_bytes(video_bytes)
 
156
  fusion = results["fusion"]
157
+
158
  md = "## 🧠 Fusion Results (Main)\n\n"
159
  for trait, score in fusion.items():
160
  bar = "β–ˆ" * int(score / 5) + "β–‘" * (20 - int(score / 5))
 
182
  )
183
 
184
  # Mount Gradio over the FastAPI app
185
+ app = gr.mount_gradio_app(app, demo, path="/")
186
+
187
+ if __name__ == "__main__":
188
+ uvicorn.run(app, host="0.0.0.0", port=7860)