SondosM commited on
Commit
36e09c1
Β·
verified Β·
1 Parent(s): 2375247

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -46
app.py CHANGED
@@ -1,19 +1,5 @@
1
  """
2
  Arabic Sign Language Interpreter - FastAPI Server (Optimized)
3
-
4
- Pipeline:
5
- Image Input
6
- ──► YOLO Detection (hand crop)
7
- ──► WiLoR 3D Pose (extract 3D joints + MANO params)
8
- ──► Stage-1: classifier.pkl β†’ "letter" or "number"?
9
- ──► Stage-2: MLP_letters.pkl β†’ specific Arabic letter
10
- OR MLP_numbers.pkl β†’ specific digit
11
- ──► JSON Response
12
-
13
- Modes (set MODE env var):
14
- full : YOLO + WiLoR FP32 + MLP (~1.1–2.5 GB)
15
- quantized : YOLO + WiLoR INT8 + MLP (~600 MB–1.2 GB)
16
- lightweight : MediaPipe + MLP (~50 MB)
17
  """
18
 
19
  import io
@@ -22,6 +8,7 @@ import inspect
22
  import sys
23
  import os
24
  import types
 
25
  from unittest.mock import MagicMock
26
 
27
  import numpy as np
@@ -39,6 +26,7 @@ from fastapi import FastAPI, File, UploadFile, HTTPException
39
  from fastapi.middleware.cors import CORSMiddleware
40
  from fastapi.responses import JSONResponse
41
  import uvicorn
 
42
 
43
  # ─── Runtime mode ──────────────────────────────────────────────────────────────
44
  MODE = os.environ.get("MODE", "full").lower()
@@ -71,41 +59,49 @@ for _mod in ["OpenGL", "OpenGL.GL", "OpenGL.GL.framebufferobjects",
71
 
72
  os.environ["PYOPENGL_PLATFORM"] = "osmesa"
73
 
74
- # ─── Configuration ─────────────────────────────────────────────────────────────
75
- WILOR_REPO_PATH = "./WiLoR"
76
- WILOR_CKPT = "./WiLoR/pretrained_models/wilor_final.ckpt"
77
- WILOR_CFG = "./WiLoR/pretrained_models/model_config.yaml"
78
- CLASSIFIER_PATH = "./classifier.pkl"
79
- MLP_LETTERS_PATH = "./MLP_letters.pkl"
80
- MLP_NUMBERS_PATH = "./MLP_numbers.pkl"
81
- DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  WILOR_TRANSFORM = transforms.Compose([
84
  transforms.ToTensor(),
85
  transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
86
  ])
87
 
88
- def _resolve_detector_path() -> str:
89
- candidates = [
90
- "./detector.pt",
91
- "./detector",
92
- "./pretrained_models/detector.pt",
93
- "./pretrained_models/detector",
94
- "./MANO/detector.pt",
95
- "./WiLoR/detector.pt",
96
- ]
97
- for c in candidates:
98
- if Path(c).exists():
99
- print(f"[INFO] Detector found at: {c}")
100
- return c
101
- import glob
102
- found = glob.glob("/app/**/detector.pt", recursive=True) + glob.glob("/app/**/detector", recursive=True)
103
- if found:
104
- print(f"[INFO] Detector found at: {found[0]}")
105
- return found[0]
106
- all_files = list(Path("/app").rglob("detector*"))
107
- raise FileNotFoundError(f"Detector not found! Searched everywhere. Found these detector* files: {all_files}")
108
-
109
  # ─── Global model handles ──────────────────────────────────────────────────────
110
  wilor_model = None
111
  yolo_detector = None
@@ -174,10 +170,9 @@ def load_models():
174
  mp_hands_model = _load_mediapipe()
175
  print("βœ… MediaPipe loaded.")
176
  else:
177
- detector_path = _resolve_detector_path()
178
  from ultralytics import YOLO
179
- print(f"[INFO] Loading YOLO detector from {detector_path} ...")
180
- yolo_detector = YOLO(detector_path)
181
  print("[INFO] YOLO loaded.")
182
 
183
  if MODE == "full":
 
1
  """
2
  Arabic Sign Language Interpreter - FastAPI Server (Optimized)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  """
4
 
5
  import io
 
8
  import sys
9
  import os
10
  import types
11
+ import shutil
12
  from unittest.mock import MagicMock
13
 
14
  import numpy as np
 
26
  from fastapi.middleware.cors import CORSMiddleware
27
  from fastapi.responses import JSONResponse
28
  import uvicorn
29
+ from huggingface_hub import hf_hub_download
30
 
31
  # ─── Runtime mode ──────────────────────────────────────────────────────────────
32
  MODE = os.environ.get("MODE", "full").lower()
 
59
 
60
  os.environ["PYOPENGL_PLATFORM"] = "osmesa"
61
 
62
+ # ─── Hugging Face Model Integration ───────────────────────────────────────────
63
+ REPO_ID = "SondosM/api_GP"
64
+
65
+ def get_hf_file(filename, is_mano=False):
66
+ print(f"Downloading {filename} from {REPO_ID}...")
67
+ temp_path = hf_hub_download(repo_id=REPO_ID, filename=filename)
68
+
69
+ if is_mano:
70
+ os.makedirs("./mano_data", exist_ok=True)
71
+ target_path = os.path.join("./mano_data", os.path.basename(filename))
72
+ if not os.path.exists(target_path):
73
+ shutil.copy(temp_path, target_path)
74
+ print(f"Copied {filename} to {target_path}")
75
+ return target_path
76
+
77
+ return temp_path
78
+
79
+ # ─── Download all required files at startup ───────────────────────────────────
80
+ print("Initializing model file paths...")
81
+
82
+ # MANO files
83
+ get_hf_file("mano_data/mano_data/mano_mean_params.npz", is_mano=True)
84
+ get_hf_file("mano_data/mano_data/MANO_LEFT.pkl", is_mano=True)
85
+ get_hf_file("mano_data/mano_data/MANO_RIGHT.pkl", is_mano=True)
86
+
87
+ # Model weights
88
+ WILOR_REPO_PATH = "./WiLoR"
89
+ WILOR_CKPT = get_hf_file("pretrained_models/pretrained_models/wilor_final.ckpt")
90
+ WILOR_CFG = get_hf_file("pretrained_models/pretrained_models/model_config.yaml")
91
+ DETECTOR_PATH = get_hf_file("pretrained_models/pretrained_models/detector.pt")
92
+
93
+ # Classifiers
94
+ CLASSIFIER_PATH = get_hf_file("classifier.pkl")
95
+ MLP_LETTERS_PATH = get_hf_file("MLP_letters.pkl")
96
+ MLP_NUMBERS_PATH = get_hf_file("MLP_numbers.pkl")
97
+
98
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
99
 
100
  WILOR_TRANSFORM = transforms.Compose([
101
  transforms.ToTensor(),
102
  transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
103
  ])
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  # ─── Global model handles ──────────────────────────────────────────────────────
106
  wilor_model = None
107
  yolo_detector = None
 
170
  mp_hands_model = _load_mediapipe()
171
  print("βœ… MediaPipe loaded.")
172
  else:
 
173
  from ultralytics import YOLO
174
+ print(f"[INFO] Loading YOLO detector from {DETECTOR_PATH} ...")
175
+ yolo_detector = YOLO(DETECTOR_PATH)
176
  print("[INFO] YOLO loaded.")
177
 
178
  if MODE == "full":